LLVM API Documentation
00001 //===- ObjCARCAPElim.cpp - ObjC ARC Optimization --------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// \file 00010 /// 00011 /// This file defines ObjC ARC optimizations. ARC stands for Automatic 00012 /// Reference Counting and is a system for managing reference counts for objects 00013 /// in Objective C. 00014 /// 00015 /// This specific file implements optimizations which remove extraneous 00016 /// autorelease pools. 00017 /// 00018 /// WARNING: This file knows about certain library functions. It recognizes them 00019 /// by name, and hardwires knowledge of their semantics. 00020 /// 00021 /// WARNING: This file knows about how certain Objective-C library functions are 00022 /// used. Naive LLVM IR transformations which would otherwise be 00023 /// behavior-preserving may break these assumptions. 00024 /// 00025 //===----------------------------------------------------------------------===// 00026 00027 #include "ObjCARC.h" 00028 #include "llvm/ADT/STLExtras.h" 00029 #include "llvm/IR/Constants.h" 00030 #include "llvm/Support/Debug.h" 00031 #include "llvm/Support/raw_ostream.h" 00032 00033 using namespace llvm; 00034 using namespace llvm::objcarc; 00035 00036 #define DEBUG_TYPE "objc-arc-ap-elim" 00037 00038 namespace { 00039 /// \brief Autorelease pool elimination. 00040 class ObjCARCAPElim : public ModulePass { 00041 void getAnalysisUsage(AnalysisUsage &AU) const override; 00042 bool runOnModule(Module &M) override; 00043 00044 static bool MayAutorelease(ImmutableCallSite CS, unsigned Depth = 0); 00045 static bool OptimizeBB(BasicBlock *BB); 00046 00047 public: 00048 static char ID; 00049 ObjCARCAPElim() : ModulePass(ID) { 00050 initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry()); 00051 } 00052 }; 00053 } 00054 00055 char ObjCARCAPElim::ID = 0; 00056 INITIALIZE_PASS(ObjCARCAPElim, 00057 "objc-arc-apelim", 00058 "ObjC ARC autorelease pool elimination", 00059 false, false) 00060 00061 Pass *llvm::createObjCARCAPElimPass() { 00062 return new ObjCARCAPElim(); 00063 } 00064 00065 void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const { 00066 AU.setPreservesCFG(); 00067 } 00068 00069 /// Interprocedurally determine if calls made by the given call site can 00070 /// possibly produce autoreleases. 00071 bool ObjCARCAPElim::MayAutorelease(ImmutableCallSite CS, unsigned Depth) { 00072 if (const Function *Callee = CS.getCalledFunction()) { 00073 if (Callee->isDeclaration() || Callee->mayBeOverridden()) 00074 return true; 00075 for (Function::const_iterator I = Callee->begin(), E = Callee->end(); 00076 I != E; ++I) { 00077 const BasicBlock *BB = I; 00078 for (BasicBlock::const_iterator J = BB->begin(), F = BB->end(); 00079 J != F; ++J) 00080 if (ImmutableCallSite JCS = ImmutableCallSite(J)) 00081 // This recursion depth limit is arbitrary. It's just great 00082 // enough to cover known interesting testcases. 00083 if (Depth < 3 && 00084 !JCS.onlyReadsMemory() && 00085 MayAutorelease(JCS, Depth + 1)) 00086 return true; 00087 } 00088 return false; 00089 } 00090 00091 return true; 00092 } 00093 00094 bool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) { 00095 bool Changed = false; 00096 00097 Instruction *Push = nullptr; 00098 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { 00099 Instruction *Inst = I++; 00100 switch (GetBasicInstructionClass(Inst)) { 00101 case IC_AutoreleasepoolPush: 00102 Push = Inst; 00103 break; 00104 case IC_AutoreleasepoolPop: 00105 // If this pop matches a push and nothing in between can autorelease, 00106 // zap the pair. 00107 if (Push && cast<CallInst>(Inst)->getArgOperand(0) == Push) { 00108 Changed = true; 00109 DEBUG(dbgs() << "ObjCARCAPElim::OptimizeBB: Zapping push pop " 00110 "autorelease pair:\n" 00111 " Pop: " << *Inst << "\n" 00112 << " Push: " << *Push << "\n"); 00113 Inst->eraseFromParent(); 00114 Push->eraseFromParent(); 00115 } 00116 Push = nullptr; 00117 break; 00118 case IC_CallOrUser: 00119 if (MayAutorelease(ImmutableCallSite(Inst))) 00120 Push = nullptr; 00121 break; 00122 default: 00123 break; 00124 } 00125 } 00126 00127 return Changed; 00128 } 00129 00130 bool ObjCARCAPElim::runOnModule(Module &M) { 00131 if (!EnableARCOpts) 00132 return false; 00133 00134 // If nothing in the Module uses ARC, don't do anything. 00135 if (!ModuleHasARC(M)) 00136 return false; 00137 00138 // Find the llvm.global_ctors variable, as the first step in 00139 // identifying the global constructors. In theory, unnecessary autorelease 00140 // pools could occur anywhere, but in practice it's pretty rare. Global 00141 // ctors are a place where autorelease pools get inserted automatically, 00142 // so it's pretty common for them to be unnecessary, and it's pretty 00143 // profitable to eliminate them. 00144 GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); 00145 if (!GV) 00146 return false; 00147 00148 assert(GV->hasDefinitiveInitializer() && 00149 "llvm.global_ctors is uncooperative!"); 00150 00151 bool Changed = false; 00152 00153 // Dig the constructor functions out of GV's initializer. 00154 ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); 00155 for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end(); 00156 OI != OE; ++OI) { 00157 Value *Op = *OI; 00158 // llvm.global_ctors is an array of three-field structs where the second 00159 // members are constructor functions. 00160 Function *F = dyn_cast<Function>(cast<ConstantStruct>(Op)->getOperand(1)); 00161 // If the user used a constructor function with the wrong signature and 00162 // it got bitcasted or whatever, look the other way. 00163 if (!F) 00164 continue; 00165 // Only look at function definitions. 00166 if (F->isDeclaration()) 00167 continue; 00168 // Only look at functions with one basic block. 00169 if (std::next(F->begin()) != F->end()) 00170 continue; 00171 // Ok, a single-block constructor function definition. Try to optimize it. 00172 Changed |= OptimizeBB(F->begin()); 00173 } 00174 00175 return Changed; 00176 }