Merge pull request #2067 from swiftix/SR-249

Add [nonatomic] attribute to all SIL reference counting instructions.

Support this attribute at SIL level,  IRGen and LLVM-based ARC passes.
This commit is contained in:
swiftix
2016-04-06 23:56:43 -07:00
53 changed files with 1118 additions and 478 deletions

View File

@@ -557,9 +557,9 @@ static void insertReleases(ArrayRef<StoreInst*> Stores,
// can simply ask SSAUpdater for the reaching store.
SILValue RelVal = SSAUp.GetValueAtEndOfBlock(RelPoint->getParent());
if (StVal->getType().isReferenceCounted(RelPoint->getModule()))
B.createStrongRelease(RelPoint->getLoc(), RelVal);
B.createStrongRelease(RelPoint->getLoc(), RelVal, Atomicity::Atomic);
else
B.createReleaseValue(RelPoint->getLoc(), RelVal);
B.createReleaseValue(RelPoint->getLoc(), RelVal, Atomicity::Atomic);
}
}

View File

@@ -45,10 +45,10 @@ static SILInstruction *createDecrement(SILValue Ptr, SILInstruction *InsertPt) {
// If Ptr has reference semantics itself, create a strong_release.
if (Ptr->getType().isReferenceCounted(B.getModule()))
return B.createStrongRelease(Loc, Ptr);
return B.createStrongRelease(Loc, Ptr, Atomicity::Atomic);
// Otherwise create a release value.
return B.createReleaseValue(Loc, Ptr);
return B.createReleaseValue(Loc, Ptr, Atomicity::Atomic);
}
//===----------------------------------------------------------------------===//
@@ -407,7 +407,8 @@ static void createThunkBody(SILBasicBlock *BB, SILFunction *NewF,
for (auto &ArgDesc : ArgDescs) {
if (ArgDesc.CalleeRelease.empty())
continue;
Builder.createReleaseValue(Loc, BB->getBBArg(ArgDesc.Index));
Builder.createReleaseValue(Loc, BB->getBBArg(ArgDesc.Index),
Atomicity::Atomic);
}
Builder.createThrow(Loc, ErrorArg);

View File

@@ -219,7 +219,7 @@ bool ReleaseDevirtualizer::createDeallocCall(SILType AllocType,
// Do what a release would do before calling the deallocator: set the object
// in deallocating state, which means set the RC_DEALLOCATING_FLAG flag.
B.createSetDeallocating(ReleaseInst->getLoc(), object);
B.createSetDeallocating(ReleaseInst->getLoc(), object, Atomicity::Atomic);
// Create the call to the destructor with the allocated object as self
// argument.

View File

@@ -74,12 +74,12 @@ static void createRefCountOpForPayload(SILBuilder &Builder, SILInstruction *I,
// And our payload is refcounted, insert a strong_retain onto the
// payload.
if (UEDITy.isReferenceCounted(Mod)) {
Builder.createStrongRetain(I->getLoc(), UEDI);
Builder.createStrongRetain(I->getLoc(), UEDI, Atomicity::Atomic);
return;
}
// Otherwise, insert a retain_value on the payload.
Builder.createRetainValue(I->getLoc(), UEDI);
Builder.createRetainValue(I->getLoc(), UEDI, Atomicity::Atomic);
return;
}
@@ -90,13 +90,13 @@ static void createRefCountOpForPayload(SILBuilder &Builder, SILInstruction *I,
// If our payload has reference semantics, insert the strong release.
if (UEDITy.isReferenceCounted(Mod)) {
Builder.createStrongRelease(I->getLoc(), UEDI);
Builder.createStrongRelease(I->getLoc(), UEDI, Atomicity::Atomic);
return;
}
// Otherwise if our payload is non-trivial but lacking reference semantics,
// insert the release_value.
Builder.createReleaseValue(I->getLoc(), UEDI);
Builder.createReleaseValue(I->getLoc(), UEDI, Atomicity::Atomic);
}
//===----------------------------------------------------------------------===//
@@ -859,10 +859,10 @@ static bool tryToSinkRefCountInst(SILBasicBlock::iterator T,
Builder.setInsertionPoint(&*SuccBB->begin());
if (isa<StrongRetainInst>(I)) {
Builder.createStrongRetain(I->getLoc(), Ptr);
Builder.createStrongRetain(I->getLoc(), Ptr, Atomicity::Atomic);
} else {
assert(isa<RetainValueInst>(I) && "This can only be retain_value");
Builder.createRetainValue(I->getLoc(), Ptr);
Builder.createRetainValue(I->getLoc(), Ptr, Atomicity::Atomic);
}
}
@@ -963,10 +963,12 @@ static bool hoistDecrementsToPredecessors(SILBasicBlock *BB, AliasAnalysis *AA,
Builder.setInsertionPoint(PredBB->getTerminator());
SILInstruction *Release;
if (isa<StrongReleaseInst>(Inst)) {
Release = Builder.createStrongRelease(Inst->getLoc(), Ptr);
Release =
Builder.createStrongRelease(Inst->getLoc(), Ptr, Atomicity::Atomic);
} else {
assert(isa<ReleaseValueInst>(Inst) && "This can only be retain_value");
Release = Builder.createReleaseValue(Inst->getLoc(), Ptr);
Release =
Builder.createReleaseValue(Inst->getLoc(), Ptr, Atomicity::Atomic);
}
// Update the last instruction to consider when looking for ARC uses or
// decrements in predecessor blocks.
@@ -1648,7 +1650,8 @@ sinkIncrementsOutOfSwitchRegions(AliasAnalysis *AA,
// TODO: Which debug loc should we use here? Using one of the locs from the
// delete list seems reasonable for now...
SILBuilder(getBB()->begin()).createRetainValue(DeleteList[0]->getLoc(),
EnumValue);
EnumValue,
Atomicity::Atomic);
for (auto *I : DeleteList)
I->eraseFromParent();
++NumSunk;

View File

@@ -135,9 +135,10 @@ static FullApplySite speculateMonomorphicTarget(FullApplySite AI,
if (auto *Release =
dyn_cast<StrongReleaseInst>(std::next(Continue->begin()))) {
if (Release->getOperand() == CMI->getOperand()) {
VirtBuilder.createStrongRelease(Release->getLoc(), CMI->getOperand());
IdenBuilder.createStrongRelease(Release->getLoc(),
DownCastedClassInstance);
VirtBuilder.createStrongRelease(Release->getLoc(), CMI->getOperand(),
Atomicity::Atomic);
IdenBuilder.createStrongRelease(
Release->getLoc(), DownCastedClassInstance, Atomicity::Atomic);
Release->eraseFromParent();
}
}