[llvm] r241466 - Resubmit "Add new EliminateAvailableExternally module pass" (r239480)

Rafael EspĂ­ndola rafael.espindola at gmail.com
Sat Jul 11 12:58:49 PDT 2015


Having to change the visibility in here is really odd.

Reid, your theory was that clang was not setting the visibility
correctly, was that not the case?

On 6 July 2015 at 12:22, Teresa Johnson <tejohnson at google.com> wrote:
> Author: tejohnson
> Date: Mon Jul  6 11:22:42 2015
> New Revision: 241466
>
> URL: http://llvm.org/viewvc/llvm-project?rev=241466&view=rev
> Log:
> Resubmit "Add new EliminateAvailableExternally module pass" (r239480)
>
> This change includes a fix for https://code.google.com/p/chromium/issues/detail?id=499508#c3,
> which required updating the visibility for symbols with eliminated definitions.
>
> --Original Commit Message--
>
> 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. 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=241466&r1=241465&r2=241466&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/InitializePasses.h (original)
> +++ llvm/trunk/include/llvm/InitializePasses.h Mon Jul  6 11:22:42 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=241466&r1=241465&r2=241466&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/IPO.h (original)
> +++ llvm/trunk/include/llvm/Transforms/IPO.h Mon Jul  6 11:22:42 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=241466&r1=241465&r2=241466&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h (original)
> +++ llvm/trunk/include/llvm/Transforms/IPO/PassManagerBuilder.h Mon Jul  6 11:22:42 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=241466&r1=241465&r2=241466&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Transforms/IPO/CMakeLists.txt Mon Jul  6 11:22:42 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=241466&view=auto
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp (added)
> +++ llvm/trunk/lib/Transforms/IPO/ElimAvailExtern.cpp Mon Jul  6 11:22:42 2015
> @@ -0,0 +1,99 @@
> +//===-- 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);
> +    I->setVisibility(GlobalValue::DefaultVisibility);
> +    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->setVisibility(GlobalValue::DefaultVisibility);
> +    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);
> +    I->setVisibility(GlobalValue::DefaultVisibility);
> +    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=241466&r1=241465&r2=241466&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp (original)
> +++ llvm/trunk/lib/Transforms/IPO/PassManagerBuilder.cpp Mon Jul  6 11:22:42 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



More information about the llvm-commits mailing list