1 //===- DependencyAnalysis.cpp - ObjC ARC Optimization ---------------------===// 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 /// 11 /// This file defines special dependency analysis routines used in Objective C 12 /// ARC Optimizations. 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 #include "DependencyAnalysis.h" 24 #include "ObjCARC.h" 25 #include "ProvenanceAnalysis.h" 26 #include "llvm/IR/CFG.h" 27 28 using namespace llvm; 29 using namespace llvm::objcarc; 30 31 #define DEBUG_TYPE "objc-arc-dependency" 32 33 /// Test whether the given instruction can result in a reference count 34 /// modification (positive or negative) for the pointer's object. 35 bool llvm::objcarc::CanAlterRefCount(const Instruction *Inst, const Value *Ptr, 36 ProvenanceAnalysis &PA, 37 ARCInstKind Class) { 38 switch (Class) { 39 case ARCInstKind::Autorelease: 40 case ARCInstKind::AutoreleaseRV: 41 case ARCInstKind::IntrinsicUser: 42 case ARCInstKind::User: 43 // These operations never directly modify a reference count. 44 return false; 45 default: break; 46 } 47 48 const auto *Call = cast<CallBase>(Inst); 49 50 // See if AliasAnalysis can help us with the call. 51 FunctionModRefBehavior MRB = PA.getAA()->getModRefBehavior(Call); 52 if (AliasAnalysis::onlyReadsMemory(MRB)) 53 return false; 54 if (AliasAnalysis::onlyAccessesArgPointees(MRB)) { 55 const DataLayout &DL = Inst->getModule()->getDataLayout(); 56 for (const Value *Op : Call->args()) { 57 if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && 58 PA.related(Ptr, Op, DL)) 59 return true; 60 } 61 return false; 62 } 63 64 // Assume the worst. 65 return true; 66 } 67 68 bool llvm::objcarc::CanDecrementRefCount(const Instruction *Inst, 69 const Value *Ptr, 70 ProvenanceAnalysis &PA, 71 ARCInstKind Class) { 72 // First perform a quick check if Class can not touch ref counts. 73 if (!CanDecrementRefCount(Class)) 74 return false; 75 76 // Otherwise, just use CanAlterRefCount for now. 77 return CanAlterRefCount(Inst, Ptr, PA, Class); 78 } 79 80 /// Test whether the given instruction can "use" the given pointer's object in a 81 /// way that requires the reference count to be positive. 82 bool llvm::objcarc::CanUse(const Instruction *Inst, const Value *Ptr, 83 ProvenanceAnalysis &PA, ARCInstKind Class) { 84 // ARCInstKind::Call operations (as opposed to 85 // ARCInstKind::CallOrUser) never "use" objc pointers. 86 if (Class == ARCInstKind::Call) 87 return false; 88 89 const DataLayout &DL = Inst->getModule()->getDataLayout(); 90 91 // Consider various instructions which may have pointer arguments which are 92 // not "uses". 93 if (const ICmpInst *ICI = dyn_cast<ICmpInst>(Inst)) { 94 // Comparing a pointer with null, or any other constant, isn't really a use, 95 // because we don't care what the pointer points to, or about the values 96 // of any other dynamic reference-counted pointers. 97 if (!IsPotentialRetainableObjPtr(ICI->getOperand(1), *PA.getAA())) 98 return false; 99 } else if (auto CS = ImmutableCallSite(Inst)) { 100 // For calls, just check the arguments (and not the callee operand). 101 for (ImmutableCallSite::arg_iterator OI = CS.arg_begin(), 102 OE = CS.arg_end(); OI != OE; ++OI) { 103 const Value *Op = *OI; 104 if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && 105 PA.related(Ptr, Op, DL)) 106 return true; 107 } 108 return false; 109 } else if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) { 110 // Special-case stores, because we don't care about the stored value, just 111 // the store address. 112 const Value *Op = GetUnderlyingObjCPtr(SI->getPointerOperand(), DL); 113 // If we can't tell what the underlying object was, assume there is a 114 // dependence. 115 return IsPotentialRetainableObjPtr(Op, *PA.getAA()) && 116 PA.related(Op, Ptr, DL); 117 } 118 119 // Check each operand for a match. 120 for (User::const_op_iterator OI = Inst->op_begin(), OE = Inst->op_end(); 121 OI != OE; ++OI) { 122 const Value *Op = *OI; 123 if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op, DL)) 124 return true; 125 } 126 return false; 127 } 128 129 /// Test if there can be dependencies on Inst through Arg. This function only 130 /// tests dependencies relevant for removing pairs of calls. 131 bool 132 llvm::objcarc::Depends(DependenceKind Flavor, Instruction *Inst, 133 const Value *Arg, ProvenanceAnalysis &PA) { 134 // If we've reached the definition of Arg, stop. 135 if (Inst == Arg) 136 return true; 137 138 switch (Flavor) { 139 case NeedsPositiveRetainCount: { 140 ARCInstKind Class = GetARCInstKind(Inst); 141 switch (Class) { 142 case ARCInstKind::AutoreleasepoolPop: 143 case ARCInstKind::AutoreleasepoolPush: 144 case ARCInstKind::None: 145 return false; 146 default: 147 return CanUse(Inst, Arg, PA, Class); 148 } 149 } 150 151 case AutoreleasePoolBoundary: { 152 ARCInstKind Class = GetARCInstKind(Inst); 153 switch (Class) { 154 case ARCInstKind::AutoreleasepoolPop: 155 case ARCInstKind::AutoreleasepoolPush: 156 // These mark the end and begin of an autorelease pool scope. 157 return true; 158 default: 159 // Nothing else does this. 160 return false; 161 } 162 } 163 164 case CanChangeRetainCount: { 165 ARCInstKind Class = GetARCInstKind(Inst); 166 switch (Class) { 167 case ARCInstKind::AutoreleasepoolPop: 168 // Conservatively assume this can decrement any count. 169 return true; 170 case ARCInstKind::AutoreleasepoolPush: 171 case ARCInstKind::None: 172 return false; 173 default: 174 return CanAlterRefCount(Inst, Arg, PA, Class); 175 } 176 } 177 178 case RetainAutoreleaseDep: 179 switch (GetBasicARCInstKind(Inst)) { 180 case ARCInstKind::AutoreleasepoolPop: 181 case ARCInstKind::AutoreleasepoolPush: 182 // Don't merge an objc_autorelease with an objc_retain inside a different 183 // autoreleasepool scope. 184 return true; 185 case ARCInstKind::Retain: 186 case ARCInstKind::RetainRV: 187 // Check for a retain of the same pointer for merging. 188 return GetArgRCIdentityRoot(Inst) == Arg; 189 default: 190 // Nothing else matters for objc_retainAutorelease formation. 191 return false; 192 } 193 194 case RetainAutoreleaseRVDep: { 195 ARCInstKind Class = GetBasicARCInstKind(Inst); 196 switch (Class) { 197 case ARCInstKind::Retain: 198 case ARCInstKind::RetainRV: 199 // Check for a retain of the same pointer for merging. 200 return GetArgRCIdentityRoot(Inst) == Arg; 201 default: 202 // Anything that can autorelease interrupts 203 // retainAutoreleaseReturnValue formation. 204 return CanInterruptRV(Class); 205 } 206 } 207 208 case RetainRVDep: 209 return CanInterruptRV(GetBasicARCInstKind(Inst)); 210 } 211 212 llvm_unreachable("Invalid dependence flavor"); 213 } 214 215 /// Walk up the CFG from StartPos (which is in StartBB) and find local and 216 /// non-local dependencies on Arg. 217 /// 218 /// TODO: Cache results? 219 void 220 llvm::objcarc::FindDependencies(DependenceKind Flavor, 221 const Value *Arg, 222 BasicBlock *StartBB, Instruction *StartInst, 223 SmallPtrSetImpl<Instruction *> &DependingInsts, 224 SmallPtrSetImpl<const BasicBlock *> &Visited, 225 ProvenanceAnalysis &PA) { 226 BasicBlock::iterator StartPos = StartInst->getIterator(); 227 228 SmallVector<std::pair<BasicBlock *, BasicBlock::iterator>, 4> Worklist; 229 Worklist.push_back(std::make_pair(StartBB, StartPos)); 230 do { 231 std::pair<BasicBlock *, BasicBlock::iterator> Pair = 232 Worklist.pop_back_val(); 233 BasicBlock *LocalStartBB = Pair.first; 234 BasicBlock::iterator LocalStartPos = Pair.second; 235 BasicBlock::iterator StartBBBegin = LocalStartBB->begin(); 236 for (;;) { 237 if (LocalStartPos == StartBBBegin) { 238 pred_iterator PI(LocalStartBB), PE(LocalStartBB, false); 239 if (PI == PE) 240 // If we've reached the function entry, produce a null dependence. 241 DependingInsts.insert(nullptr); 242 else 243 // Add the predecessors to the worklist. 244 do { 245 BasicBlock *PredBB = *PI; 246 if (Visited.insert(PredBB).second) 247 Worklist.push_back(std::make_pair(PredBB, PredBB->end())); 248 } while (++PI != PE); 249 break; 250 } 251 252 Instruction *Inst = &*--LocalStartPos; 253 if (Depends(Flavor, Inst, Arg, PA)) { 254 DependingInsts.insert(Inst); 255 break; 256 } 257 } 258 } while (!Worklist.empty()); 259 260 // Determine whether the original StartBB post-dominates all of the blocks we 261 // visited. If not, insert a sentinal indicating that most optimizations are 262 // not safe. 263 for (const BasicBlock *BB : Visited) { 264 if (BB == StartBB) 265 continue; 266 for (const BasicBlock *Succ : successors(BB)) 267 if (Succ != StartBB && !Visited.count(Succ)) { 268 DependingInsts.insert(reinterpret_cast<Instruction *>(-1)); 269 return; 270 } 271 } 272 } 273