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