22#ifndef LLVM_ANALYSIS_OBJCARCANALYSISUTILS_H
23#define LLVM_ANALYSIS_OBJCARCANALYSISUTILS_H
44 std::initializer_list<Intrinsic::ID> Intrinsics = {
45 Intrinsic::objc_retain,
46 Intrinsic::objc_release,
47 Intrinsic::objc_autorelease,
48 Intrinsic::objc_retainAutoreleasedReturnValue,
49 Intrinsic::objc_retainBlock,
50 Intrinsic::objc_autoreleaseReturnValue,
51 Intrinsic::objc_autoreleasePoolPush,
52 Intrinsic::objc_loadWeakRetained,
53 Intrinsic::objc_loadWeak,
54 Intrinsic::objc_destroyWeak,
55 Intrinsic::objc_initWeak,
56 Intrinsic::objc_copyWeak,
57 Intrinsic::objc_retainedObject,
58 Intrinsic::objc_unretainedObject,
59 Intrinsic::objc_unretainedPointer,
60 Intrinsic::objc_clang_arc_noop_use,
61 Intrinsic::objc_clang_arc_use,
66 "Can only check non-overloaded intrinsics");
82 V = cast<CallInst>(V)->getArgOperand(0);
91 DenseMap<
const Value *, std::pair<WeakVH, WeakTrackingVH>> &Cache) {
93 auto InCache = Cache.lookup(V);
94 if (InCache.first && InCache.second)
95 return InCache.second;
99 std::make_pair(
const_cast<Value *
>(V),
const_cast<Value *
>(Computed));
120 V = V->stripPointerCasts();
123 V = cast<CallInst>(V)->getArgOperand(0);
144 return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
148 return isa<BitCastInst>(
I) ||
149 (isa<GetElementPtrInst>(
I) &&
150 cast<GetElementPtrInst>(
I)->hasAllZeroIndices());
157 if (isa<Constant>(
Op) || isa<AllocaInst>(
Op))
160 if (
const Argument *Arg = dyn_cast<Argument>(
Op))
161 if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
162 Arg->hasStructRetAttr())
198 if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
199 isa<Argument>(V) || isa<Constant>(V) ||
203 if (
const LoadInst *LI = dyn_cast<LoadInst>(V)) {
204 const Value *Pointer =
206 if (
const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
209 if (GV->isConstant())
214 if (
Name.starts_with(
"\01l_objc_msgSend_fixup_"))
218 if (Section.contains(
"__message_refs") ||
219 Section.contains(
"__objc_classrefs") ||
220 Section.contains(
"__objc_superrefs") ||
221 Section.contains(
"__objc_methname") || Section.contains(
"__cstring"))
240 std::optional<unsigned> ImpreciseReleaseMDKind;
243 std::optional<unsigned> CopyOnEscapeMDKind;
246 std::optional<unsigned> NoObjCARCExceptionsMDKind;
251 ImpreciseReleaseMDKind = std::nullopt;
252 CopyOnEscapeMDKind = std::nullopt;
253 NoObjCARCExceptionsMDKind = std::nullopt;
259 if (!ImpreciseReleaseMDKind)
260 ImpreciseReleaseMDKind =
261 M->getContext().getMDKindID(
"clang.imprecise_release");
262 return *ImpreciseReleaseMDKind;
264 if (!CopyOnEscapeMDKind)
266 M->getContext().getMDKindID(
"clang.arc.copy_on_escape");
267 return *CopyOnEscapeMDKind;
269 if (!NoObjCARCExceptionsMDKind)
270 NoObjCARCExceptionsMDKind =
271 M->getContext().getMDKindID(
"clang.arc.no_objc_arc_exceptions");
272 return *NoObjCARCExceptionsMDKind;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
A private abstract base class describing the concept of an individual alias analysis implementation.
This class represents an incoming formal argument to a Function.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool onlyReadsMemory(unsigned OpNo) const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents an Operation in the Expression.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
Class to represent pointers.
StringRef - Represent a constant reference to a string, i.e.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
A cache of MDKinds used by various ARC optimizations.
unsigned get(ARCMDKindID ID)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
LLVM_ABI bool isOverloaded(ID id)
Returns true if the intrinsic can be overloaded.
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
bool ModuleHasARC(const Module &M)
Test if the given module looks interesting to run ARC optimization on.
ARCInstKind GetCallSiteClass(const CallBase &CB)
Helper for GetARCInstKind.
bool IsNullOrUndef(const Value *V)
ARCInstKind
Equivalence classes of instructions in the ARC Model.
@ CallOrUser
could call objc_release and/or "use" pointers
@ None
anything that is inert from an ARC perspective.
@ User
could "use" a pointer
@ Call
could call objc_release
bool IsObjCIdentifiedObject(const Value *V)
Return true if this value refers to a distinct and identifiable object.
bool EnableARCOpts
A handy option to enable/disable all ARC Optimizations.
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
bool IsNoopInstruction(const Instruction *I)
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
const Value * GetUnderlyingObjCPtrCached(const Value *V, DenseMap< const Value *, std::pair< WeakVH, WeakTrackingVH > > &Cache)
A wrapper for GetUnderlyingObjCPtr used for results memoization.
Value * GetArgRCIdentityRoot(Value *Inst)
Assuming the given instruction is one of the special calls such as objc_retain or objc_release,...
const Value * GetUnderlyingObjCPtr(const Value *V)
This is a wrapper around getUnderlyingObject which also knows how to look through objc_retain and obj...
const Value * GetRCIdentityRoot(const Value *V)
The RCIdentity root of a value V is a dominating value U for which retaining or releasing U is equiva...
This is an optimization pass for GlobalISel generic memory operations.
@ Mod
The access may modify the value stored in memory.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....