aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/ObjCARC/PtrState.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC/PtrState.cpp')
-rw-r--r--llvm/lib/Transforms/ObjCARC/PtrState.cpp46
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!");
}