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");
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();
161 if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
162 Arg->hasStructRetAttr())
204 const Value *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.
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.
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.
Abstract Attribute helper functions.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Mod
The access may modify the value stored in memory.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....