diff options
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC/PtrState.cpp')
-rw-r--r-- | llvm/lib/Transforms/ObjCARC/PtrState.cpp | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/PtrState.cpp b/llvm/lib/Transforms/ObjCARC/PtrState.cpp index 6071ec3e4d91..d10d5851d5ea 100644 --- a/llvm/lib/Transforms/ObjCARC/PtrState.cpp +++ b/llvm/lib/Transforms/ObjCARC/PtrState.cpp @@ -11,6 +11,7 @@ #include "ObjCARC.h" #include "llvm/Analysis/ObjCARCAnalysisUtils.h" #include "llvm/Analysis/ObjCARCInstKind.h" +#include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" @@ -43,8 +44,6 @@ raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS, const Sequence S) { return OS << "S_CanRelease"; case S_Use: return OS << "S_Use"; - case S_Release: - return OS << "S_Release"; case S_MovableRelease: return OS << "S_MovableRelease"; case S_Stop: @@ -74,12 +73,10 @@ static Sequence MergeSeqs(Sequence A, Sequence B, bool TopDown) { } else { // Choose the side which is further along in the sequence. if ((A == S_Use || A == S_CanRelease) && - (B == S_Use || B == S_Release || B == S_Stop || B == S_MovableRelease)) + (B == S_Use || B == S_Stop || B == S_MovableRelease)) return A; // If both sides are releases, choose the more conservative one. - if (A == S_Stop && (B == S_Release || B == S_MovableRelease)) - return A; - if (A == S_Release && B == S_MovableRelease) + if (A == S_Stop && B == S_MovableRelease) return A; } @@ -183,7 +180,7 @@ bool BottomUpPtrState::InitBottomUp(ARCMDKindCache &Cache, Instruction *I) { // pairs by making PtrState hold a stack of states, but this is // simple and avoids adding overhead for the non-nested case. bool NestingDetected = false; - if (GetSeq() == S_Release || GetSeq() == S_MovableRelease) { + if (GetSeq() == S_MovableRelease) { LLVM_DEBUG( dbgs() << " Found nested releases (i.e. a release pair)\n"); NestingDetected = true; @@ -191,8 +188,10 @@ bool BottomUpPtrState::InitBottomUp(ARCMDKindCache &Cache, Instruction *I) { MDNode *ReleaseMetadata = I->getMetadata(Cache.get(ARCMDKindID::ImpreciseRelease)); - Sequence NewSeq = ReleaseMetadata ? S_MovableRelease : S_Release; + Sequence NewSeq = ReleaseMetadata ? S_MovableRelease : S_Stop; ResetSequenceProgress(NewSeq); + if (NewSeq == S_Stop) + InsertReverseInsertPt(I); SetReleaseMetadata(ReleaseMetadata); SetKnownSafe(HasKnownPositiveRefCount()); SetTailCallRelease(cast<CallInst>(I)->isTailCall()); @@ -207,7 +206,6 @@ bool BottomUpPtrState::MatchWithRetain() { Sequence OldSeq = GetSeq(); switch (OldSeq) { case S_Stop: - case S_Release: case S_MovableRelease: case S_Use: // If OldSeq is not S_Use or OldSeq is S_Use and we are tracking an @@ -242,7 +240,6 @@ bool BottomUpPtrState::HandlePotentialAlterRefCount(Instruction *Inst, SetSeq(S_CanRelease); return true; case S_CanRelease: - case S_Release: case S_MovableRelease: case S_Stop: case S_None: @@ -280,21 +277,22 @@ void BottomUpPtrState::HandlePotentialUse(BasicBlock *BB, Instruction *Inst, InsertAfter = skipDebugIntrinsics(InsertAfter); InsertReverseInsertPt(&*InsertAfter); + + // Don't insert anything between a call/invoke with operand bundle + // "clang.arc.attachedcall" and the retainRV/claimRV call that uses the call + // result. + if (auto *CB = dyn_cast<CallBase>(Inst)) + if (objcarc::hasAttachedCallOpBundle(CB)) + SetCFGHazardAfflicted(true); }; // Check for possible direct uses. switch (GetSeq()) { - case S_Release: case S_MovableRelease: if (CanUse(Inst, Ptr, PA, Class)) { LLVM_DEBUG(dbgs() << " CanUse: Seq: " << GetSeq() << "; " << *Ptr << "\n"); SetSeqAndInsertReverseInsertPt(S_Use); - } else if (Seq == S_Release && IsUser(Class)) { - LLVM_DEBUG(dbgs() << " PreciseReleaseUse: Seq: " << GetSeq() - << "; " << *Ptr << "\n"); - // Non-movable releases depend on any possible objc pointer use. - SetSeqAndInsertReverseInsertPt(S_Stop); } else if (const auto *Call = getreturnRVOperand(*Inst, Class)) { if (CanUse(Call, Ptr, PA, GetBasicARCInstKind(Call))) { LLVM_DEBUG(dbgs() << " ReleaseUse: Seq: " << GetSeq() << "; " @@ -370,17 +368,15 @@ bool TopDownPtrState::MatchWithRelease(ARCMDKindCache &Cache, case S_None: return false; case S_Stop: - case S_Release: case S_MovableRelease: llvm_unreachable("top-down pointer in bottom up state!"); } llvm_unreachable("Sequence unknown enum value"); } -bool TopDownPtrState::HandlePotentialAlterRefCount(Instruction *Inst, - const Value *Ptr, - ProvenanceAnalysis &PA, - ARCInstKind Class) { +bool TopDownPtrState::HandlePotentialAlterRefCount( + Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, + ARCInstKind Class, const BundledRetainClaimRVs &BundledRVs) { // Check for possible releases. Treat clang.arc.use as a releasing instruction // to prevent sinking a retain past it. if (!CanDecrementRefCount(Inst, Ptr, PA, Class) && @@ -396,6 +392,12 @@ bool TopDownPtrState::HandlePotentialAlterRefCount(Instruction *Inst, assert(!HasReverseInsertPts()); InsertReverseInsertPt(Inst); + // Don't insert anything between a call/invoke with operand bundle + // "clang.arc.attachedcall" and the retainRV/claimRV call that uses the call + // result. + if (BundledRVs.contains(Inst)) + SetCFGHazardAfflicted(true); + // One call can't cause a transition from S_Retain to S_CanRelease // and S_CanRelease to S_Use. If we've made the first transition, // we're done. @@ -405,7 +407,6 @@ bool TopDownPtrState::HandlePotentialAlterRefCount(Instruction *Inst, case S_None: return false; case S_Stop: - case S_Release: case S_MovableRelease: llvm_unreachable("top-down pointer in release state!"); } @@ -429,7 +430,6 @@ void TopDownPtrState::HandlePotentialUse(Instruction *Inst, const Value *Ptr, case S_None: return; case S_Stop: - case S_Release: case S_MovableRelease: llvm_unreachable("top-down pointer in release state!"); } |