31 #define DEBUG_TYPE "objc-arc-ptr-state" 40 return OS <<
"S_None";
42 return OS <<
"S_Retain";
44 return OS <<
"S_CanRelease";
48 return OS <<
"S_Release";
50 return OS <<
"S_MovableRelease";
52 return OS <<
"S_Stop";
130 KnownPositiveRefCount =
true;
135 KnownPositiveRefCount =
false;
159 }
else if (Partial || Other.
Partial) {
164 ClearSequenceProgress();
170 Partial = RRI.Merge(Other.
RRI);
186 bool NestingDetected =
false;
189 dbgs() <<
" Found nested releases (i.e. a release pair)\n");
190 NestingDetected =
true;
196 ResetSequenceProgress(NewSeq);
197 SetReleaseMetadata(ReleaseMetadata);
198 SetKnownSafe(HasKnownPositiveRefCount());
199 SetTailCallRelease(cast<CallInst>(I)->isTailCall());
201 SetKnownPositiveRefCount();
202 return NestingDetected;
206 SetKnownPositiveRefCount();
216 if (OldSeq !=
S_Use || IsTrackingImpreciseReleases())
217 ClearReverseInsertPts();
261 auto SetSeqAndInsertReverseInsertPt = [&](
Sequence NewSeq){
262 assert(!HasReverseInsertPts());
268 if (isa<InvokeInst>(Inst)) {
270 InsertAfter = IP == BB->
end() ? std::prev(BB->
end()) : IP;
271 if (isa<CatchSwitchInst>(InsertAfter))
275 SetCFGHazardAfflicted(
true);
279 InsertReverseInsertPt(&*InsertAfter);
286 if (
CanUse(Inst, Ptr, PA, Class)) {
289 SetSeqAndInsertReverseInsertPt(
S_Use);
292 <<
"; " << *Ptr <<
"\n");
294 SetSeqAndInsertReverseInsertPt(
S_Stop);
299 SetSeqAndInsertReverseInsertPt(
S_Stop);
304 if (
CanUse(Inst, Ptr, PA, Class)) {
306 <<
"; " << *Ptr <<
"\n");
324 bool NestingDetected =
false;
337 NestingDetected =
true;
340 SetKnownSafe(HasKnownPositiveRefCount());
344 SetKnownPositiveRefCount();
345 return NestingDetected;
350 ClearKnownPositiveRefCount();
360 if (OldSeq ==
S_Retain || ReleaseMetadata !=
nullptr)
361 ClearReverseInsertPts();
364 SetReleaseMetadata(ReleaseMetadata);
365 SetTailCallRelease(cast<CallInst>(Release)->isTailCall());
387 LLVM_DEBUG(
dbgs() <<
" CanAlterRefCount: Seq: " << GetSeq() <<
"; " 389 ClearKnownPositiveRefCount();
393 assert(!HasReverseInsertPts());
394 InsertReverseInsertPt(Inst);
418 if (!
CanUse(Inst, Ptr, PA, Class))
bool Merge(const RRInfo &Other)
Conservatively merge the two RRInfo.
This file declares special dependency analysis routines used in Objective C ARC Optimizations.
bool IsUser(ARCInstKind Class)
Test if the given class is a kind of user.
SmallPtrSet< Instruction *, 2 > Calls
For a top-down sequence, the set of objc_retains or objc_retainBlocks.
This class represents lattice values for constants.
bool CanUse(const Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Test whether the given instruction can "use" the given pointer's object in a way that requires the re...
bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
bool MatchWithRelease(ARCMDKindCache &Cache, Instruction *Release)
Return true if this set of retains can be paired with the given release.
SmallPtrSet< Instruction *, 2 > ReverseInsertPts
The set of optimal insert positions for moving calls in the opposite sequence.
This class summarizes several per-pointer runtime properties which are propagated through the flow gr...
unsigned get(ARCMDKindID ID)
bool IsTailCallRelease
True of the objc_release calls are all marked with the "tail" keyword.
bool InitBottomUp(ARCMDKindCache &Cache, Instruction *I)
(Re-)Initialize this bottom up pointer returning true if we detected a pointer with nested releases...
objc_retainAutoreleasedReturnValue
void ClearKnownPositiveRefCount()
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void HandlePotentialUse(BasicBlock *BB, Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Unidirectional information about either a retain-decrement-use-release sequence or release-use-decrem...
raw_ostream & operator<<(raw_ostream &OS, const ARCInstKind Class)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void HandlePotentialUse(Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
RRInfo RRI
Unidirectional information about the current sequence.
LLVM Basic Block Representation.
bool KnownPositiveRefCount
True if the reference count is known to be incremented.
void Merge(const PtrState &Other, bool TopDown)
like S_Release, but code motion is stopped.
self_iterator getIterator()
A cache of MDKinds used by various ARC optimizations.
bool MatchWithRetain()
Return true if this set of releases can be paired with a release.
This file defines common analysis utilities used by the ObjC ARC Optimizer.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void ResetSequenceProgress(Sequence NewSeq)
bool CFGHazardAfflicted
If this is true, we cannot perform code motion but can still remove retain/release pairs...
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
objc_release(x), !clang.imprecise_release.
Iterator for intrusive lists based on ilist_node.
static const Instruction * getreturnRVOperand(const Instruction &Inst, ARCInstKind Class)
If Inst is a ReturnRV and its operand is a call or invoke, return the operand.
bool Partial
True if we've seen an opportunity for partial RR elimination, such as pushing calls into a CFG triang...
ARCInstKind
Equivalence classes of instructions in the ARC Model.
bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
MDNode * ReleaseMetadata
If the Calls are objc_release calls and they all have a clang.imprecise_release tag, this is the metadata tag.
static Sequence MergeSeqs(Sequence A, Sequence B, bool TopDown)
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
void SetKnownPositiveRefCount()
bool CanAlterRefCount(const Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Test whether the given instruction can result in a reference count modification (positive or negative...
void SetSeq(Sequence NewSeq)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
foo(x) – x could possibly see a ref count decrement.
bool KnownSafe
After an objc_retain, the reference count of the referenced object is known to be positive...
This class implements an extremely fast bulk output stream that can only output to a stream...
This is similar to BasicAliasAnalysis, and it uses many of the same techniques, except it uses specia...
bool InitTopDown(ARCInstKind Kind, Instruction *I)
(Re-)Initialize this bottom up pointer returning true if we detected a pointer with nested releases...