[llvm-commits] [llvm] r148330 - in /llvm/trunk: include/llvm/InitializePasses.h include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/ObjCARC.cpp lib/Transforms/Scalar/Scalar.cpp test/Transforms/ObjCARC/apelim.ll
Eli Friedman
eli.friedman at gmail.com
Tue Jan 17 13:15:01 PST 2012
On Tue, Jan 17, 2012 at 12:52 PM, Dan Gohman <gohman at apple.com> wrote:
> Author: djg
> Date: Tue Jan 17 14:52:24 2012
> New Revision: 148330
>
> URL: http://llvm.org/viewvc/llvm-project?rev=148330&view=rev
> Log:
> Add a new ObjC ARC optimization pass to eliminate unneeded
> autorelease push+pop pairs.
>
> Added:
> llvm/trunk/test/Transforms/ObjCARC/apelim.ll
> Modified:
> llvm/trunk/include/llvm/InitializePasses.h
> llvm/trunk/include/llvm/LinkAllPasses.h
> llvm/trunk/include/llvm/Transforms/Scalar.h
> llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
> llvm/trunk/lib/Transforms/Scalar/Scalar.cpp
>
> Modified: llvm/trunk/include/llvm/InitializePasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=148330&r1=148329&r2=148330&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/InitializePasses.h (original)
> +++ llvm/trunk/include/llvm/InitializePasses.h Tue Jan 17 14:52:24 2012
> @@ -168,6 +168,7 @@
> void initializeNoProfileInfoPass(PassRegistry&);
> void initializeNoPathProfileInfoPass(PassRegistry&);
> void initializeObjCARCAliasAnalysisPass(PassRegistry&);
> +void initializeObjCARCAPElimPass(PassRegistry&);
> void initializeObjCARCExpandPass(PassRegistry&);
> void initializeObjCARCContractPass(PassRegistry&);
> void initializeObjCARCOptPass(PassRegistry&);
>
> Modified: llvm/trunk/include/llvm/LinkAllPasses.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=148330&r1=148329&r2=148330&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
> +++ llvm/trunk/include/llvm/LinkAllPasses.h Tue Jan 17 14:52:24 2012
> @@ -97,6 +97,7 @@
> (void) llvm::createNoAAPass();
> (void) llvm::createNoProfileInfoPass();
> (void) llvm::createObjCARCAliasAnalysisPass();
> + (void) llvm::createObjCARCAPElimPass();
> (void) llvm::createObjCARCExpandPass();
> (void) llvm::createObjCARCContractPass();
> (void) llvm::createObjCARCOptPass();
>
> Modified: llvm/trunk/include/llvm/Transforms/Scalar.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar.h?rev=148330&r1=148329&r2=148330&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Scalar.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Scalar.h Tue Jan 17 14:52:24 2012
> @@ -327,6 +327,12 @@
>
> //===----------------------------------------------------------------------===//
> //
> +// ObjCARCAPElim - ObjC ARC autorelease pool elimination.
> +//
> +Pass *createObjCARCAPElimPass();
> +
> +//===----------------------------------------------------------------------===//
> +//
> // ObjCARCExpand - ObjC ARC preliminary simplifications.
> //
> Pass *createObjCARCExpandPass();
>
> Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=148330&r1=148329&r2=148330&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Tue Jan 17 14:52:24 2012
> @@ -375,7 +375,7 @@
> }
>
> // Otherwise, be conservative.
> - return IC_User;
> + return isa<InvokeInst>(V) ? IC_CallOrUser : IC_User;
> }
>
> /// IsRetain - Test if the the given class is objc_retain or
> @@ -884,6 +884,122 @@
> }
>
> //===----------------------------------------------------------------------===//
> +// ARC autorelease pool elimination.
> +//===----------------------------------------------------------------------===//
> +
> +namespace {
> + /// ObjCARCAPElim - Autorelease pool elimination.
> + class ObjCARCAPElim : public ModulePass {
> + virtual void getAnalysisUsage(AnalysisUsage &AU) const;
> + virtual bool runOnModule(Module &M);
> +
> + bool MayAutorelease(CallSite CS);
> + 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();
> +}
> +
> +/// MayAutorelease - Interprocedurally determine if calls made by the
> +/// given call site can possibly produce autoreleases.
> +bool ObjCARCAPElim::MayAutorelease(CallSite CS) {
> + if (Function *Callee = CS.getCalledFunction()) {
> + if (Callee->isDeclaration() || Callee->mayBeOverridden())
> + return true;
> + for (Function::iterator I = Callee->begin(), E = Callee->end();
> + I != E; ++I) {
> + BasicBlock *BB = I;
> + for (BasicBlock::iterator J = BB->begin(), F = BB->end(); J != F; ++J)
> + if (CallSite JCS = CallSite(J))
> + if (!JCS.onlyReadsMemory() && MayAutorelease(JCS))
> + return true;
> + }
> + return false;
> + }
> +
> + return true;
> +}
> +
> +bool ObjCARCAPElim::OptimizeBB(BasicBlock *BB) {
> + bool Changed = false;
> +
> + Instruction *Push = 0;
> + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
> + Instruction *Inst = I++;
> + switch (GetBasicInstructionClass(Inst)) {
> + case IC_AutoreleasepoolPush:
> + Push = Inst;
> + break;
> + case IC_AutoreleasepoolPop:
> + // If this pop matches a push and nothing in between can autorelease,
> + // zap the pair.
> + if (Push && cast<CallInst>(Inst)->getArgOperand(0) == Push) {
> + Changed = true;
> + Inst->eraseFromParent();
> + Push->eraseFromParent();
> + }
> + Push = 0;
> + break;
> + case IC_CallOrUser:
> + if (MayAutorelease(CallSite(Inst)))
> + Push = 0;
> + break;
> + default:
> + break;
> + }
> + }
> +
> + return Changed;
> +}
> +
> +bool ObjCARCAPElim::runOnModule(Module &M) {
> + if (!EnableARCOpts)
> + return false;
> +
> + // If nothing in the Module uses ARC, don't do anything.
> + if (!ModuleHasARC(M))
> + return false;
> +
> + bool Changed = false;
> +
> + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
> + Function *F = I;
> + // Only look at function definitions.
> + if (F->isDeclaration())
> + continue;
> + // Only look at global constructor functions. Unfortunately,
> + // the name is the most convenient way to recognize them.
> + if (!F->getName().startswith("_GLOBAL__I_"))
> + continue;
This seems way more specialized than it needs to be; why not a more
general transformation that removes all redundant
objc_autoreleasePoolPush/objc_autoreleasePoolPop pairs?
Anyway, if you really only want global constructors, traversing
llvm.global_ctors seems like it would be more reliable.
-Eli
More information about the llvm-commits
mailing list