aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/ObjCARC
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/ObjCARC')
-rw-r--r--lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h14
-rw-r--r--lib/Transforms/ObjCARC/ObjCARCContract.cpp1
-rw-r--r--lib/Transforms/ObjCARC/ObjCARCOpts.cpp92
3 files changed, 14 insertions, 93 deletions
diff --git a/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h b/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
index c74827210364..c541fa4c8bee 100644
--- a/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
+++ b/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h
@@ -127,9 +127,8 @@ private:
LLVMContext &C = TheModule->getContext();
Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
- AttributeSet Attr =
- AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
- Attribute::NoUnwind);
+ AttributeList Attr = AttributeList().addAttribute(
+ C, AttributeList::FunctionIndex, Attribute::NoUnwind);
FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
/*isVarArg=*/false);
return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
@@ -144,10 +143,10 @@ private:
Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
Type *Params[] = { I8X };
FunctionType *Fty = FunctionType::get(I8X, Params, /*isVarArg=*/false);
- AttributeSet Attr = AttributeSet();
+ AttributeList Attr = AttributeList();
if (NoUnwind)
- Attr = Attr.addAttribute(C, AttributeSet::FunctionIndex,
+ Attr = Attr.addAttribute(C, AttributeList::FunctionIndex,
Attribute::NoUnwind);
return Decl = TheModule->getOrInsertFunction(Name, Fty, Attr);
@@ -162,9 +161,8 @@ private:
Type *I8XX = PointerType::getUnqual(I8X);
Type *Params[] = { I8XX, I8X };
- AttributeSet Attr =
- AttributeSet().addAttribute(C, AttributeSet::FunctionIndex,
- Attribute::NoUnwind);
+ AttributeList Attr = AttributeList().addAttribute(
+ C, AttributeList::FunctionIndex, Attribute::NoUnwind);
Attr = Attr.addAttribute(C, 1, Attribute::NoCapture);
FunctionType *Fty = FunctionType::get(Type::getVoidTy(C), Params,
diff --git a/lib/Transforms/ObjCARC/ObjCARCContract.cpp b/lib/Transforms/ObjCARC/ObjCARCContract.cpp
index 23c1f5990ba5..a86eaaec7641 100644
--- a/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ b/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -394,6 +394,7 @@ void ObjCARCContract::tryToContractReleaseIntoStoreStrong(Instruction *Release,
DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong << "\n");
+ if (&*Iter == Retain) ++Iter;
if (&*Iter == Store) ++Iter;
Store->eraseFromParent();
Release->eraseFromParent();
diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index 136d54a6cb75..3c73376c9906 100644
--- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -85,41 +85,6 @@ static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
return nullptr;
}
-/// This is a wrapper around getUnderlyingObjCPtr along the lines of
-/// GetUnderlyingObjects except that it returns early when it sees the first
-/// alloca.
-static inline bool AreAnyUnderlyingObjectsAnAlloca(const Value *V,
- const DataLayout &DL) {
- SmallPtrSet<const Value *, 4> Visited;
- SmallVector<const Value *, 4> Worklist;
- Worklist.push_back(V);
- do {
- const Value *P = Worklist.pop_back_val();
- P = GetUnderlyingObjCPtr(P, DL);
-
- if (isa<AllocaInst>(P))
- return true;
-
- if (!Visited.insert(P).second)
- continue;
-
- if (const SelectInst *SI = dyn_cast<const SelectInst>(P)) {
- Worklist.push_back(SI->getTrueValue());
- Worklist.push_back(SI->getFalseValue());
- continue;
- }
-
- if (const PHINode *PN = dyn_cast<const PHINode>(P)) {
- for (Value *IncValue : PN->incoming_values())
- Worklist.push_back(IncValue);
- continue;
- }
- } while (!Worklist.empty());
-
- return false;
-}
-
-
/// @}
///
/// \defgroup ARCOpt ARC Optimization.
@@ -481,9 +446,6 @@ namespace {
/// MDKind identifiers.
ARCMDKindCache MDKindCache;
- // This is used to track if a pointer is stored into an alloca.
- DenseSet<const Value *> MultiOwnersSet;
-
/// A flag indicating whether this optimization pass should run.
bool Run;
@@ -524,8 +486,7 @@ namespace {
PairUpRetainsAndReleases(DenseMap<const BasicBlock *, BBState> &BBStates,
BlotMapVector<Value *, RRInfo> &Retains,
DenseMap<Value *, RRInfo> &Releases, Module *M,
- SmallVectorImpl<Instruction *> &NewRetains,
- SmallVectorImpl<Instruction *> &NewReleases,
+ Instruction * Retain,
SmallVectorImpl<Instruction *> &DeadInsts,
RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
Value *Arg, bool KnownSafe,
@@ -1155,29 +1116,6 @@ bool ObjCARCOpt::VisitInstructionBottomUp(
case ARCInstKind::None:
// These are irrelevant.
return NestingDetected;
- case ARCInstKind::User:
- // If we have a store into an alloca of a pointer we are tracking, the
- // pointer has multiple owners implying that we must be more conservative.
- //
- // This comes up in the context of a pointer being ``KnownSafe''. In the
- // presence of a block being initialized, the frontend will emit the
- // objc_retain on the original pointer and the release on the pointer loaded
- // from the alloca. The optimizer will through the provenance analysis
- // realize that the two are related, but since we only require KnownSafe in
- // one direction, will match the inner retain on the original pointer with
- // the guard release on the original pointer. This is fixed by ensuring that
- // in the presence of allocas we only unconditionally remove pointers if
- // both our retain and our release are KnownSafe.
- if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
- const DataLayout &DL = BB->getModule()->getDataLayout();
- if (AreAnyUnderlyingObjectsAnAlloca(SI->getPointerOperand(), DL)) {
- auto I = MyStates.findPtrBottomUpState(
- GetRCIdentityRoot(SI->getValueOperand()));
- if (I != MyStates.bottom_up_ptr_end())
- MultiOwnersSet.insert(I->first);
- }
- }
- break;
default:
break;
}
@@ -1540,8 +1478,7 @@ bool ObjCARCOpt::PairUpRetainsAndReleases(
DenseMap<const BasicBlock *, BBState> &BBStates,
BlotMapVector<Value *, RRInfo> &Retains,
DenseMap<Value *, RRInfo> &Releases, Module *M,
- SmallVectorImpl<Instruction *> &NewRetains,
- SmallVectorImpl<Instruction *> &NewReleases,
+ Instruction *Retain,
SmallVectorImpl<Instruction *> &DeadInsts, RRInfo &RetainsToMove,
RRInfo &ReleasesToMove, Value *Arg, bool KnownSafe,
bool &AnyPairsCompletelyEliminated) {
@@ -1549,7 +1486,6 @@ bool ObjCARCOpt::PairUpRetainsAndReleases(
// is already incremented, we can similarly ignore possible decrements unless
// we are dealing with a retainable object with multiple provenance sources.
bool KnownSafeTD = true, KnownSafeBU = true;
- bool MultipleOwners = false;
bool CFGHazardAfflicted = false;
// Connect the dots between the top-down-collected RetainsToMove and
@@ -1561,14 +1497,13 @@ bool ObjCARCOpt::PairUpRetainsAndReleases(
unsigned OldCount = 0;
unsigned NewCount = 0;
bool FirstRelease = true;
- for (;;) {
+ for (SmallVector<Instruction *, 4> NewRetains{Retain};;) {
+ SmallVector<Instruction *, 4> NewReleases;
for (Instruction *NewRetain : NewRetains) {
auto It = Retains.find(NewRetain);
assert(It != Retains.end());
const RRInfo &NewRetainRRI = It->second;
KnownSafeTD &= NewRetainRRI.KnownSafe;
- MultipleOwners =
- MultipleOwners || MultiOwnersSet.count(GetArgRCIdentityRoot(NewRetain));
for (Instruction *NewRetainRelease : NewRetainRRI.Calls) {
auto Jt = Releases.find(NewRetainRelease);
if (Jt == Releases.end())
@@ -1691,7 +1626,6 @@ bool ObjCARCOpt::PairUpRetainsAndReleases(
}
}
}
- NewReleases.clear();
if (NewRetains.empty()) break;
}
@@ -1745,10 +1679,6 @@ bool ObjCARCOpt::PerformCodePlacement(
DEBUG(dbgs() << "\n== ObjCARCOpt::PerformCodePlacement ==\n");
bool AnyPairsCompletelyEliminated = false;
- RRInfo RetainsToMove;
- RRInfo ReleasesToMove;
- SmallVector<Instruction *, 4> NewRetains;
- SmallVector<Instruction *, 4> NewReleases;
SmallVector<Instruction *, 8> DeadInsts;
// Visit each retain.
@@ -1780,9 +1710,10 @@ bool ObjCARCOpt::PerformCodePlacement(
// Connect the dots between the top-down-collected RetainsToMove and
// bottom-up-collected ReleasesToMove to form sets of related calls.
- NewRetains.push_back(Retain);
+ RRInfo RetainsToMove, ReleasesToMove;
+
bool PerformMoveCalls = PairUpRetainsAndReleases(
- BBStates, Retains, Releases, M, NewRetains, NewReleases, DeadInsts,
+ BBStates, Retains, Releases, M, Retain, DeadInsts,
RetainsToMove, ReleasesToMove, Arg, KnownSafe,
AnyPairsCompletelyEliminated);
@@ -1792,12 +1723,6 @@ bool ObjCARCOpt::PerformCodePlacement(
MoveCalls(Arg, RetainsToMove, ReleasesToMove,
Retains, Releases, DeadInsts, M);
}
-
- // Clean up state for next retain.
- NewReleases.clear();
- NewRetains.clear();
- RetainsToMove.clear();
- ReleasesToMove.clear();
}
// Now that we're done moving everything, we can delete the newly dead
@@ -1987,9 +1912,6 @@ bool ObjCARCOpt::OptimizeSequences(Function &F) {
Releases,
F.getParent());
- // Cleanup.
- MultiOwnersSet.clear();
-
return AnyPairsCompletelyEliminated && NestingDetected;
}