[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