LLVM  15.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.
82  const Value *V,
83  DenseMap<const Value *, std::pair<WeakVH, WeakTrackingVH>> &Cache) {
84  // The entry is invalid if either value handle is null.
85  auto InCache = Cache.lookup(V);
86  if (InCache.first && InCache.second)
87  return InCache.second;
88 
89  const Value *Computed = GetUnderlyingObjCPtr(V);
90  Cache[V] =
91  std::make_pair(const_cast<Value *>(V), const_cast<Value *>(Computed));
92  return Computed;
93 }
94 
95 /// The RCIdentity root of a value \p V is a dominating value U for which
96 /// retaining or releasing U is equivalent to retaining or releasing V. In other
97 /// words, ARC operations on \p V are equivalent to ARC operations on \p U.
98 ///
99 /// We use this in the ARC optimizer to make it easier to match up ARC
100 /// operations by always mapping ARC operations to RCIdentityRoots instead of
101 /// pointers themselves.
102 ///
103 /// The two ways that we see RCIdentical values in ObjC are via:
104 ///
105 /// 1. PointerCasts
106 /// 2. Forwarding Calls that return their argument verbatim.
107 ///
108 /// Thus this function strips off pointer casts and forwarding calls. *NOTE*
109 /// This implies that two RCIdentical values must alias.
110 inline const Value *GetRCIdentityRoot(const Value *V) {
111  for (;;) {
112  V = V->stripPointerCasts();
114  break;
115  V = cast<CallInst>(V)->getArgOperand(0);
116  }
117  return V;
118 }
119 
120 /// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
121 /// casts away the const of the result. For documentation about what an
122 /// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
123 /// function.
125  return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
126 }
127 
128 /// Assuming the given instruction is one of the special calls such as
129 /// objc_retain or objc_release, return the RCIdentity root of the argument of
130 /// the call.
132  return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
133 }
134 
135 inline bool IsNullOrUndef(const Value *V) {
136  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
137 }
138 
139 inline bool IsNoopInstruction(const Instruction *I) {
140  return isa<BitCastInst>(I) ||
141  (isa<GetElementPtrInst>(I) &&
142  cast<GetElementPtrInst>(I)->hasAllZeroIndices());
143 }
144 
145 /// Test whether the given value is possible a retainable object pointer.
146 inline bool IsPotentialRetainableObjPtr(const Value *Op) {
147  // Pointers to static or stack storage are not valid retainable object
148  // pointers.
149  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
150  return false;
151  // Special arguments can not be a valid retainable object pointer.
152  if (const Argument *Arg = dyn_cast<Argument>(Op))
153  if (Arg->hasPassPointeeByValueCopyAttr() || Arg->hasNestAttr() ||
154  Arg->hasStructRetAttr())
155  return false;
156  // Only consider values with pointer types.
157  //
158  // It seemes intuitive to exclude function pointer types as well, since
159  // functions are never retainable object pointers, however clang occasionally
160  // bitcasts retainable object pointers to function-pointer type temporarily.
161  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
162  if (!Ty)
163  return false;
164  // Conservatively assume anything else is a potential retainable object
165  // pointer.
166  return true;
167 }
168 
170 
171 /// Helper for GetARCInstKind. Determines what kind of construct CS
172 /// is.
174  for (const Use &U : CB.args())
177 
179 }
180 
181 /// Return true if this value refers to a distinct and identifiable
182 /// object.
183 ///
184 /// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
185 /// special knowledge of ObjC conventions.
186 inline bool IsObjCIdentifiedObject(const Value *V) {
187  // Assume that call results and arguments have their own "provenance".
188  // Constants (including GlobalVariables) and Allocas are never
189  // reference-counted.
190  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
191  isa<Argument>(V) || isa<Constant>(V) ||
192  isa<AllocaInst>(V))
193  return true;
194 
195  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
196  const Value *Pointer =
197  GetRCIdentityRoot(LI->getPointerOperand());
198  if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
199  // A constant pointer can't be pointing to an object on the heap. It may
200  // be reference-counted, but it won't be deleted.
201  if (GV->isConstant())
202  return true;
203  StringRef Name = GV->getName();
204  // These special variables are known to hold values which are not
205  // reference-counted pointers.
206  if (Name.startswith("\01l_objc_msgSend_fixup_"))
207  return true;
208 
209  StringRef Section = GV->getSection();
210  if (Section.contains("__message_refs") ||
211  Section.contains("__objc_classrefs") ||
212  Section.contains("__objc_superrefs") ||
213  Section.contains("__objc_methname") || Section.contains("__cstring"))
214  return true;
215  }
216  }
217 
218  return false;
219 }
220 
221 enum class ARCMDKindID {
223  CopyOnEscape,
225 };
226 
227 /// A cache of MDKinds used by various ARC optimizations.
229  Module *M;
230 
231  /// The Metadata Kind for clang.imprecise_release metadata.
232  llvm::Optional<unsigned> ImpreciseReleaseMDKind;
233 
234  /// The Metadata Kind for clang.arc.copy_on_escape metadata.
235  llvm::Optional<unsigned> CopyOnEscapeMDKind;
236 
237  /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
238  llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
239 
240 public:
241  void init(Module *Mod) {
242  M = Mod;
243  ImpreciseReleaseMDKind = NoneType::None;
244  CopyOnEscapeMDKind = NoneType::None;
245  NoObjCARCExceptionsMDKind = NoneType::None;
246  }
247 
248  unsigned get(ARCMDKindID ID) {
249  switch (ID) {
251  if (!ImpreciseReleaseMDKind)
252  ImpreciseReleaseMDKind =
253  M->getContext().getMDKindID("clang.imprecise_release");
254  return *ImpreciseReleaseMDKind;
256  if (!CopyOnEscapeMDKind)
257  CopyOnEscapeMDKind =
258  M->getContext().getMDKindID("clang.arc.copy_on_escape");
259  return *CopyOnEscapeMDKind;
261  if (!NoObjCARCExceptionsMDKind)
262  NoObjCARCExceptionsMDKind =
263  M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
264  return *NoObjCARCExceptionsMDKind;
265  }
266  llvm_unreachable("Covered switch isn't covered?!");
267  }
268 };
269 
270 } // end namespace objcarc
271 } // end namespace llvm
272 
273 #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:28
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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::objcarc::ARCMDKindCache::get
unsigned get(ARCMDKindID ID)
Definition: ObjCARCAnalysisUtils.h:248
llvm::objcarc::ARCMDKindCache::init
void init(Module *Mod)
Definition: ObjCARCAnalysisUtils.h:241
llvm::GlobalVariable
Definition: GlobalVariable.h:39
ValueTracking.h
Module.h
llvm::Optional< unsigned >
llvm::objcarc::ARCInstKind::Call
@ Call
could call objc_release
Arg
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
Definition: AMDGPULibCalls.cpp:186
Constants.h
llvm::objcarc::IsPotentialRetainableObjPtr
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
Definition: ObjCARCAnalysisUtils.h:146
llvm::AAResults
Definition: AliasAnalysis.h:511
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:131
llvm::objcarc::ARCInstKind::CallOrUser
@ CallOrUser
could call objc_release and/or "use" pointers
llvm::Instruction
Definition: Instruction.h:42
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:4455
llvm::objcarc::ARCMDKindID
ARCMDKindID
Definition: ObjCARCAnalysisUtils.h:221
llvm::objcarc::ARCInstKind
ARCInstKind
Definition: ObjCARCInstKind.h:28
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::CallBase::onlyReadsMemory
bool onlyReadsMemory(unsigned OpNo) const
Definition: InstrTypes.h:1720
llvm::objcarc::GetUnderlyingObjCPtrCached
const Value * GetUnderlyingObjCPtrCached(const Value *V, DenseMap< const Value *, std::pair< WeakVH, WeakTrackingVH >> &Cache)
A wrapper for GetUnderlyingObjCPtr used for results memoization.
Definition: ObjCARCAnalysisUtils.h:81
llvm::objcarc::ARCMDKindID::CopyOnEscape
@ CopyOnEscape
llvm::objcarc::ARCMDKindID::ImpreciseRelease
@ ImpreciseRelease
llvm::NoneType::None
@ None
llvm::objcarc::ARCMDKindID::NoObjCARCExceptions
@ NoObjCARCExceptions
llvm::DenseMap
Definition: DenseMap.h:716
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:632
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:186
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::objcarc::IsNoopInstruction
bool IsNoopInstruction(const Instruction *I)
Definition: ObjCARCAnalysisUtils.h:139
llvm::objcarc::ARCMDKindCache
A cache of MDKinds used by various ARC optimizations.
Definition: ObjCARCAnalysisUtils.h:228
llvm::objcarc::IsNullOrUndef
bool IsNullOrUndef(const Value *V)
Definition: ObjCARCAnalysisUtils.h:135
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:143
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:173
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:110
llvm::Value::stripPointerCasts
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:682
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:345
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:173
AA
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:1174
Mod
Module * Mod
Definition: PassBuilderBindings.cpp:54
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::objcarc::IsForwarding
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
Definition: ObjCARCInstKind.cpp:415
llvm::CallBase::args
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1332
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43