LLVM  7.0.0svn
ObjCARCAnalysisUtils.h
Go to the documentation of this file.
1 //===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file defines common analysis utilities used by the ObjC ARC Optimizer.
11 /// ARC stands for Automatic Reference Counting and is a system for managing
12 /// reference counts for objects in Objective C.
13 ///
14 /// WARNING: This file knows about certain library functions. It recognizes them
15 /// by name, and hardwires knowledge of their semantics.
16 ///
17 /// WARNING: This file knows about how certain Objective-C library functions are
18 /// used. Naive LLVM IR transformations which would otherwise be
19 /// behavior-preserving may break these assumptions.
20 ///
21 //===----------------------------------------------------------------------===//
22 
23 #ifndef LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
24 #define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
25 
26 #include "llvm/ADT/Optional.h"
27 #include "llvm/ADT/StringSwitch.h"
30 #include "llvm/Analysis/Passes.h"
32 #include "llvm/IR/CallSite.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/InstIterator.h"
35 #include "llvm/IR/LLVMContext.h"
36 #include "llvm/IR/Module.h"
37 #include "llvm/Pass.h"
38 
39 namespace llvm {
40 class raw_ostream;
41 }
42 
43 namespace llvm {
44 namespace objcarc {
45 
46 /// A handy option to enable/disable all ARC Optimizations.
47 extern bool EnableARCOpts;
48 
49 /// Test if the given module looks interesting to run ARC optimization
50 /// on.
51 inline bool ModuleHasARC(const Module &M) {
52  return
53  M.getNamedValue("objc_retain") ||
54  M.getNamedValue("objc_release") ||
55  M.getNamedValue("objc_autorelease") ||
56  M.getNamedValue("objc_retainAutoreleasedReturnValue") ||
57  M.getNamedValue("objc_unsafeClaimAutoreleasedReturnValue") ||
58  M.getNamedValue("objc_retainBlock") ||
59  M.getNamedValue("objc_autoreleaseReturnValue") ||
60  M.getNamedValue("objc_autoreleasePoolPush") ||
61  M.getNamedValue("objc_loadWeakRetained") ||
62  M.getNamedValue("objc_loadWeak") ||
63  M.getNamedValue("objc_destroyWeak") ||
64  M.getNamedValue("objc_storeWeak") ||
65  M.getNamedValue("objc_initWeak") ||
66  M.getNamedValue("objc_moveWeak") ||
67  M.getNamedValue("objc_copyWeak") ||
68  M.getNamedValue("objc_retainedObject") ||
69  M.getNamedValue("objc_unretainedObject") ||
70  M.getNamedValue("objc_unretainedPointer") ||
71  M.getNamedValue("clang.arc.use");
72 }
73 
74 /// This is a wrapper around getUnderlyingObject which also knows how to
75 /// look through objc_retain and objc_autorelease calls, which we know to return
76 /// their argument verbatim.
77 inline const Value *GetUnderlyingObjCPtr(const Value *V,
78  const DataLayout &DL) {
79  for (;;) {
80  V = GetUnderlyingObject(V, DL);
82  break;
83  V = cast<CallInst>(V)->getArgOperand(0);
84  }
85 
86  return V;
87 }
88 
89 /// A wrapper for GetUnderlyingObjCPtr used for results memoization.
90 inline const Value *
93  if (auto InCache = Cache.lookup(V))
94  return InCache;
95 
96  return Cache[V] = GetUnderlyingObjCPtr(V, DL);
97 }
98 
99 /// The RCIdentity root of a value \p V is a dominating value U for which
100 /// retaining or releasing U is equivalent to retaining or releasing V. In other
101 /// words, ARC operations on \p V are equivalent to ARC operations on \p U.
102 ///
103 /// We use this in the ARC optimizer to make it easier to match up ARC
104 /// operations by always mapping ARC operations to RCIdentityRoots instead of
105 /// pointers themselves.
106 ///
107 /// The two ways that we see RCIdentical values in ObjC are via:
108 ///
109 /// 1. PointerCasts
110 /// 2. Forwarding Calls that return their argument verbatim.
111 ///
112 /// Thus this function strips off pointer casts and forwarding calls. *NOTE*
113 /// This implies that two RCIdentical values must alias.
114 inline const Value *GetRCIdentityRoot(const Value *V) {
115  for (;;) {
116  V = V->stripPointerCasts();
118  break;
119  V = cast<CallInst>(V)->getArgOperand(0);
120  }
121  return V;
122 }
123 
124 /// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
125 /// casts away the const of the result. For documentation about what an
126 /// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
127 /// function.
129  return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
130 }
131 
132 /// Assuming the given instruction is one of the special calls such as
133 /// objc_retain or objc_release, return the RCIdentity root of the argument of
134 /// the call.
136  return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
137 }
138 
139 inline bool IsNullOrUndef(const Value *V) {
140  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
141 }
142 
143 inline bool IsNoopInstruction(const Instruction *I) {
144  return isa<BitCastInst>(I) ||
145  (isa<GetElementPtrInst>(I) &&
146  cast<GetElementPtrInst>(I)->hasAllZeroIndices());
147 }
148 
149 /// Test whether the given value is possible a retainable object pointer.
150 inline bool IsPotentialRetainableObjPtr(const Value *Op) {
151  // Pointers to static or stack storage are not valid retainable object
152  // pointers.
153  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
154  return false;
155  // Special arguments can not be a valid retainable object pointer.
156  if (const Argument *Arg = dyn_cast<Argument>(Op))
157  if (Arg->hasByValAttr() ||
158  Arg->hasInAllocaAttr() ||
159  Arg->hasNestAttr() ||
160  Arg->hasStructRetAttr())
161  return false;
162  // Only consider values with pointer types.
163  //
164  // It seemes intuitive to exclude function pointer types as well, since
165  // functions are never retainable object pointers, however clang occasionally
166  // bitcasts retainable object pointers to function-pointer type temporarily.
167  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
168  if (!Ty)
169  return false;
170  // Conservatively assume anything else is a potential retainable object
171  // pointer.
172  return true;
173 }
174 
176  AliasAnalysis &AA) {
177  // First make the rudimentary check.
179  return false;
180 
181  // Objects in constant memory are not reference-counted.
182  if (AA.pointsToConstantMemory(Op))
183  return false;
184 
185  // Pointers in constant memory are not pointing to reference-counted objects.
186  if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
187  if (AA.pointsToConstantMemory(LI->getPointerOperand()))
188  return false;
189 
190  // Otherwise assume the worst.
191  return true;
192 }
193 
194 /// Helper for GetARCInstKind. Determines what kind of construct CS
195 /// is.
198  I != E; ++I)
201 
203 }
204 
205 /// Return true if this value refers to a distinct and identifiable
206 /// object.
207 ///
208 /// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
209 /// special knowledge of ObjC conventions.
210 inline bool IsObjCIdentifiedObject(const Value *V) {
211  // Assume that call results and arguments have their own "provenance".
212  // Constants (including GlobalVariables) and Allocas are never
213  // reference-counted.
214  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
215  isa<Argument>(V) || isa<Constant>(V) ||
216  isa<AllocaInst>(V))
217  return true;
218 
219  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
220  const Value *Pointer =
221  GetRCIdentityRoot(LI->getPointerOperand());
222  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
223  // A constant pointer can't be pointing to an object on the heap. It may
224  // be reference-counted, but it won't be deleted.
225  if (GV->isConstant())
226  return true;
227  StringRef Name = GV->getName();
228  // These special variables are known to hold values which are not
229  // reference-counted pointers.
230  if (Name.startswith("\01l_objc_msgSend_fixup_"))
231  return true;
232 
233  StringRef Section = GV->getSection();
234  if (Section.find("__message_refs") != StringRef::npos ||
235  Section.find("__objc_classrefs") != StringRef::npos ||
236  Section.find("__objc_superrefs") != StringRef::npos ||
237  Section.find("__objc_methname") != StringRef::npos ||
238  Section.find("__cstring") != StringRef::npos)
239  return true;
240  }
241  }
242 
243  return false;
244 }
245 
246 enum class ARCMDKindID {
248  CopyOnEscape,
250 };
251 
252 /// A cache of MDKinds used by various ARC optimizations.
254  Module *M;
255 
256  /// The Metadata Kind for clang.imprecise_release metadata.
257  llvm::Optional<unsigned> ImpreciseReleaseMDKind;
258 
259  /// The Metadata Kind for clang.arc.copy_on_escape metadata.
260  llvm::Optional<unsigned> CopyOnEscapeMDKind;
261 
262  /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
263  llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
264 
265 public:
266  void init(Module *Mod) {
267  M = Mod;
268  ImpreciseReleaseMDKind = NoneType::None;
269  CopyOnEscapeMDKind = NoneType::None;
270  NoObjCARCExceptionsMDKind = NoneType::None;
271  }
272 
273  unsigned get(ARCMDKindID ID) {
274  switch (ID) {
276  if (!ImpreciseReleaseMDKind)
277  ImpreciseReleaseMDKind =
278  M->getContext().getMDKindID("clang.imprecise_release");
279  return *ImpreciseReleaseMDKind;
281  if (!CopyOnEscapeMDKind)
282  CopyOnEscapeMDKind =
283  M->getContext().getMDKindID("clang.arc.copy_on_escape");
284  return *CopyOnEscapeMDKind;
286  if (!NoObjCARCExceptionsMDKind)
287  NoObjCARCExceptionsMDKind =
288  M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
289  return *NoObjCARCExceptionsMDKind;
290  }
291  llvm_unreachable("Covered switch isn't covered?!");
292  }
293 };
294 
295 } // end namespace objcarc
296 } // end namespace llvm
297 
298 #endif
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
This class represents an incoming formal argument to a Function.
Definition: Argument.h:30
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
could call objc_release and/or "use" pointers
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
Value * GetArgRCIdentityRoot(Value *Inst)
Assuming the given instruction is one of the special calls such as objc_retain or objc_release...
could call objc_release
An instruction for reading from memory.
Definition: Instructions.h:164
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
bool IsObjCIdentifiedObject(const Value *V)
Return true if this value refers to a distinct and identifiable object.
bool onlyReadsMemory() const
Determine if the call does not access or only reads memory.
Definition: CallSite.h:454
unsigned getMDKindID(StringRef Name) const
getMDKindID - Return a unique non-zero ID for the specified metadata kind.
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:242
A Use represents the edge between a Value definition and its users.
Definition: Use.h:56
IterTy arg_end() const
Definition: CallSite.h:575
bool IsNullOrUndef(const Value *V)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
bool EnableARCOpts
A handy option to enable/disable all ARC Optimizations.
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type. ...
Definition: Module.cpp:112
bool ModuleHasARC(const Module &M)
Test if the given module looks interesting to run ARC optimization on.
Class to represent pointers.
Definition: DerivedTypes.h:467
bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal=false)
Checks whether the given location points to constant memory, or if OrLocal is true whether it points ...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
A cache of MDKinds used by various ARC optimizations.
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs, and aliases.
Definition: Value.cpp:538
anything that is inert from an ARC perspective.
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
ARCInstKind GetBasicARCInstKind(const Value *V)
Determine which objc runtime call instruction class V belongs to.
IterTy arg_begin() const
Definition: CallSite.h:571
const Value * GetUnderlyingObjCPtrCached(const Value *V, const DataLayout &DL, DenseMap< const Value *, const Value *> &Cache)
A wrapper for GetUnderlyingObjCPtr used for results memoization.
ARCInstKind
Equivalence classes of instructions in the ARC Model.
Module.h This file contains the declarations for the Module class.
amdgpu Simplify well known AMD library false Value Value * Arg
could "use" a pointer
static const size_t npos
Definition: StringRef.h:51
Establish a view to a call site for examination.
Definition: CallSite.h:713
#define I(x, y, z)
Definition: MD5.cpp:58
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
ARCInstKind GetCallSiteClass(ImmutableCallSite CS)
Helper for GetARCInstKind.
const Value * GetUnderlyingObjCPtr(const Value *V, const DataLayout &DL)
This is a wrapper around getUnderlyingObject which also knows how to look through objc_retain and obj...
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:181
LLVM Value Representation.
Definition: Value.h:73
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...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:298
bool IsNoopInstruction(const Instruction *I)