LLVM  13.0.0git
ObjCARCAnalysisUtils.h
Go to the documentation of this file.
1 //===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file defines common analysis utilities used by the ObjC ARC Optimizer.
10 /// ARC stands for Automatic Reference Counting and is a system for managing
11 /// reference counts for objects in Objective C.
12 ///
13 /// WARNING: This file knows about certain library functions. It recognizes them
14 /// by name, and hardwires knowledge of their semantics.
15 ///
16 /// WARNING: This file knows about how certain Objective-C library functions are
17 /// used. Naive LLVM IR transformations which would otherwise be
18 /// behavior-preserving may break these assumptions.
19 ///
20 //===----------------------------------------------------------------------===//
21 
22 #ifndef LLVM_ANALYSIS_OBJCARCANALYSISUTILS_H
23 #define LLVM_ANALYSIS_OBJCARCANALYSISUTILS_H
24 
25 #include "llvm/ADT/Optional.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/IR/ValueHandle.h"
31 
32 namespace llvm {
33 
34 class AAResults;
35 
36 namespace objcarc {
37 
38 /// A handy option to enable/disable all ARC Optimizations.
39 extern bool EnableARCOpts;
40 
41 /// Test if the given module looks interesting to run ARC optimization
42 /// on.
43 inline bool ModuleHasARC(const Module &M) {
44  return
45  M.getNamedValue("llvm.objc.retain") ||
46  M.getNamedValue("llvm.objc.release") ||
47  M.getNamedValue("llvm.objc.autorelease") ||
48  M.getNamedValue("llvm.objc.retainAutoreleasedReturnValue") ||
49  M.getNamedValue("llvm.objc.unsafeClaimAutoreleasedReturnValue") ||
50  M.getNamedValue("llvm.objc.retainBlock") ||
51  M.getNamedValue("llvm.objc.autoreleaseReturnValue") ||
52  M.getNamedValue("llvm.objc.autoreleasePoolPush") ||
53  M.getNamedValue("llvm.objc.loadWeakRetained") ||
54  M.getNamedValue("llvm.objc.loadWeak") ||
55  M.getNamedValue("llvm.objc.destroyWeak") ||
56  M.getNamedValue("llvm.objc.storeWeak") ||
57  M.getNamedValue("llvm.objc.initWeak") ||
58  M.getNamedValue("llvm.objc.moveWeak") ||
59  M.getNamedValue("llvm.objc.copyWeak") ||
60  M.getNamedValue("llvm.objc.retainedObject") ||
61  M.getNamedValue("llvm.objc.unretainedObject") ||
62  M.getNamedValue("llvm.objc.unretainedPointer") ||
63  M.getNamedValue("llvm.objc.clang.arc.use");
64 }
65 
66 /// This is a wrapper around getUnderlyingObject which also knows how to
67 /// look through objc_retain and objc_autorelease calls, which we know to return
68 /// their argument verbatim.
69 inline const Value *GetUnderlyingObjCPtr(const Value *V) {
70  for (;;) {
71  V = getUnderlyingObject(V);
73  break;
74  V = cast<CallInst>(V)->getArgOperand(0);
75  }
76 
77  return V;
78 }
79 
80 /// A wrapper for GetUnderlyingObjCPtr used for results memoization.
81 inline const Value *
84  if (auto InCache = Cache.lookup(V))
85  return InCache;
86 
87  const Value *Computed = GetUnderlyingObjCPtr(V);
88  Cache[V] = const_cast<Value *>(Computed);
89  return Computed;
90 }
91 
92 /// The RCIdentity root of a value \p V is a dominating value U for which
93 /// retaining or releasing U is equivalent to retaining or releasing V. In other
94 /// words, ARC operations on \p V are equivalent to ARC operations on \p U.
95 ///
96 /// We use this in the ARC optimizer to make it easier to match up ARC
97 /// operations by always mapping ARC operations to RCIdentityRoots instead of
98 /// pointers themselves.
99 ///
100 /// The two ways that we see RCIdentical values in ObjC are via:
101 ///
102 /// 1. PointerCasts
103 /// 2. Forwarding Calls that return their argument verbatim.
104 ///
105 /// Thus this function strips off pointer casts and forwarding calls. *NOTE*
106 /// This implies that two RCIdentical values must alias.
107 inline const Value *GetRCIdentityRoot(const Value *V) {
108  for (;;) {
109  V = V->stripPointerCasts();
111  break;
112  V = cast<CallInst>(V)->getArgOperand(0);
113  }
114  return V;
115 }
116 
117 /// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
118 /// casts away the const of the result. For documentation about what an
119 /// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
120 /// function.
122  return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
123 }
124 
125 /// Assuming the given instruction is one of the special calls such as
126 /// objc_retain or objc_release, return the RCIdentity root of the argument of
127 /// the call.
129  return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
130 }
131 
132 inline bool IsNullOrUndef(const Value *V) {
133  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
134 }
135 
136 inline bool IsNoopInstruction(const Instruction *I) {
137  return isa<BitCastInst>(I) ||
138  (isa<GetElementPtrInst>(I) &&
139  cast<GetElementPtrInst>(I)->hasAllZeroIndices());
140 }
141 
142 /// Test whether the given value is possible a retainable object pointer.
143 inline bool IsPotentialRetainableObjPtr(const Value *Op) {
144  // Pointers to static or stack storage are not valid retainable object
145  // pointers.
146  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
147  return false;
148  // Special arguments can not be a valid retainable object pointer.
149  if (const Argument *Arg = dyn_cast<Argument>(Op))
150  if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
151  Arg->hasStructRetAttr())
152  return false;
153  // Only consider values with pointer types.
154  //
155  // It seemes intuitive to exclude function pointer types as well, since
156  // functions are never retainable object pointers, however clang occasionally
157  // bitcasts retainable object pointers to function-pointer type temporarily.
158  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
159  if (!Ty)
160  return false;
161  // Conservatively assume anything else is a potential retainable object
162  // pointer.
163  return true;
164 }
165 
167 
168 /// Helper for GetARCInstKind. Determines what kind of construct CS
169 /// is.
171  for (auto I = CB.arg_begin(), E = CB.arg_end(); I != E; ++I)
174 
176 }
177 
178 /// Return true if this value refers to a distinct and identifiable
179 /// object.
180 ///
181 /// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
182 /// special knowledge of ObjC conventions.
183 inline bool IsObjCIdentifiedObject(const Value *V) {
184  // Assume that call results and arguments have their own "provenance".
185  // Constants (including GlobalVariables) and Allocas are never
186  // reference-counted.
187  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
188  isa<Argument>(V) || isa<Constant>(V) ||
189  isa<AllocaInst>(V))
190  return true;
191 
192  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
193  const Value *Pointer =
194  GetRCIdentityRoot(LI->getPointerOperand());
195  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
196  // A constant pointer can't be pointing to an object on the heap. It may
197  // be reference-counted, but it won't be deleted.
198  if (GV->isConstant())
199  return true;
200  StringRef Name = GV->getName();
201  // These special variables are known to hold values which are not
202  // reference-counted pointers.
203  if (Name.startswith("\01l_objc_msgSend_fixup_"))
204  return true;
205 
206  StringRef Section = GV->getSection();
207  if (Section.find("__message_refs") != StringRef::npos ||
208  Section.find("__objc_classrefs") != StringRef::npos ||
209  Section.find("__objc_superrefs") != StringRef::npos ||
210  Section.find("__objc_methname") != StringRef::npos ||
211  Section.find("__cstring") != StringRef::npos)
212  return true;
213  }
214  }
215 
216  return false;
217 }
218 
219 enum class ARCMDKindID {
221  CopyOnEscape,
223 };
224 
225 /// A cache of MDKinds used by various ARC optimizations.
227  Module *M;
228 
229  /// The Metadata Kind for clang.imprecise_release metadata.
230  llvm::Optional<unsigned> ImpreciseReleaseMDKind;
231 
232  /// The Metadata Kind for clang.arc.copy_on_escape metadata.
233  llvm::Optional<unsigned> CopyOnEscapeMDKind;
234 
235  /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
236  llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
237 
238 public:
239  void init(Module *Mod) {
240  M = Mod;
241  ImpreciseReleaseMDKind = NoneType::None;
242  CopyOnEscapeMDKind = NoneType::None;
243  NoObjCARCExceptionsMDKind = NoneType::None;
244  }
245 
246  unsigned get(ARCMDKindID ID) {
247  switch (ID) {
249  if (!ImpreciseReleaseMDKind)
250  ImpreciseReleaseMDKind =
251  M->getContext().getMDKindID("clang.imprecise_release");
252  return *ImpreciseReleaseMDKind;
254  if (!CopyOnEscapeMDKind)
255  CopyOnEscapeMDKind =
256  M->getContext().getMDKindID("clang.arc.copy_on_escape");
257  return *CopyOnEscapeMDKind;
259  if (!NoObjCARCExceptionsMDKind)
260  NoObjCARCExceptionsMDKind =
261  M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
262  return *NoObjCARCExceptionsMDKind;
263  }
264  llvm_unreachable("Covered switch isn't covered?!");
265  }
266 };
267 
268 } // end namespace objcarc
269 } // end namespace llvm
270 
271 #endif
llvm::objcarc::GetBasicARCInstKind
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
Definition: ObjCARCInstKind.h:104
llvm::objcarc::ARCInstKind::User
@ User
could "use" a pointer
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition: Argument.h:29
llvm
Definition: AllocatorList.h:23
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
Optional.h
llvm::DenseMapBase< DenseMap< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::lookup
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:197
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:60
llvm::objcarc::ARCMDKindCache::get
unsigned get(ARCMDKindID ID)
Definition: ObjCARCAnalysisUtils.h:246
llvm::objcarc::ARCMDKindCache::init
void init(Module *Mod)
Definition: ObjCARCAnalysisUtils.h:239
llvm::GlobalVariable
Definition: GlobalVariable.h:40
ValueTracking.h
Module.h
llvm::Optional< unsigned >
llvm::objcarc::ARCInstKind::Call
@ Call
could call objc_release
llvm::CallBase::arg_begin
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Definition: InstrTypes.h:1306
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:78
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:206
Constants.h
llvm::objcarc::IsPotentialRetainableObjPtr
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
Definition: ObjCARCAnalysisUtils.h:143
llvm::AAResults
Definition: AliasAnalysis.h:456
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::objcarc::GetArgRCIdentityRoot
Value * GetArgRCIdentityRoot(Value *Inst)
Assuming the given instruction is one of the special calls such as objc_retain or objc_release,...
Definition: ObjCARCAnalysisUtils.h:128
llvm::objcarc::ARCInstKind::CallOrUser
@ CallOrUser
could call objc_release and/or "use" pointers
llvm::Instruction
Definition: Instruction.h:45
llvm::getUnderlyingObject
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
Definition: ValueTracking.cpp:4314
llvm::objcarc::ARCMDKindID
ARCMDKindID
Definition: ObjCARCAnalysisUtils.h:219
llvm::objcarc::ARCInstKind
ARCInstKind
Definition: ObjCARCInstKind.h:28
llvm::CallBase::onlyReadsMemory
bool onlyReadsMemory(unsigned OpNo) const
Definition: InstrTypes.h:1705
llvm::objcarc::ARCMDKindID::CopyOnEscape
@ CopyOnEscape
llvm::objcarc::ARCMDKindID::ImpreciseRelease
@ ImpreciseRelease
llvm::NoneType::None
@ None
llvm::objcarc::ARCMDKindID::NoObjCARCExceptions
@ NoObjCARCExceptions
llvm::DenseMap
Definition: DenseMap.h:714
llvm::objcarc::GetUnderlyingObjCPtrCached
const Value * GetUnderlyingObjCPtrCached(const Value *V, DenseMap< const Value *, WeakTrackingVH > &Cache)
A wrapper for GetUnderlyingObjCPtr used for results memoization.
Definition: ObjCARCAnalysisUtils.h:82
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:634
ObjCARCInstKind.h
llvm::objcarc::EnableARCOpts
bool EnableARCOpts
A handy option to enable/disable all ARC Optimizations.
Definition: ObjCARCAnalysisUtils.cpp:23
llvm::objcarc::IsObjCIdentifiedObject
bool IsObjCIdentifiedObject(const Value *V)
Return true if this value refers to a distinct and identifiable object.
Definition: ObjCARCAnalysisUtils.h:183
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::CallBase::arg_end
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
Definition: InstrTypes.h:1312
llvm::objcarc::IsNoopInstruction
bool IsNoopInstruction(const Instruction *I)
Definition: ObjCARCAnalysisUtils.h:136
llvm::objcarc::ARCMDKindCache
A cache of MDKinds used by various ARC optimizations.
Definition: ObjCARCAnalysisUtils.h:226
llvm::objcarc::IsNullOrUndef
bool IsNullOrUndef(const Value *V)
Definition: ObjCARCAnalysisUtils.h:132
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::objcarc::GetUnderlyingObjCPtr
const Value * GetUnderlyingObjCPtr(const Value *V)
This is a wrapper around getUnderlyingObject which also knows how to look through objc_retain and obj...
Definition: ObjCARCAnalysisUtils.h:69
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
ValueHandle.h
llvm::objcarc::GetRCIdentityRoot
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...
Definition: ObjCARCAnalysisUtils.h:107
llvm::Value::stripPointerCasts
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:662
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:314
llvm::objcarc::ModuleHasARC
bool ModuleHasARC(const Module &M)
Test if the given module looks interesting to run ARC optimization on.
Definition: ObjCARCAnalysisUtils.h:43
llvm::objcarc::GetCallSiteClass
ARCInstKind GetCallSiteClass(const CallBase &CB)
Helper for GetARCInstKind.
Definition: ObjCARCAnalysisUtils.h:170
llvm::objcarc::ARCInstKind::None
@ None
anything that is inert from an ARC perspective.
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1164
Mod
Module * Mod
Definition: PassBuilderBindings.cpp:54
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::objcarc::IsForwarding
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
Definition: ObjCARCInstKind.cpp:416
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38