17fd324a31fbfd237f43d38d3a780a19fbf909ba3Michael Gottesman//===- ObjCARCAPElim.cpp - ObjC ARC Optimization --------------------------===// 23c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman// 33c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman// The LLVM Compiler Infrastructure 43c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman// 53c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman// This file is distributed under the University of Illinois Open Source 63c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman// License. See LICENSE.TXT for details. 73c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman// 83c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman//===----------------------------------------------------------------------===// 93c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// \file 107fd324a31fbfd237f43d38d3a780a19fbf909ba3Michael Gottesman/// 113c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// This file defines ObjC ARC optimizations. ARC stands for Automatic 123c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// Reference Counting and is a system for managing reference counts for objects 133c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// in Objective C. 143c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// 157fd324a31fbfd237f43d38d3a780a19fbf909ba3Michael Gottesman/// This specific file implements optimizations which remove extraneous 167fd324a31fbfd237f43d38d3a780a19fbf909ba3Michael Gottesman/// autorelease pools. 173c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// 183c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them 193c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// by name, and hardwires knowledge of their semantics. 203c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// 213c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are 223c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// used. Naive LLVM IR transformations which would otherwise be 233c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// behavior-preserving may break these assumptions. 243c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// 253c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman//===----------------------------------------------------------------------===// 263c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 273c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "ObjCARC.h" 283c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "llvm/ADT/STLExtras.h" 293c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "llvm/IR/Constants.h" 309ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman#include "llvm/Support/Debug.h" 3109840daeefc1aa8760c535ded6a37eb4f8cd4eaaTimur Iskhodzhanov#include "llvm/Support/raw_ostream.h" 323c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 333c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanusing namespace llvm; 343c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanusing namespace llvm::objcarc; 353c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "objc-arc-ap-elim" 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 383c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmannamespace { 393c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman /// \brief Autorelease pool elimination. 403c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman class ObjCARCAPElim : public ModulePass { 4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override; 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnModule(Module &M) override; 433c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 443c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman static bool MayAutorelease(ImmutableCallSite CS, unsigned Depth = 0); 453c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman static bool OptimizeBB(BasicBlock *BB); 463c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 473c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman public: 483c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman static char ID; 493c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman ObjCARCAPElim() : ModulePass(ID) { 503c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry()); 513c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 523c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman }; 533c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman} 543c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 553c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanchar ObjCARCAPElim::ID = 0; 563c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael GottesmanINITIALIZE_PASS(ObjCARCAPElim, 573c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman "objc-arc-apelim", 583c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman "ObjC ARC autorelease pool elimination", 593c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman false, false) 603c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 613c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael GottesmanPass *llvm::createObjCARCAPElimPass() { 623c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return new ObjCARCAPElim(); 633c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman} 643c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 653c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanvoid ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const { 663c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman AU.setPreservesCFG(); 673c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman} 683c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 693c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// Interprocedurally determine if calls made by the given call site can 703c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// possibly produce autoreleases. 713c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanbool ObjCARCAPElim::MayAutorelease(ImmutableCallSite CS, unsigned Depth) { 723c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (const Function *Callee = CS.getCalledFunction()) { 733c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (Callee->isDeclaration() || Callee->mayBeOverridden()) 743c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return true; 753c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman for (Function::const_iterator I = Callee->begin(), E = Callee->end(); 763c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman I != E; ++I) { 773c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman const BasicBlock *BB = I; 783c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman for (BasicBlock::const_iterator J = BB->begin(), F = BB->end(); 793c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman J != F; ++J) 803c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (ImmutableCallSite JCS = ImmutableCallSite(J)) 813c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // This recursion depth limit is arbitrary. It's just great 823c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // enough to cover known interesting testcases. 833c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (Depth < 3 && 843c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman !JCS.onlyReadsMemory() && 853c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman MayAutorelease(JCS, Depth + 1)) 863c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return true; 873c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 883c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return false; 893c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 903c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 913c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return true; 923c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman} 933c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 943c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanbool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) { 953c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman bool Changed = false; 963c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Instruction *Push = nullptr; 983c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) { 993c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Instruction *Inst = I++; 1003c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman switch (GetBasicInstructionClass(Inst)) { 1013c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman case IC_AutoreleasepoolPush: 1023c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Push = Inst; 1033c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman break; 1043c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman case IC_AutoreleasepoolPop: 1053c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // If this pop matches a push and nothing in between can autorelease, 1063c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // zap the pair. 1073c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (Push && cast<CallInst>(Inst)->getArgOperand(0) == Push) { 1083c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Changed = true; 1093c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman DEBUG(dbgs() << "ObjCARCAPElim::OptimizeBB: Zapping push pop " 1103c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman "autorelease pair:\n" 1113c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman " Pop: " << *Inst << "\n" 1123c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman << " Push: " << *Push << "\n"); 1133c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Inst->eraseFromParent(); 1143c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Push->eraseFromParent(); 1153c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Push = nullptr; 1173c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman break; 1183c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman case IC_CallOrUser: 1193c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (MayAutorelease(ImmutableCallSite(Inst))) 120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Push = nullptr; 1213c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman break; 1223c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman default: 1233c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman break; 1243c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 1253c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 1263c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1273c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return Changed; 1283c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman} 1293c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1303c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanbool ObjCARCAPElim::runOnModule(Module &M) { 1313c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (!EnableARCOpts) 1323c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return false; 1333c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1343c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // If nothing in the Module uses ARC, don't do anything. 1353c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (!ModuleHasARC(M)) 1363c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return false; 1373c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1383c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // Find the llvm.global_ctors variable, as the first step in 1393c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // identifying the global constructors. In theory, unnecessary autorelease 1403c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // pools could occur anywhere, but in practice it's pretty rare. Global 1413c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // ctors are a place where autorelease pools get inserted automatically, 1423c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // so it's pretty common for them to be unnecessary, and it's pretty 1433c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // profitable to eliminate them. 1443c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors"); 1453c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (!GV) 1463c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return false; 1473c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1483c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman assert(GV->hasDefinitiveInitializer() && 1493c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman "llvm.global_ctors is uncooperative!"); 1503c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1513c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman bool Changed = false; 1523c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1533c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // Dig the constructor functions out of GV's initializer. 1543c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); 1553c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end(); 1563c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman OI != OE; ++OI) { 1573c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Value *Op = *OI; 158dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // llvm.global_ctors is an array of three-field structs where the second 159dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // members are constructor functions. 1603c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Function *F = dyn_cast<Function>(cast<ConstantStruct>(Op)->getOperand(1)); 1613c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // If the user used a constructor function with the wrong signature and 1623c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // it got bitcasted or whatever, look the other way. 1633c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (!F) 1643c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman continue; 1653c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // Only look at function definitions. 1663c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman if (F->isDeclaration()) 1673c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman continue; 1683c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // Only look at functions with one basic block. 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (std::next(F->begin()) != F->end()) 1703c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman continue; 1713c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman // Ok, a single-block constructor function definition. Try to optimize it. 1723c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman Changed |= OptimizeBB(F->begin()); 1733c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman } 1743c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman 1753c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman return Changed; 1763c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman} 177