diff options
-rw-r--r-- | llvm/include/llvm/InitializePasses.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/Transforms/IPO/GlobalOpt.h | 32 | ||||
-rw-r--r-- | llvm/lib/LTO/LTOCodeGenerator.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Passes/PassBuilder.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/Passes/PassRegistry.def | 1 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/GlobalOpt.cpp | 95 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/IPO.cpp | 2 | ||||
-rw-r--r-- | llvm/test/Transforms/GlobalOpt/basictest.ll | 1 |
8 files changed, 95 insertions, 41 deletions
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 557f927a656..75738891c1b 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -141,7 +141,7 @@ void initializeGCMachineCodeAnalysisPass(PassRegistry&); void initializeGCModuleInfoPass(PassRegistry&); void initializeGVNLegacyPassPass(PassRegistry&); void initializeGlobalDCEPass(PassRegistry&); -void initializeGlobalOptPass(PassRegistry&); +void initializeGlobalOptLegacyPassPass(PassRegistry&); void initializeGlobalsAAWrapperPassPass(PassRegistry&); void initializeIPCPPass(PassRegistry&); void initializeIPSCCPPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO/GlobalOpt.h b/llvm/include/llvm/Transforms/IPO/GlobalOpt.h new file mode 100644 index 00000000000..5a25a6db439 --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/GlobalOpt.h @@ -0,0 +1,32 @@ +//===- GlobalOpt.h - Optimize Global Variables ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass transforms simple global variables that never have their address +// taken. If obviously true, it marks read/write globals as constant, deletes +// variables only stored to, etc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_GLOBALOPT_H +#define LLVM_TRANSFORMS_IPO_GLOBALOPT_H + +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// Optimize globals that never have their address taken. +class GlobalOptPass : public PassInfoMixin<GlobalOptPass> { +public: + PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM); +}; + +} + +#endif // LLVM_TRANSFORMS_IPO_GLOBALOPT_H diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 12bc05c3701..b98cb7dc6e6 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -98,7 +98,7 @@ void LTOCodeGenerator::initializeLTOPasses() { initializeInternalizePassPass(R); initializeIPSCCPPass(R); - initializeGlobalOptPass(R); + initializeGlobalOptLegacyPassPass(R); initializeConstantMergePass(R); initializeDAHPass(R); initializeInstructionCombiningPassPass(R); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 6d6993b305d..f2acd9af831 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -47,6 +47,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/ForceFunctionAttrs.h" #include "llvm/Transforms/IPO/FunctionAttrs.h" +#include "llvm/Transforms/IPO/GlobalOpt.h" #include "llvm/Transforms/IPO/InferFunctionAttrs.h" #include "llvm/Transforms/IPO/StripDeadPrototypes.h" #include "llvm/Transforms/InstCombine/InstCombine.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 8215eac1e51..d36146661eb 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -36,6 +36,7 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA()) #define MODULE_PASS(NAME, CREATE_PASS) #endif MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) +MODULE_PASS("globalopt", GlobalOptPass()) MODULE_PASS("inferattrs", InferFunctionAttrsPass()) MODULE_PASS("instrprof", InstrProfiling()) MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass()) diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index dbace87b2c3..26c1e09876d 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/GlobalOpt.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" @@ -40,6 +40,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Utils/CtorUtils.h" #include "llvm/Transforms/Utils/Evaluator.h" #include "llvm/Transforms/Utils/GlobalStatus.h" @@ -64,31 +65,6 @@ STATISTIC(NumAliasesResolved, "Number of global aliases resolved"); STATISTIC(NumAliasesRemoved, "Number of global aliases eliminated"); STATISTIC(NumCXXDtorsRemoved, "Number of global C++ destructors removed"); -namespace { - struct GlobalOpt : public ModulePass { - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired<TargetLibraryInfoWrapperPass>(); - AU.addRequired<DominatorTreeWrapperPass>(); - } - static char ID; // Pass identification, replacement for typeid - GlobalOpt() : ModulePass(ID) { - initializeGlobalOptPass(*PassRegistry::getPassRegistry()); - } - - bool runOnModule(Module &M) override; - }; -} - -char GlobalOpt::ID = 0; -INITIALIZE_PASS_BEGIN(GlobalOpt, "globalopt", - "Global Variable Optimizer", false, false) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_END(GlobalOpt, "globalopt", - "Global Variable Optimizer", false, false) - -ModulePass *llvm::createGlobalOptimizerPass() { return new GlobalOpt(); } - /// Is this global variable possibly used by a leak checker as a root? If so, /// we might not really want to eliminate the stores to it. static bool isLeakCheckerRoot(GlobalVariable *GV) { @@ -2530,19 +2506,11 @@ static bool OptimizeEmptyGlobalCXXDtors(Function *CXAAtExitFn) { return Changed; } -bool GlobalOpt::runOnModule(Module &M) { - if (skipModule(M)) - return false; - - bool Changed = false; - - auto &DL = M.getDataLayout(); - auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); - auto LookupDomTree = [this](Function &F) -> DominatorTree & { - return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); - }; - +static bool optimizeGlobalsInModule( + Module &M, const DataLayout &DL, TargetLibraryInfo *TLI, + function_ref<DominatorTree &(Function &)> LookupDomTree) { SmallSet<const Comdat *, 8> NotDiscardableComdats; + bool Changed = false; bool LocalChange = true; while (LocalChange) { LocalChange = false; @@ -2591,3 +2559,54 @@ bool GlobalOpt::runOnModule(Module &M) { return Changed; } + +PreservedAnalyses GlobalOptPass::run(Module &M, AnalysisManager<Module> &AM) { + auto &DL = M.getDataLayout(); + auto &TLI = AM.getResult<TargetLibraryAnalysis>(M); + auto &FAM = + AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); + auto LookupDomTree = [&FAM](Function &F) -> DominatorTree &{ + return FAM.getResult<DominatorTreeAnalysis>(F); + }; + if (!optimizeGlobalsInModule(M, DL, &TLI, LookupDomTree)) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); +} + +namespace { +struct GlobalOptLegacyPass : public ModulePass { + static char ID; // Pass identification, replacement for typeid + GlobalOptLegacyPass() : ModulePass(ID) { + initializeGlobalOptLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + if (skipModule(M)) + return false; + + auto &DL = M.getDataLayout(); + auto *TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); + auto LookupDomTree = [this](Function &F) -> DominatorTree & { + return this->getAnalysis<DominatorTreeWrapperPass>(F).getDomTree(); + }; + return optimizeGlobalsInModule(M, DL, TLI, LookupDomTree); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<TargetLibraryInfoWrapperPass>(); + AU.addRequired<DominatorTreeWrapperPass>(); + } +}; +} + +char GlobalOptLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(GlobalOptLegacyPass, "globalopt", + "Global Variable Optimizer", false, false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_END(GlobalOptLegacyPass, "globalopt", + "Global Variable Optimizer", false, false) + +ModulePass *llvm::createGlobalOptimizerPass() { + return new GlobalOptLegacyPass(); +} diff --git a/llvm/lib/Transforms/IPO/IPO.cpp b/llvm/lib/Transforms/IPO/IPO.cpp index 7e010606429..514b3cc895a 100644 --- a/llvm/lib/Transforms/IPO/IPO.cpp +++ b/llvm/lib/Transforms/IPO/IPO.cpp @@ -30,7 +30,7 @@ void llvm::initializeIPO(PassRegistry &Registry) { initializeDAHPass(Registry); initializeForceFunctionAttrsLegacyPassPass(Registry); initializeGlobalDCEPass(Registry); - initializeGlobalOptPass(Registry); + initializeGlobalOptLegacyPassPass(Registry); initializeIPCPPass(Registry); initializeAlwaysInlinerPass(Registry); initializeSimpleInlinerPass(Registry); diff --git a/llvm/test/Transforms/GlobalOpt/basictest.ll b/llvm/test/Transforms/GlobalOpt/basictest.ll index bc30e74995f..d5294820abe 100644 --- a/llvm/test/Transforms/GlobalOpt/basictest.ll +++ b/llvm/test/Transforms/GlobalOpt/basictest.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -globalopt -S | FileCheck %s +; RUN: opt < %s -passes=globalopt -S | FileCheck %s ; CHECK-NOT: global @X = internal global i32 4 ; <i32*> [#uses=1] |