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"
28#include "llvm/Analysis/AliasAnalysis.h"
29#include "llvm/Analysis/ObjCARCInstKind.h"
30#include "llvm/Analysis/Passes.h"
31#include "llvm/Analysis/ValueTracking.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
39namespace llvm {
40class raw_ostream;
41}
42
43namespace llvm {
44namespace objcarc {
45
46/// \brief A handy option to enable/disable all ARC Optimizations.
47extern bool EnableARCOpts;
48
49/// \brief Test if the given module looks interesting to run ARC optimization
50/// on.
51inline 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/// \brief 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.
77inline const Value *GetUnderlyingObjCPtr(const Value *V,
78                                                const DataLayout &DL) {
79  for (;;) {
80    V = GetUnderlyingObject(V, DL);
81    if (!IsForwarding(GetBasicARCInstKind(V)))
82      break;
83    V = cast<CallInst>(V)->getArgOperand(0);
84  }
85
86  return V;
87}
88
89/// The RCIdentity root of a value \p V is a dominating value U for which
90/// retaining or releasing U is equivalent to retaining or releasing V. In other
91/// words, ARC operations on \p V are equivalent to ARC operations on \p U.
92///
93/// We use this in the ARC optimizer to make it easier to match up ARC
94/// operations by always mapping ARC operations to RCIdentityRoots instead of
95/// pointers themselves.
96///
97/// The two ways that we see RCIdentical values in ObjC are via:
98///
99///   1. PointerCasts
100///   2. Forwarding Calls that return their argument verbatim.
101///
102/// Thus this function strips off pointer casts and forwarding calls. *NOTE*
103/// This implies that two RCIdentical values must alias.
104inline const Value *GetRCIdentityRoot(const Value *V) {
105  for (;;) {
106    V = V->stripPointerCasts();
107    if (!IsForwarding(GetBasicARCInstKind(V)))
108      break;
109    V = cast<CallInst>(V)->getArgOperand(0);
110  }
111  return V;
112}
113
114/// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
115/// casts away the const of the result. For documentation about what an
116/// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
117/// function.
118inline Value *GetRCIdentityRoot(Value *V) {
119  return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
120}
121
122/// \brief Assuming the given instruction is one of the special calls such as
123/// objc_retain or objc_release, return the RCIdentity root of the argument of
124/// the call.
125inline Value *GetArgRCIdentityRoot(Value *Inst) {
126  return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
127}
128
129inline bool IsNullOrUndef(const Value *V) {
130  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
131}
132
133inline bool IsNoopInstruction(const Instruction *I) {
134  return isa<BitCastInst>(I) ||
135    (isa<GetElementPtrInst>(I) &&
136     cast<GetElementPtrInst>(I)->hasAllZeroIndices());
137}
138
139/// \brief Test whether the given value is possible a retainable object pointer.
140inline bool IsPotentialRetainableObjPtr(const Value *Op) {
141  // Pointers to static or stack storage are not valid retainable object
142  // pointers.
143  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
144    return false;
145  // Special arguments can not be a valid retainable object pointer.
146  if (const Argument *Arg = dyn_cast<Argument>(Op))
147    if (Arg->hasByValAttr() ||
148        Arg->hasInAllocaAttr() ||
149        Arg->hasNestAttr() ||
150        Arg->hasStructRetAttr())
151      return false;
152  // Only consider values with pointer types.
153  //
154  // It seemes intuitive to exclude function pointer types as well, since
155  // functions are never retainable object pointers, however clang occasionally
156  // bitcasts retainable object pointers to function-pointer type temporarily.
157  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
158  if (!Ty)
159    return false;
160  // Conservatively assume anything else is a potential retainable object
161  // pointer.
162  return true;
163}
164
165inline bool IsPotentialRetainableObjPtr(const Value *Op,
166                                               AliasAnalysis &AA) {
167  // First make the rudimentary check.
168  if (!IsPotentialRetainableObjPtr(Op))
169    return false;
170
171  // Objects in constant memory are not reference-counted.
172  if (AA.pointsToConstantMemory(Op))
173    return false;
174
175  // Pointers in constant memory are not pointing to reference-counted objects.
176  if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
177    if (AA.pointsToConstantMemory(LI->getPointerOperand()))
178      return false;
179
180  // Otherwise assume the worst.
181  return true;
182}
183
184/// \brief Helper for GetARCInstKind. Determines what kind of construct CS
185/// is.
186inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
187  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
188       I != E; ++I)
189    if (IsPotentialRetainableObjPtr(*I))
190      return CS.onlyReadsMemory() ? ARCInstKind::User : ARCInstKind::CallOrUser;
191
192  return CS.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call;
193}
194
195/// \brief Return true if this value refers to a distinct and identifiable
196/// object.
197///
198/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
199/// special knowledge of ObjC conventions.
200inline bool IsObjCIdentifiedObject(const Value *V) {
201  // Assume that call results and arguments have their own "provenance".
202  // Constants (including GlobalVariables) and Allocas are never
203  // reference-counted.
204  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
205      isa<Argument>(V) || isa<Constant>(V) ||
206      isa<AllocaInst>(V))
207    return true;
208
209  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
210    const Value *Pointer =
211      GetRCIdentityRoot(LI->getPointerOperand());
212    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
213      // A constant pointer can't be pointing to an object on the heap. It may
214      // be reference-counted, but it won't be deleted.
215      if (GV->isConstant())
216        return true;
217      StringRef Name = GV->getName();
218      // These special variables are known to hold values which are not
219      // reference-counted pointers.
220      if (Name.startswith("\01l_objc_msgSend_fixup_"))
221        return true;
222
223      StringRef Section = GV->getSection();
224      if (Section.find("__message_refs") != StringRef::npos ||
225          Section.find("__objc_classrefs") != StringRef::npos ||
226          Section.find("__objc_superrefs") != StringRef::npos ||
227          Section.find("__objc_methname") != StringRef::npos ||
228          Section.find("__cstring") != StringRef::npos)
229        return true;
230    }
231  }
232
233  return false;
234}
235
236enum class ARCMDKindID {
237  ImpreciseRelease,
238  CopyOnEscape,
239  NoObjCARCExceptions,
240};
241
242/// A cache of MDKinds used by various ARC optimizations.
243class ARCMDKindCache {
244  Module *M;
245
246  /// The Metadata Kind for clang.imprecise_release metadata.
247  llvm::Optional<unsigned> ImpreciseReleaseMDKind;
248
249  /// The Metadata Kind for clang.arc.copy_on_escape metadata.
250  llvm::Optional<unsigned> CopyOnEscapeMDKind;
251
252  /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
253  llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
254
255public:
256  void init(Module *Mod) {
257    M = Mod;
258    ImpreciseReleaseMDKind = NoneType::None;
259    CopyOnEscapeMDKind = NoneType::None;
260    NoObjCARCExceptionsMDKind = NoneType::None;
261  }
262
263  unsigned get(ARCMDKindID ID) {
264    switch (ID) {
265    case ARCMDKindID::ImpreciseRelease:
266      if (!ImpreciseReleaseMDKind)
267        ImpreciseReleaseMDKind =
268            M->getContext().getMDKindID("clang.imprecise_release");
269      return *ImpreciseReleaseMDKind;
270    case ARCMDKindID::CopyOnEscape:
271      if (!CopyOnEscapeMDKind)
272        CopyOnEscapeMDKind =
273            M->getContext().getMDKindID("clang.arc.copy_on_escape");
274      return *CopyOnEscapeMDKind;
275    case ARCMDKindID::NoObjCARCExceptions:
276      if (!NoObjCARCExceptionsMDKind)
277        NoObjCARCExceptionsMDKind =
278            M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
279      return *NoObjCARCExceptionsMDKind;
280    }
281    llvm_unreachable("Covered switch isn't covered?!");
282  }
283};
284
285} // end namespace objcarc
286} // end namespace llvm
287
288#endif
289