1 //===- ObjCARCUtil.cpp - ObjC ARC Optimization --------*- mode: 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 several utility functions used by various ARC 11 /// optimizations which are IMHO too big to be in a header file. 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 #include "ObjCARC.h" 23 #include "llvm/IR/Intrinsics.h" 24 25 using namespace llvm; 26 using namespace llvm::objcarc; 27 28 raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS, 29 const InstructionClass Class) { 30 switch (Class) { 31 case IC_Retain: 32 return OS << "IC_Retain"; 33 case IC_RetainRV: 34 return OS << "IC_RetainRV"; 35 case IC_RetainBlock: 36 return OS << "IC_RetainBlock"; 37 case IC_Release: 38 return OS << "IC_Release"; 39 case IC_Autorelease: 40 return OS << "IC_Autorelease"; 41 case IC_AutoreleaseRV: 42 return OS << "IC_AutoreleaseRV"; 43 case IC_AutoreleasepoolPush: 44 return OS << "IC_AutoreleasepoolPush"; 45 case IC_AutoreleasepoolPop: 46 return OS << "IC_AutoreleasepoolPop"; 47 case IC_NoopCast: 48 return OS << "IC_NoopCast"; 49 case IC_FusedRetainAutorelease: 50 return OS << "IC_FusedRetainAutorelease"; 51 case IC_FusedRetainAutoreleaseRV: 52 return OS << "IC_FusedRetainAutoreleaseRV"; 53 case IC_LoadWeakRetained: 54 return OS << "IC_LoadWeakRetained"; 55 case IC_StoreWeak: 56 return OS << "IC_StoreWeak"; 57 case IC_InitWeak: 58 return OS << "IC_InitWeak"; 59 case IC_LoadWeak: 60 return OS << "IC_LoadWeak"; 61 case IC_MoveWeak: 62 return OS << "IC_MoveWeak"; 63 case IC_CopyWeak: 64 return OS << "IC_CopyWeak"; 65 case IC_DestroyWeak: 66 return OS << "IC_DestroyWeak"; 67 case IC_StoreStrong: 68 return OS << "IC_StoreStrong"; 69 case IC_CallOrUser: 70 return OS << "IC_CallOrUser"; 71 case IC_Call: 72 return OS << "IC_Call"; 73 case IC_User: 74 return OS << "IC_User"; 75 case IC_None: 76 return OS << "IC_None"; 77 } 78 llvm_unreachable("Unknown instruction class!"); 79 } 80 81 InstructionClass llvm::objcarc::GetFunctionClass(const Function *F) { 82 Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); 83 84 // No arguments. 85 if (AI == AE) 86 return StringSwitch<InstructionClass>(F->getName()) 87 .Case("objc_autoreleasePoolPush", IC_AutoreleasepoolPush) 88 .Default(IC_CallOrUser); 89 90 // One argument. 91 const Argument *A0 = AI++; 92 if (AI == AE) 93 // Argument is a pointer. 94 if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) { 95 Type *ETy = PTy->getElementType(); 96 // Argument is i8*. 97 if (ETy->isIntegerTy(8)) 98 return StringSwitch<InstructionClass>(F->getName()) 99 .Case("objc_retain", IC_Retain) 100 .Case("objc_retainAutoreleasedReturnValue", IC_RetainRV) 101 .Case("objc_retainBlock", IC_RetainBlock) 102 .Case("objc_release", IC_Release) 103 .Case("objc_autorelease", IC_Autorelease) 104 .Case("objc_autoreleaseReturnValue", IC_AutoreleaseRV) 105 .Case("objc_autoreleasePoolPop", IC_AutoreleasepoolPop) 106 .Case("objc_retainedObject", IC_NoopCast) 107 .Case("objc_unretainedObject", IC_NoopCast) 108 .Case("objc_unretainedPointer", IC_NoopCast) 109 .Case("objc_retain_autorelease", IC_FusedRetainAutorelease) 110 .Case("objc_retainAutorelease", IC_FusedRetainAutorelease) 111 .Case("objc_retainAutoreleaseReturnValue",IC_FusedRetainAutoreleaseRV) 112 .Default(IC_CallOrUser); 113 114 // Argument is i8** 115 if (PointerType *Pte = dyn_cast<PointerType>(ETy)) 116 if (Pte->getElementType()->isIntegerTy(8)) 117 return StringSwitch<InstructionClass>(F->getName()) 118 .Case("objc_loadWeakRetained", IC_LoadWeakRetained) 119 .Case("objc_loadWeak", IC_LoadWeak) 120 .Case("objc_destroyWeak", IC_DestroyWeak) 121 .Default(IC_CallOrUser); 122 } 123 124 // Two arguments, first is i8**. 125 const Argument *A1 = AI++; 126 if (AI == AE) 127 if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) 128 if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType())) 129 if (Pte->getElementType()->isIntegerTy(8)) 130 if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) { 131 Type *ETy1 = PTy1->getElementType(); 132 // Second argument is i8* 133 if (ETy1->isIntegerTy(8)) 134 return StringSwitch<InstructionClass>(F->getName()) 135 .Case("objc_storeWeak", IC_StoreWeak) 136 .Case("objc_initWeak", IC_InitWeak) 137 .Case("objc_storeStrong", IC_StoreStrong) 138 .Default(IC_CallOrUser); 139 // Second argument is i8**. 140 if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1)) 141 if (Pte1->getElementType()->isIntegerTy(8)) 142 return StringSwitch<InstructionClass>(F->getName()) 143 .Case("objc_moveWeak", IC_MoveWeak) 144 .Case("objc_copyWeak", IC_CopyWeak) 145 .Default(IC_CallOrUser); 146 } 147 148 // Anything else. 149 return IC_CallOrUser; 150 } 151 152 /// \brief Determine what kind of construct V is. 153 InstructionClass 154 llvm::objcarc::GetInstructionClass(const Value *V) { 155 if (const Instruction *I = dyn_cast<Instruction>(V)) { 156 // Any instruction other than bitcast and gep with a pointer operand have a 157 // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer 158 // to a subsequent use, rather than using it themselves, in this sense. 159 // As a short cut, several other opcodes are known to have no pointer 160 // operands of interest. And ret is never followed by a release, so it's 161 // not interesting to examine. 162 switch (I->getOpcode()) { 163 case Instruction::Call: { 164 const CallInst *CI = cast<CallInst>(I); 165 // Check for calls to special functions. 166 if (const Function *F = CI->getCalledFunction()) { 167 InstructionClass Class = GetFunctionClass(F); 168 if (Class != IC_CallOrUser) 169 return Class; 170 171 // None of the intrinsic functions do objc_release. For intrinsics, the 172 // only question is whether or not they may be users. 173 switch (F->getIntrinsicID()) { 174 case Intrinsic::returnaddress: case Intrinsic::frameaddress: 175 case Intrinsic::stacksave: case Intrinsic::stackrestore: 176 case Intrinsic::vastart: case Intrinsic::vacopy: case Intrinsic::vaend: 177 case Intrinsic::objectsize: case Intrinsic::prefetch: 178 case Intrinsic::stackprotector: 179 case Intrinsic::eh_return_i32: case Intrinsic::eh_return_i64: 180 case Intrinsic::eh_typeid_for: case Intrinsic::eh_dwarf_cfa: 181 case Intrinsic::eh_sjlj_lsda: case Intrinsic::eh_sjlj_functioncontext: 182 case Intrinsic::init_trampoline: case Intrinsic::adjust_trampoline: 183 case Intrinsic::lifetime_start: case Intrinsic::lifetime_end: 184 case Intrinsic::invariant_start: case Intrinsic::invariant_end: 185 // Don't let dbg info affect our results. 186 case Intrinsic::dbg_declare: case Intrinsic::dbg_value: 187 // Short cut: Some intrinsics obviously don't use ObjC pointers. 188 return IC_None; 189 default: 190 break; 191 } 192 } 193 return GetCallSiteClass(CI); 194 } 195 case Instruction::Invoke: 196 return GetCallSiteClass(cast<InvokeInst>(I)); 197 case Instruction::BitCast: 198 case Instruction::GetElementPtr: 199 case Instruction::Select: case Instruction::PHI: 200 case Instruction::Ret: case Instruction::Br: 201 case Instruction::Switch: case Instruction::IndirectBr: 202 case Instruction::Alloca: case Instruction::VAArg: 203 case Instruction::Add: case Instruction::FAdd: 204 case Instruction::Sub: case Instruction::FSub: 205 case Instruction::Mul: case Instruction::FMul: 206 case Instruction::SDiv: case Instruction::UDiv: case Instruction::FDiv: 207 case Instruction::SRem: case Instruction::URem: case Instruction::FRem: 208 case Instruction::Shl: case Instruction::LShr: case Instruction::AShr: 209 case Instruction::And: case Instruction::Or: case Instruction::Xor: 210 case Instruction::SExt: case Instruction::ZExt: case Instruction::Trunc: 211 case Instruction::IntToPtr: case Instruction::FCmp: 212 case Instruction::FPTrunc: case Instruction::FPExt: 213 case Instruction::FPToUI: case Instruction::FPToSI: 214 case Instruction::UIToFP: case Instruction::SIToFP: 215 case Instruction::InsertElement: case Instruction::ExtractElement: 216 case Instruction::ShuffleVector: 217 case Instruction::ExtractValue: 218 break; 219 case Instruction::ICmp: 220 // Comparing a pointer with null, or any other constant, isn't an 221 // interesting use, because we don't care what the pointer points to, or 222 // about the values of any other dynamic reference-counted pointers. 223 if (IsPotentialRetainableObjPtr(I->getOperand(1))) 224 return IC_User; 225 break; 226 default: 227 // For anything else, check all the operands. 228 // Note that this includes both operands of a Store: while the first 229 // operand isn't actually being dereferenced, it is being stored to 230 // memory where we can no longer track who might read it and dereference 231 // it, so we have to consider it potentially used. 232 for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end(); 233 OI != OE; ++OI) 234 if (IsPotentialRetainableObjPtr(*OI)) 235 return IC_User; 236 } 237 } 238 239 // Otherwise, it's totally inert for ARC purposes. 240 return IC_None; 241 } 242