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#define DEBUG_TYPE "objc-arc-ap-elim"
283c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "ObjCARC.h"
293c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "llvm/ADT/STLExtras.h"
303c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "llvm/IR/Constants.h"
319ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman#include "llvm/Support/Debug.h"
3209840daeefc1aa8760c535ded6a37eb4f8cd4eaaTimur Iskhodzhanov#include "llvm/Support/raw_ostream.h"
333c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
343c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanusing namespace llvm;
353c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanusing namespace llvm::objcarc;
363c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
373c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmannamespace {
383c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  /// \brief Autorelease pool elimination.
393c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  class ObjCARCAPElim : public ModulePass {
403c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
413c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    virtual bool runOnModule(Module &M);
423c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
433c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    static bool MayAutorelease(ImmutableCallSite CS, unsigned Depth = 0);
443c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    static bool OptimizeBB(BasicBlock *BB);
453c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
463c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  public:
473c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    static char ID;
483c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    ObjCARCAPElim() : ModulePass(ID) {
493c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry());
503c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    }
513c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  };
523c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman}
533c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
543c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanchar ObjCARCAPElim::ID = 0;
553c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael GottesmanINITIALIZE_PASS(ObjCARCAPElim,
563c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman                "objc-arc-apelim",
573c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman                "ObjC ARC autorelease pool elimination",
583c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman                false, false)
593c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
603c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael GottesmanPass *llvm::createObjCARCAPElimPass() {
613c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  return new ObjCARCAPElim();
623c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman}
633c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
643c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanvoid ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const {
653c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  AU.setPreservesCFG();
663c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman}
673c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
683c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// Interprocedurally determine if calls made by the given call site can
693c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman/// possibly produce autoreleases.
703c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanbool ObjCARCAPElim::MayAutorelease(ImmutableCallSite CS, unsigned Depth) {
713c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  if (const Function *Callee = CS.getCalledFunction()) {
723c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    if (Callee->isDeclaration() || Callee->mayBeOverridden())
733c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      return true;
743c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    for (Function::const_iterator I = Callee->begin(), E = Callee->end();
753c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman         I != E; ++I) {
763c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      const BasicBlock *BB = I;
773c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      for (BasicBlock::const_iterator J = BB->begin(), F = BB->end();
783c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman           J != F; ++J)
793c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman        if (ImmutableCallSite JCS = ImmutableCallSite(J))
803c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman          // This recursion depth limit is arbitrary. It's just great
813c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman          // enough to cover known interesting testcases.
823c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman          if (Depth < 3 &&
833c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman              !JCS.onlyReadsMemory() &&
843c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman              MayAutorelease(JCS, Depth + 1))
853c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman            return true;
863c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    }
873c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    return false;
883c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  }
893c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
903c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  return true;
913c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman}
923c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
933c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanbool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) {
943c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  bool Changed = false;
953c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
963c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  Instruction *Push = 0;
973c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
983c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    Instruction *Inst = I++;
993c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    switch (GetBasicInstructionClass(Inst)) {
1003c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    case IC_AutoreleasepoolPush:
1013c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      Push = Inst;
1023c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      break;
1033c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    case IC_AutoreleasepoolPop:
1043c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      // If this pop matches a push and nothing in between can autorelease,
1053c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      // zap the pair.
1063c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      if (Push && cast<CallInst>(Inst)->getArgOperand(0) == Push) {
1073c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman        Changed = true;
1083c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman        DEBUG(dbgs() << "ObjCARCAPElim::OptimizeBB: Zapping push pop "
1093c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman                        "autorelease pair:\n"
1103c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman                        "                           Pop: " << *Inst << "\n"
1113c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman                     << "                           Push: " << *Push << "\n");
1123c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman        Inst->eraseFromParent();
1133c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman        Push->eraseFromParent();
1143c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      }
1153c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      Push = 0;
1163c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      break;
1173c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    case IC_CallOrUser:
1183c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      if (MayAutorelease(ImmutableCallSite(Inst)))
1193c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman        Push = 0;
1203c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      break;
1213c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    default:
1223c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      break;
1233c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    }
1243c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  }
1253c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1263c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  return Changed;
1273c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman}
1283c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1293c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesmanbool ObjCARCAPElim::runOnModule(Module &M) {
1303c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  if (!EnableARCOpts)
1313c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    return false;
1323c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1333c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // If nothing in the Module uses ARC, don't do anything.
1343c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  if (!ModuleHasARC(M))
1353c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    return false;
1363c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1373c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // Find the llvm.global_ctors variable, as the first step in
1383c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // identifying the global constructors. In theory, unnecessary autorelease
1393c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // pools could occur anywhere, but in practice it's pretty rare. Global
1403c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // ctors are a place where autorelease pools get inserted automatically,
1413c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // so it's pretty common for them to be unnecessary, and it's pretty
1423c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // profitable to eliminate them.
1433c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  GlobalVariable *GV = M.getGlobalVariable("llvm.global_ctors");
1443c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  if (!GV)
1453c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    return false;
1463c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1473c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  assert(GV->hasDefinitiveInitializer() &&
1483c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman         "llvm.global_ctors is uncooperative!");
1493c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1503c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  bool Changed = false;
1513c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1523c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  // Dig the constructor functions out of GV's initializer.
1533c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
1543c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  for (User::op_iterator OI = Init->op_begin(), OE = Init->op_end();
1553c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman       OI != OE; ++OI) {
1563c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    Value *Op = *OI;
1573c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // llvm.global_ctors is an array of pairs where the second members
1583c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // are constructor functions.
1593c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    Function *F = dyn_cast<Function>(cast<ConstantStruct>(Op)->getOperand(1));
1603c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // If the user used a constructor function with the wrong signature and
1613c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // it got bitcasted or whatever, look the other way.
1623c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    if (!F)
1633c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      continue;
1643c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // Only look at function definitions.
1653c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    if (F->isDeclaration())
1663c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      continue;
1673c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // Only look at functions with one basic block.
1683c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    if (llvm::next(F->begin()) != F->end())
1693c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman      continue;
1703c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    // Ok, a single-block constructor function definition. Try to optimize it.
1713c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman    Changed |= OptimizeBB(F->begin());
1723c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  }
1733c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
1743c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman  return Changed;
1753c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman}
176