diff --git a/llvm/include/llvm/Transforms/ObjCARC.h b/llvm/include/llvm/Transforms/ObjCARC.h --- a/llvm/include/llvm/Transforms/ObjCARC.h +++ b/llvm/include/llvm/Transforms/ObjCARC.h @@ -52,6 +52,10 @@ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); }; +struct ObjCARCAPElimPass : public PassInfoMixin { + PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); +}; + } // End llvm namespace #endif diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -75,6 +75,7 @@ MODULE_PASS("name-anon-globals", NameAnonGlobalPass()) MODULE_PASS("no-op-module", NoOpModulePass()) MODULE_PASS("objc-arc", ObjCARCOptPass()) +MODULE_PASS("objc-arc-apelim", ObjCARCOptPass()) MODULE_PASS("objc-arc-contract", ObjCARCContractPass()) MODULE_PASS("partial-inliner", PartialInlinerPass()) MODULE_PASS("pgo-icall-prom", PGOIndirectCallPromotion()) diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp --- a/llvm/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCAPElim.cpp @@ -26,9 +26,11 @@ #include "ObjCARC.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/ObjCARC.h" using namespace llvm; using namespace llvm::objcarc; @@ -36,39 +38,10 @@ #define DEBUG_TYPE "objc-arc-ap-elim" namespace { - /// Autorelease pool elimination. - class ObjCARCAPElim : public ModulePass { - void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnModule(Module &M) override; - - static bool MayAutorelease(const CallBase &CB, unsigned Depth = 0); - static bool OptimizeBB(BasicBlock *BB); - - public: - static char ID; - ObjCARCAPElim() : ModulePass(ID) { - initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry()); - } - }; -} - -char ObjCARCAPElim::ID = 0; -INITIALIZE_PASS(ObjCARCAPElim, - "objc-arc-apelim", - "ObjC ARC autorelease pool elimination", - false, false) - -Pass *llvm::createObjCARCAPElimPass() { - return new ObjCARCAPElim(); -} - -void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); -} /// Interprocedurally determine if calls made by the given call site can /// possibly produce autoreleases. -bool ObjCARCAPElim::MayAutorelease(const CallBase &CB, unsigned Depth) { +bool MayAutorelease(const CallBase &CB, unsigned Depth = 0) { if (const Function *Callee = CB.getCalledFunction()) { if (!Callee->hasExactDefinition()) return true; @@ -87,7 +60,7 @@ return true; } -bool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) { +bool OptimizeBB(BasicBlock *BB) { bool Changed = false; Instruction *Push = nullptr; @@ -125,17 +98,13 @@ return Changed; } -bool ObjCARCAPElim::runOnModule(Module &M) { +bool runImpl(Module &M) { if (!EnableARCOpts) return false; // If nothing in the Module uses ARC, don't do anything. if (!ModuleHasARC(M)) return false; - - if (skipModule(M)) - return false; - // Find the llvm.global_ctors variable, as the first step in // identifying the global constructors. In theory, unnecessary autorelease // pools could occur anywhere, but in practice it's pretty rare. Global @@ -175,3 +144,40 @@ return Changed; } + +/// Autorelease pool elimination. +class ObjCARCAPElim : public ModulePass { + void getAnalysisUsage(AnalysisUsage &AU) const override; + bool runOnModule(Module &M) override; + +public: + static char ID; + ObjCARCAPElim() : ModulePass(ID) { + initializeObjCARCAPElimPass(*PassRegistry::getPassRegistry()); + } +}; +} // namespace + +char ObjCARCAPElim::ID = 0; +INITIALIZE_PASS(ObjCARCAPElim, "objc-arc-apelim", + "ObjC ARC autorelease pool elimination", false, false) + +Pass *llvm::createObjCARCAPElimPass() { return new ObjCARCAPElim(); } + +void ObjCARCAPElim::getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); +} + +bool ObjCARCAPElim::runOnModule(Module &M) { + if (skipModule(M)) + return false; + return runImpl(M); +} + +PreservedAnalyses ObjCARCAPElimPass::run(Module &M, ModuleAnalysisManager &AM) { + if (!runImpl(M)) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserveSet(); + return PA; +} diff --git a/llvm/test/Transforms/ObjCARC/apelim.ll b/llvm/test/Transforms/ObjCARC/apelim.ll --- a/llvm/test/Transforms/ObjCARC/apelim.ll +++ b/llvm/test/Transforms/ObjCARC/apelim.ll @@ -1,4 +1,5 @@ ; RUN: opt -S -objc-arc-apelim < %s | FileCheck %s +; RUN: opt -S -passes=objc-arc-apelim < %s | FileCheck %s ; rdar://10227311 @llvm.global_ctors = appending global [2 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__I_x, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__I_y, i8* null }]