1263508Sdim//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim/// \file
10249259Sdim/// This file defines common definitions/declarations used by the ObjC ARC
11249259Sdim/// Optimizer. ARC stands for Automatic Reference Counting and is a system for
12249259Sdim/// managing reference counts for objects in Objective C.
13249259Sdim///
14249259Sdim/// WARNING: This file knows about certain library functions. It recognizes them
15249259Sdim/// by name, and hardwires knowledge of their semantics.
16249259Sdim///
17249259Sdim/// WARNING: This file knows about how certain Objective-C library functions are
18249259Sdim/// used. Naive LLVM IR transformations which would otherwise be
19249259Sdim/// behavior-preserving may break these assumptions.
20249259Sdim///
21249259Sdim//===----------------------------------------------------------------------===//
22249259Sdim
23249259Sdim#ifndef LLVM_TRANSFORMS_SCALAR_OBJCARC_H
24249259Sdim#define LLVM_TRANSFORMS_SCALAR_OBJCARC_H
25249259Sdim
26249259Sdim#include "llvm/ADT/StringSwitch.h"
27249259Sdim#include "llvm/Analysis/AliasAnalysis.h"
28249259Sdim#include "llvm/Analysis/Passes.h"
29249259Sdim#include "llvm/Analysis/ValueTracking.h"
30249259Sdim#include "llvm/IR/Module.h"
31249259Sdim#include "llvm/Pass.h"
32249259Sdim#include "llvm/Support/CallSite.h"
33249259Sdim#include "llvm/Support/InstIterator.h"
34249259Sdim#include "llvm/Transforms/ObjCARC.h"
35249259Sdim#include "llvm/Transforms/Utils/Local.h"
36249259Sdim
37249259Sdimnamespace llvm {
38249259Sdimclass raw_ostream;
39249259Sdim}
40249259Sdim
41249259Sdimnamespace llvm {
42249259Sdimnamespace objcarc {
43249259Sdim
44249259Sdim/// \brief A handy option to enable/disable all ARC Optimizations.
45249259Sdimextern bool EnableARCOpts;
46249259Sdim
47249259Sdim/// \brief Test if the given module looks interesting to run ARC optimization
48249259Sdim/// on.
49249259Sdimstatic inline bool ModuleHasARC(const Module &M) {
50249259Sdim  return
51249259Sdim    M.getNamedValue("objc_retain") ||
52249259Sdim    M.getNamedValue("objc_release") ||
53249259Sdim    M.getNamedValue("objc_autorelease") ||
54249259Sdim    M.getNamedValue("objc_retainAutoreleasedReturnValue") ||
55249259Sdim    M.getNamedValue("objc_retainBlock") ||
56249259Sdim    M.getNamedValue("objc_autoreleaseReturnValue") ||
57249259Sdim    M.getNamedValue("objc_autoreleasePoolPush") ||
58249259Sdim    M.getNamedValue("objc_loadWeakRetained") ||
59249259Sdim    M.getNamedValue("objc_loadWeak") ||
60249259Sdim    M.getNamedValue("objc_destroyWeak") ||
61249259Sdim    M.getNamedValue("objc_storeWeak") ||
62249259Sdim    M.getNamedValue("objc_initWeak") ||
63249259Sdim    M.getNamedValue("objc_moveWeak") ||
64249259Sdim    M.getNamedValue("objc_copyWeak") ||
65249259Sdim    M.getNamedValue("objc_retainedObject") ||
66249259Sdim    M.getNamedValue("objc_unretainedObject") ||
67249259Sdim    M.getNamedValue("objc_unretainedPointer") ||
68249259Sdim    M.getNamedValue("clang.arc.use");
69249259Sdim}
70249259Sdim
71249259Sdim/// \enum InstructionClass
72249259Sdim/// \brief A simple classification for instructions.
73249259Sdimenum InstructionClass {
74249259Sdim  IC_Retain,              ///< objc_retain
75249259Sdim  IC_RetainRV,            ///< objc_retainAutoreleasedReturnValue
76249259Sdim  IC_RetainBlock,         ///< objc_retainBlock
77249259Sdim  IC_Release,             ///< objc_release
78249259Sdim  IC_Autorelease,         ///< objc_autorelease
79249259Sdim  IC_AutoreleaseRV,       ///< objc_autoreleaseReturnValue
80249259Sdim  IC_AutoreleasepoolPush, ///< objc_autoreleasePoolPush
81249259Sdim  IC_AutoreleasepoolPop,  ///< objc_autoreleasePoolPop
82249259Sdim  IC_NoopCast,            ///< objc_retainedObject, etc.
83249259Sdim  IC_FusedRetainAutorelease, ///< objc_retainAutorelease
84249259Sdim  IC_FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
85249259Sdim  IC_LoadWeakRetained,    ///< objc_loadWeakRetained (primitive)
86249259Sdim  IC_StoreWeak,           ///< objc_storeWeak (primitive)
87249259Sdim  IC_InitWeak,            ///< objc_initWeak (derived)
88249259Sdim  IC_LoadWeak,            ///< objc_loadWeak (derived)
89249259Sdim  IC_MoveWeak,            ///< objc_moveWeak (derived)
90249259Sdim  IC_CopyWeak,            ///< objc_copyWeak (derived)
91249259Sdim  IC_DestroyWeak,         ///< objc_destroyWeak (derived)
92249259Sdim  IC_StoreStrong,         ///< objc_storeStrong (derived)
93249259Sdim  IC_IntrinsicUser,       ///< clang.arc.use
94249259Sdim  IC_CallOrUser,          ///< could call objc_release and/or "use" pointers
95249259Sdim  IC_Call,                ///< could call objc_release
96249259Sdim  IC_User,                ///< could "use" a pointer
97249259Sdim  IC_None                 ///< anything else
98249259Sdim};
99249259Sdim
100249259Sdimraw_ostream &operator<<(raw_ostream &OS, const InstructionClass Class);
101249259Sdim
102249259Sdim/// \brief Test if the given class is a kind of user.
103249259Sdiminline static bool IsUser(InstructionClass Class) {
104249259Sdim  return Class == IC_User ||
105249259Sdim         Class == IC_CallOrUser ||
106249259Sdim         Class == IC_IntrinsicUser;
107249259Sdim}
108249259Sdim
109249259Sdim/// \brief Test if the given class is objc_retain or equivalent.
110249259Sdimstatic inline bool IsRetain(InstructionClass Class) {
111249259Sdim  return Class == IC_Retain ||
112249259Sdim         Class == IC_RetainRV;
113249259Sdim}
114249259Sdim
115249259Sdim/// \brief Test if the given class is objc_autorelease or equivalent.
116249259Sdimstatic inline bool IsAutorelease(InstructionClass Class) {
117249259Sdim  return Class == IC_Autorelease ||
118249259Sdim         Class == IC_AutoreleaseRV;
119249259Sdim}
120249259Sdim
121249259Sdim/// \brief Test if the given class represents instructions which return their
122249259Sdim/// argument verbatim.
123249259Sdimstatic inline bool IsForwarding(InstructionClass Class) {
124249259Sdim  return Class == IC_Retain ||
125249259Sdim         Class == IC_RetainRV ||
126249259Sdim         Class == IC_Autorelease ||
127249259Sdim         Class == IC_AutoreleaseRV ||
128249259Sdim         Class == IC_NoopCast;
129249259Sdim}
130249259Sdim
131249259Sdim/// \brief Test if the given class represents instructions which do nothing if
132249259Sdim/// passed a null pointer.
133249259Sdimstatic inline bool IsNoopOnNull(InstructionClass Class) {
134249259Sdim  return Class == IC_Retain ||
135249259Sdim         Class == IC_RetainRV ||
136249259Sdim         Class == IC_Release ||
137249259Sdim         Class == IC_Autorelease ||
138249259Sdim         Class == IC_AutoreleaseRV ||
139249259Sdim         Class == IC_RetainBlock;
140249259Sdim}
141249259Sdim
142249259Sdim/// \brief Test if the given class represents instructions which are always safe
143249259Sdim/// to mark with the "tail" keyword.
144249259Sdimstatic inline bool IsAlwaysTail(InstructionClass Class) {
145249259Sdim  // IC_RetainBlock may be given a stack argument.
146249259Sdim  return Class == IC_Retain ||
147249259Sdim         Class == IC_RetainRV ||
148249259Sdim         Class == IC_AutoreleaseRV;
149249259Sdim}
150249259Sdim
151249259Sdim/// \brief Test if the given class represents instructions which are never safe
152249259Sdim/// to mark with the "tail" keyword.
153249259Sdimstatic inline bool IsNeverTail(InstructionClass Class) {
154249259Sdim  /// It is never safe to tail call objc_autorelease since by tail calling
155249259Sdim  /// objc_autorelease, we also tail call -[NSObject autorelease] which supports
156249259Sdim  /// fast autoreleasing causing our object to be potentially reclaimed from the
157249259Sdim  /// autorelease pool which violates the semantics of __autoreleasing types in
158249259Sdim  /// ARC.
159249259Sdim  return Class == IC_Autorelease;
160249259Sdim}
161249259Sdim
162249259Sdim/// \brief Test if the given class represents instructions which are always safe
163249259Sdim/// to mark with the nounwind attribute.
164249259Sdimstatic inline bool IsNoThrow(InstructionClass Class) {
165249259Sdim  // objc_retainBlock is not nounwind because it calls user copy constructors
166249259Sdim  // which could theoretically throw.
167249259Sdim  return Class == IC_Retain ||
168249259Sdim         Class == IC_RetainRV ||
169249259Sdim         Class == IC_Release ||
170249259Sdim         Class == IC_Autorelease ||
171249259Sdim         Class == IC_AutoreleaseRV ||
172249259Sdim         Class == IC_AutoreleasepoolPush ||
173249259Sdim         Class == IC_AutoreleasepoolPop;
174249259Sdim}
175249259Sdim
176249259Sdim/// Test whether the given instruction can autorelease any pointer or cause an
177249259Sdim/// autoreleasepool pop.
178249259Sdimstatic inline bool
179249259SdimCanInterruptRV(InstructionClass Class) {
180249259Sdim  switch (Class) {
181249259Sdim  case IC_AutoreleasepoolPop:
182249259Sdim  case IC_CallOrUser:
183249259Sdim  case IC_Call:
184249259Sdim  case IC_Autorelease:
185249259Sdim  case IC_AutoreleaseRV:
186249259Sdim  case IC_FusedRetainAutorelease:
187249259Sdim  case IC_FusedRetainAutoreleaseRV:
188249259Sdim    return true;
189249259Sdim  default:
190249259Sdim    return false;
191249259Sdim  }
192249259Sdim}
193249259Sdim
194249259Sdim/// \brief Determine if F is one of the special known Functions.  If it isn't,
195249259Sdim/// return IC_CallOrUser.
196249259SdimInstructionClass GetFunctionClass(const Function *F);
197249259Sdim
198249259Sdim/// \brief Determine which objc runtime call instruction class V belongs to.
199249259Sdim///
200249259Sdim/// This is similar to GetInstructionClass except that it only detects objc
201249259Sdim/// runtime calls. This allows it to be faster.
202249259Sdim///
203249259Sdimstatic inline InstructionClass GetBasicInstructionClass(const Value *V) {
204249259Sdim  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
205249259Sdim    if (const Function *F = CI->getCalledFunction())
206249259Sdim      return GetFunctionClass(F);
207249259Sdim    // Otherwise, be conservative.
208249259Sdim    return IC_CallOrUser;
209249259Sdim  }
210249259Sdim
211249259Sdim  // Otherwise, be conservative.
212249259Sdim  return isa<InvokeInst>(V) ? IC_CallOrUser : IC_User;
213249259Sdim}
214249259Sdim
215249259Sdim/// \brief Determine what kind of construct V is.
216249259SdimInstructionClass GetInstructionClass(const Value *V);
217249259Sdim
218249259Sdim/// \brief This is a wrapper around getUnderlyingObject which also knows how to
219249259Sdim/// look through objc_retain and objc_autorelease calls, which we know to return
220249259Sdim/// their argument verbatim.
221249259Sdimstatic inline const Value *GetUnderlyingObjCPtr(const Value *V) {
222249259Sdim  for (;;) {
223249259Sdim    V = GetUnderlyingObject(V);
224249259Sdim    if (!IsForwarding(GetBasicInstructionClass(V)))
225249259Sdim      break;
226249259Sdim    V = cast<CallInst>(V)->getArgOperand(0);
227249259Sdim  }
228249259Sdim
229249259Sdim  return V;
230249259Sdim}
231249259Sdim
232249259Sdim/// \brief This is a wrapper around Value::stripPointerCasts which also knows
233249259Sdim/// how to look through objc_retain and objc_autorelease calls, which we know to
234249259Sdim/// return their argument verbatim.
235249259Sdimstatic inline const Value *StripPointerCastsAndObjCCalls(const Value *V) {
236249259Sdim  for (;;) {
237249259Sdim    V = V->stripPointerCasts();
238249259Sdim    if (!IsForwarding(GetBasicInstructionClass(V)))
239249259Sdim      break;
240249259Sdim    V = cast<CallInst>(V)->getArgOperand(0);
241249259Sdim  }
242249259Sdim  return V;
243249259Sdim}
244249259Sdim
245249259Sdim/// \brief This is a wrapper around Value::stripPointerCasts which also knows
246249259Sdim/// how to look through objc_retain and objc_autorelease calls, which we know to
247249259Sdim/// return their argument verbatim.
248249259Sdimstatic inline Value *StripPointerCastsAndObjCCalls(Value *V) {
249249259Sdim  for (;;) {
250249259Sdim    V = V->stripPointerCasts();
251249259Sdim    if (!IsForwarding(GetBasicInstructionClass(V)))
252249259Sdim      break;
253249259Sdim    V = cast<CallInst>(V)->getArgOperand(0);
254249259Sdim  }
255249259Sdim  return V;
256249259Sdim}
257249259Sdim
258249259Sdim/// \brief Assuming the given instruction is one of the special calls such as
259249259Sdim/// objc_retain or objc_release, return the argument value, stripped of no-op
260249259Sdim/// casts and forwarding calls.
261249259Sdimstatic inline Value *GetObjCArg(Value *Inst) {
262249259Sdim  return StripPointerCastsAndObjCCalls(cast<CallInst>(Inst)->getArgOperand(0));
263249259Sdim}
264249259Sdim
265249259Sdimstatic inline bool IsNullOrUndef(const Value *V) {
266249259Sdim  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
267249259Sdim}
268249259Sdim
269249259Sdimstatic inline bool IsNoopInstruction(const Instruction *I) {
270249259Sdim  return isa<BitCastInst>(I) ||
271249259Sdim    (isa<GetElementPtrInst>(I) &&
272249259Sdim     cast<GetElementPtrInst>(I)->hasAllZeroIndices());
273249259Sdim}
274249259Sdim
275249259Sdim
276249259Sdim/// \brief Erase the given instruction.
277249259Sdim///
278249259Sdim/// Many ObjC calls return their argument verbatim,
279249259Sdim/// so if it's such a call and the return value has users, replace them with the
280249259Sdim/// argument value.
281249259Sdim///
282249259Sdimstatic inline void EraseInstruction(Instruction *CI) {
283249259Sdim  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
284249259Sdim
285249259Sdim  bool Unused = CI->use_empty();
286249259Sdim
287249259Sdim  if (!Unused) {
288249259Sdim    // Replace the return value with the argument.
289263508Sdim    assert((IsForwarding(GetBasicInstructionClass(CI)) ||
290263508Sdim            (IsNoopOnNull(GetBasicInstructionClass(CI)) &&
291263508Sdim             isa<ConstantPointerNull>(OldArg))) &&
292249259Sdim           "Can't delete non-forwarding instruction with users!");
293249259Sdim    CI->replaceAllUsesWith(OldArg);
294249259Sdim  }
295249259Sdim
296249259Sdim  CI->eraseFromParent();
297249259Sdim
298249259Sdim  if (Unused)
299249259Sdim    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
300249259Sdim}
301249259Sdim
302249259Sdim/// \brief Test whether the given value is possible a retainable object pointer.
303249259Sdimstatic inline bool IsPotentialRetainableObjPtr(const Value *Op) {
304249259Sdim  // Pointers to static or stack storage are not valid retainable object
305249259Sdim  // pointers.
306249259Sdim  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
307249259Sdim    return false;
308249259Sdim  // Special arguments can not be a valid retainable object pointer.
309249259Sdim  if (const Argument *Arg = dyn_cast<Argument>(Op))
310249259Sdim    if (Arg->hasByValAttr() ||
311249259Sdim        Arg->hasNestAttr() ||
312249259Sdim        Arg->hasStructRetAttr())
313249259Sdim      return false;
314249259Sdim  // Only consider values with pointer types.
315249259Sdim  //
316249259Sdim  // It seemes intuitive to exclude function pointer types as well, since
317249259Sdim  // functions are never retainable object pointers, however clang occasionally
318249259Sdim  // bitcasts retainable object pointers to function-pointer type temporarily.
319249259Sdim  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
320249259Sdim  if (!Ty)
321249259Sdim    return false;
322249259Sdim  // Conservatively assume anything else is a potential retainable object
323249259Sdim  // pointer.
324249259Sdim  return true;
325249259Sdim}
326249259Sdim
327249259Sdimstatic inline bool IsPotentialRetainableObjPtr(const Value *Op,
328249259Sdim                                               AliasAnalysis &AA) {
329249259Sdim  // First make the rudimentary check.
330249259Sdim  if (!IsPotentialRetainableObjPtr(Op))
331249259Sdim    return false;
332249259Sdim
333249259Sdim  // Objects in constant memory are not reference-counted.
334249259Sdim  if (AA.pointsToConstantMemory(Op))
335249259Sdim    return false;
336249259Sdim
337249259Sdim  // Pointers in constant memory are not pointing to reference-counted objects.
338249259Sdim  if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
339249259Sdim    if (AA.pointsToConstantMemory(LI->getPointerOperand()))
340249259Sdim      return false;
341249259Sdim
342249259Sdim  // Otherwise assume the worst.
343249259Sdim  return true;
344249259Sdim}
345249259Sdim
346249259Sdim/// \brief Helper for GetInstructionClass. Determines what kind of construct CS
347249259Sdim/// is.
348249259Sdimstatic inline InstructionClass GetCallSiteClass(ImmutableCallSite CS) {
349249259Sdim  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
350249259Sdim       I != E; ++I)
351249259Sdim    if (IsPotentialRetainableObjPtr(*I))
352249259Sdim      return CS.onlyReadsMemory() ? IC_User : IC_CallOrUser;
353249259Sdim
354249259Sdim  return CS.onlyReadsMemory() ? IC_None : IC_Call;
355249259Sdim}
356249259Sdim
357249259Sdim/// \brief Return true if this value refers to a distinct and identifiable
358249259Sdim/// object.
359249259Sdim///
360249259Sdim/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
361249259Sdim/// special knowledge of ObjC conventions.
362249259Sdimstatic inline bool IsObjCIdentifiedObject(const Value *V) {
363249259Sdim  // Assume that call results and arguments have their own "provenance".
364249259Sdim  // Constants (including GlobalVariables) and Allocas are never
365249259Sdim  // reference-counted.
366249259Sdim  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
367249259Sdim      isa<Argument>(V) || isa<Constant>(V) ||
368249259Sdim      isa<AllocaInst>(V))
369249259Sdim    return true;
370249259Sdim
371249259Sdim  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
372249259Sdim    const Value *Pointer =
373249259Sdim      StripPointerCastsAndObjCCalls(LI->getPointerOperand());
374249259Sdim    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
375249259Sdim      // A constant pointer can't be pointing to an object on the heap. It may
376249259Sdim      // be reference-counted, but it won't be deleted.
377249259Sdim      if (GV->isConstant())
378249259Sdim        return true;
379249259Sdim      StringRef Name = GV->getName();
380249259Sdim      // These special variables are known to hold values which are not
381249259Sdim      // reference-counted pointers.
382249259Sdim      if (Name.startswith("\01L_OBJC_SELECTOR_REFERENCES_") ||
383249259Sdim          Name.startswith("\01L_OBJC_CLASSLIST_REFERENCES_") ||
384249259Sdim          Name.startswith("\01L_OBJC_CLASSLIST_SUP_REFS_$_") ||
385249259Sdim          Name.startswith("\01L_OBJC_METH_VAR_NAME_") ||
386249259Sdim          Name.startswith("\01l_objc_msgSend_fixup_"))
387249259Sdim        return true;
388249259Sdim    }
389249259Sdim  }
390249259Sdim
391249259Sdim  return false;
392249259Sdim}
393249259Sdim
394249259Sdim} // end namespace objcarc
395249259Sdim} // end namespace llvm
396249259Sdim
397249259Sdim#endif // LLVM_TRANSFORMS_SCALAR_OBJCARC_H
398