[llvm] r239480 - Add new EliminateAvailableExternally module pass, which is performed in

David Blaikie dblaikie at gmail.com
Wed Jun 10 11:00:23 PDT 2015


On Wed, Jun 10, 2015 at 10:49 AM, Teresa Johnson <tejohnson at google.com>
wrote:

> Author: tejohnson
> Date: Wed Jun 10 12:49:28 2015
> New Revision: 239480
>
> URL: http://llvm.org/viewvc/llvm-project?rev=239480&view=rev
> Log:
> Add new EliminateAvailableExternally module pass, which is performed in
> O2 compiles just before GlobalDCE, unless we are preparing for LTO.
>
> This pass eliminates available externally globals (turning them into
> declarations), regardless of whether they are dead/unreferenced, since
> we are guaranteed to have a copy available elsewhere at link time.
> This enables additional opportunities for GlobalDCE.
>
> If we are preparing for LTO (e.g. a -flto -c compile), the pass is not
> included as we want to preserve available externally functions for possible
> link time inlining.


I guess everyone else probably already thought this through & I'm just
running behind (I tuned out of the code review once it looked like other
more informed people were driving it), but why do we need to preserve these
functions in the LTO build - wouldn't we just find their definitions in
some other module anyway? Or is this to catch the case where they're truly
/external/ to LTO, such as in a pre-build object file, etc?

- David


> The FE indicates whether we are doing an -flto compile
> via the new PrepareForLTO flag on the PassManagerBuilder.


