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