> Added:
>     llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp
> Modified:
>     llvm/trunk/include/llvm/InitializePasses.h
>     llvm/trunk/include/llvm/Transforms/IPO.h
>     llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h
>     llvm/trunk/lib/Transforms/IPO/CMakeLists.txt
>     llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
>
> Modified: llvm/trunk/include/llvm/InitializePasses.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=239480&r1=239479&r2=239480&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/InitializePasses.h (original)
> +++ llvm/trunk/include/llvm/InitializePasses.h Wed Jun 10 12:49:28 2015
> @@ -130,6 +130,7 @@ void initializeSanitizerCoverageModulePa
>  void initializeDataFlowSanitizerPass(PassRegistry&);
>  void initializeScalarizerPass(PassRegistry&);
>  void initializeEarlyCSELegacyPassPass(PassRegistry &);
> +void initializeEliminateAvailableExternallyPass(PassRegistry&);
>  void initializeExpandISelPseudosPass(PassRegistry&);
>  void initializeFunctionAttrsPass(PassRegistry&);
>  void initializeGCMachineCodeAnalysisPass(PassRegistry&);
>
> Modified: llvm/trunk/include/llvm/Transforms/IPO.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO.h?rev=239480&r1=239479&r2=239480&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/IPO.h (original)
> +++ llvm/trunk/include/llvm/Transforms/IPO.h Wed Jun 10 12:49:28 2015
> @@ -71,6 +71,12 @@ ModulePass *createGlobalOptimizerPass();
>  ModulePass *createGlobalDCEPass();
>
>
>  //===----------------------------------------------------------------------===//
> +/// This transform is designed to eliminate available external globals
> +/// (functions or global variables)
> +///
> +ModulePass *createEliminateAvailableExternallyPass();
> +
>
> +//===----------------------------------------------------------------------===//
>  /// createGVExtractionPass - If deleteFn is true, this pass deletes
>  /// the specified global values. Otherwise, it deletes as much of the
> module as
>  /// possible, except for the global values specified.
>
> Modified: llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h?rev=239480&r1=239479&r2=239480&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h (original)
> +++ llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h Wed Jun 10
> 12:49:28 2015
> @@ -121,6 +121,7 @@ public:
>    bool VerifyInput;
>    bool VerifyOutput;
>    bool MergeFunctions;
> +  bool PrepareForLTO;
>
>  private:
>    /// ExtensionList - This is list of all of the extensions that are
> registered.
>
> Modified: llvm/trunk/lib/Transforms/IPO/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/CMakeLists.txt?rev=239480&r1=239479&r2=239480&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Transforms/IPO/CMakeLists.txt Wed Jun 10 12:49:28 2015
> @@ -3,6 +3,7 @@ add_llvm_library(LLVMipo
>    BarrierNoopPass.cpp
>    ConstantMerge.cpp
>    DeadArgumentElimination.cpp
> +  ElimAvailExtern.cpp
>    ExtractGV.cpp
>    FunctionAttrs.cpp
>    GlobalDCE.cpp
>
> Added: llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp?rev=239480&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp (added)
> +++ llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp Wed Jun 10 12:49:28
> 2015
> @@ -0,0 +1,96 @@
> +//===-- ElimAvailExtern.cpp - DCE unreachable internal functions
> ----------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This transform is designed to eliminate available external global
> +// definitions from the program, turning them into declarations.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/Transforms/IPO.h"
> +#include "llvm/ADT/Statistic.h"
> +#include "llvm/IR/Constants.h"
> +#include "llvm/IR/Instructions.h"
> +#include "llvm/IR/Module.h"
> +#include "llvm/Transforms/Utils/CtorUtils.h"
> +#include "llvm/Transforms/Utils/GlobalStatus.h"
> +#include "llvm/Pass.h"
> +using namespace llvm;
> +
> +#define DEBUG_TYPE "elim-avail-extern"
> +
> +STATISTIC(NumAliases  , "Number of global aliases removed");
> +STATISTIC(NumFunctions, "Number of functions removed");
> +STATISTIC(NumVariables, "Number of global variables removed");
> +
> +namespace {
> +  struct EliminateAvailableExternally : public ModulePass {
> +    static char ID; // Pass identification, replacement for typeid
> +    EliminateAvailableExternally() : ModulePass(ID) {
> +      initializeEliminateAvailableExternallyPass(
> +          *PassRegistry::getPassRegistry());
> +    }
> +
> +    // run - Do the EliminateAvailableExternally pass on the specified
> module,
> +    // optionally updating the specified callgraph to reflect the changes.
> +    //
> +    bool runOnModule(Module &M) override;
> +  };
> +}
> +
> +char EliminateAvailableExternally::ID = 0;
> +INITIALIZE_PASS(EliminateAvailableExternally, "elim-avail-extern",
> +                "Eliminate Available Externally Globals", false, false)
> +
> +ModulePass *llvm::createEliminateAvailableExternallyPass() {
> +  return new EliminateAvailableExternally();
> +}
> +
> +bool EliminateAvailableExternally::runOnModule(Module &M) {
> +  bool Changed = false;
> +
> +  // Drop initializers of available externally global variables.
> +  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
> +       I != E; ++I) {
> +    if (!I->hasAvailableExternallyLinkage())
> +      continue;
> +    if (I->hasInitializer()) {
> +      Constant *Init = I->getInitializer();
> +      I->setInitializer(nullptr);
> +      if (isSafeToDestroyConstant(Init))
> +        Init->destroyConstant();
> +    }
> +    I->removeDeadConstantUsers();
> +    I->setLinkage(GlobalValue::ExternalLinkage);
> +    NumVariables++;
> +  }
> +
> +  // Drop the bodies of available externally functions.
> +  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
> +    if (!I->hasAvailableExternallyLinkage())
> +      continue;
> +    if (!I->isDeclaration())
> +      // This will set the linkage to external
> +      I->deleteBody();
> +    I->removeDeadConstantUsers();
> +    NumFunctions++;
> +  }
> +
> +  // Drop targets of available externally aliases.
> +  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I
> != E;
> +       ++I) {
> +    if (!I->hasAvailableExternallyLinkage())
> +      continue;
> +    I->setAliasee(nullptr);
> +    I->removeDeadConstantUsers();
> +    I->setLinkage(GlobalValue::ExternalLinkage);
> +    NumAliases++;
> +  }
> +
> +  return Changed;
> +}
>
> Modified: llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp?rev=239480&r1=239479&r2=239480&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Wed Jun 10
> 12:49:28 2015
> @@ -105,6 +105,7 @@ PassManagerBuilder::PassManagerBuilder()
>      VerifyInput = false;
>      VerifyOutput = false;
>      MergeFunctions = false;
> +    PrepareForLTO = false;
>  }
>
>  PassManagerBuilder::~PassManagerBuilder() {
> @@ -401,6 +402,17 @@ void PassManagerBuilder::populateModuleP
>      // GlobalOpt already deletes dead functions and globals, at -O2 try a
>      // late pass of GlobalDCE.  It is capable of deleting dead cycles.
>      if (OptLevel > 1) {
> +      if (!PrepareForLTO) {
> +        // Remove avail extern fns and globals definitions if we aren't
> +        // compiling an object file for later LTO. For LTO we want to
> preserve
> +        // these so they are eligible for inlining at link-time. Note if
> they
> +        // are unreferenced they will be removed by GlobalDCE below, so
> +        // this only impacts referenced available externally globals.
> +        // Eventually they will be suppressed during codegen, but
> eliminating
> +        // here enables more opportunity for GlobalDCE as it may make
> +        // globals referenced by available external functions dead.
> +        MPM.add(createEliminateAvailableExternallyPass());
> +      }
>        MPM.add(createGlobalDCEPass());         // Remove dead fns and
> globals.
>        MPM.add(createConstantMergePass());     // Merge dup global
> constants
>      }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150610/2ff9a91c/attachment.html>


More information about the llvm-commits mailing list