diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index ff5398f48af..c78ce003ea8 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -96,7 +96,7 @@ void initializeStructurizeCFGPass(PassRegistry&); void initializeCFGViewerPass(PassRegistry&); void initializeConstantHoistingPass(PassRegistry&); void initializeCodeGenPreparePass(PassRegistry&); -void initializeConstantMergePass(PassRegistry&); +void initializeConstantMergeLegacyPassPass(PassRegistry &); void initializeConstantPropagationPass(PassRegistry&); void initializeMachineCopyPropagationPass(PassRegistry&); void initializeCostModelAnalysisPass(PassRegistry&); diff --git a/include/llvm/Transforms/IPO/ConstantMerge.h b/include/llvm/Transforms/IPO/ConstantMerge.h new file mode 100644 index 00000000000..f0a31978c09 --- /dev/null +++ b/include/llvm/Transforms/IPO/ConstantMerge.h @@ -0,0 +1,35 @@ +//===- ConstantMerge.h - Merge duplicate global constants -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the interface to a pass that merges duplicate global +// constants together into a single constant that is shared. This is useful +// because some passes (ie TraceValues) insert a lot of string constants into +// the program, regardless of whether or not an existing string is available. +// +// Algorithm: ConstantMerge is designed to build up a map of available constants +// and eliminate duplicates when it is initialized. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H +#define LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H + +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +/// A pass that merges duplicate global constants into a single constant. +class ConstantMergePass : public PassInfoMixin { +public: + PreservedAnalyses run(Module &M); +}; +} + +#endif // LLVM_TRANSFORMS_IPO_CONSTANTMERGE_H diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index 539996ea295..712632761ea 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -99,7 +99,7 @@ void LTOCodeGenerator::initializeLTOPasses() { initializeInternalizeLegacyPassPass(R); initializeIPSCCPPass(R); initializeGlobalOptLegacyPassPass(R); - initializeConstantMergePass(R); + initializeConstantMergeLegacyPassPass(R); initializeDAHPass(R); initializeInstructionCombiningPassPass(R); initializeSimpleInlinerPass(R); diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index 2dcd3342f38..dbe655aca14 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Regex.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/IPO/ConstantMerge.h" #include "llvm/Transforms/IPO/ForceFunctionAttrs.h" #include "llvm/Transforms/IPO/FunctionAttrs.h" #include "llvm/Transforms/IPO/GlobalDCE.h" @@ -57,10 +58,10 @@ #include "llvm/Transforms/Scalar/ADCE.h" #include "llvm/Transforms/Scalar/DCE.h" #include "llvm/Transforms/Scalar/EarlyCSE.h" +#include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Scalar/LoopRotation.h" #include "llvm/Transforms/Scalar/LoopSimplifyCFG.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" -#include "llvm/Transforms/Scalar/GVN.h" #include "llvm/Transforms/Scalar/Reassociate.h" #include "llvm/Transforms/Scalar/SROA.h" #include "llvm/Transforms/Scalar/SimplifyCFG.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 366ffbdc3f2..ab07adfe5b9 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -35,6 +35,7 @@ MODULE_ALIAS_ANALYSIS("globals-aa", GlobalsAA()) #ifndef MODULE_PASS #define MODULE_PASS(NAME, CREATE_PASS) #endif +MODULE_PASS("constmerge", ConstantMergePass()) MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) MODULE_PASS("globaldce", GlobalDCEPass()) MODULE_PASS("globalopt", GlobalOptPass()) diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp index 9489c75e6fa..11f40e86460 100644 --- a/lib/Transforms/IPO/ConstantMerge.cpp +++ b/lib/Transforms/IPO/ConstantMerge.cpp @@ -17,7 +17,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/ConstantMerge.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" @@ -28,33 +28,13 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Operator.h" #include "llvm/Pass.h" +#include "llvm/Transforms/IPO.h" using namespace llvm; #define DEBUG_TYPE "constmerge" STATISTIC(NumMerged, "Number of global constants merged"); -namespace { - struct ConstantMerge : public ModulePass { - static char ID; // Pass identification, replacement for typeid - ConstantMerge() : ModulePass(ID) { - initializeConstantMergePass(*PassRegistry::getPassRegistry()); - } - - // For this pass, process all of the globals in the module, eliminating - // duplicate constants. - bool runOnModule(Module &M) override; - }; -} - -char ConstantMerge::ID = 0; -INITIALIZE_PASS(ConstantMerge, "constmerge", - "Merge Duplicate Global Constants", false, false) - -ModulePass *llvm::createConstantMergePass() { return new ConstantMerge(); } - - - /// Find values that are marked as llvm.used. static void FindUsedValues(GlobalVariable *LLVMUsed, SmallPtrSetImpl &UsedValues) { @@ -87,10 +67,7 @@ static unsigned getAlignment(GlobalVariable *GV) { return GV->getParent()->getDataLayout().getPreferredAlignment(GV); } -bool ConstantMerge::runOnModule(Module &M) { - if (skipModule(M)) - return false; - +static bool mergeConstants(Module &M) { // Find all the globals that are marked "used". These cannot be merged. SmallPtrSet UsedGlobals; FindUsedValues(M.getGlobalVariable("llvm.used"), UsedGlobals); @@ -214,3 +191,34 @@ bool ConstantMerge::runOnModule(Module &M) { Replacements.clear(); } } + +PreservedAnalyses ConstantMergePass::run(Module &M) { + if (!mergeConstants(M)) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); +} + +namespace { +struct ConstantMergeLegacyPass : public ModulePass { + static char ID; // Pass identification, replacement for typeid + ConstantMergeLegacyPass() : ModulePass(ID) { + initializeConstantMergeLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + // For this pass, process all of the globals in the module, eliminating + // duplicate constants. + bool runOnModule(Module &M) { + if (skipModule(M)) + return false; + return mergeConstants(M); + } +}; +} + +char ConstantMergeLegacyPass::ID = 0; +INITIALIZE_PASS(ConstantMergeLegacyPass, "constmerge", + "Merge Duplicate Global Constants", false, false) + +ModulePass *llvm::createConstantMergePass() { + return new ConstantMergeLegacyPass(); +} diff --git a/lib/Transforms/IPO/IPO.cpp b/lib/Transforms/IPO/IPO.cpp index 563ecf7e21b..8cdefe3d726 100644 --- a/lib/Transforms/IPO/IPO.cpp +++ b/lib/Transforms/IPO/IPO.cpp @@ -24,7 +24,7 @@ using namespace llvm; void llvm::initializeIPO(PassRegistry &Registry) { initializeArgPromotionPass(Registry); - initializeConstantMergePass(Registry); + initializeConstantMergeLegacyPassPass(Registry); initializeCrossDSOCFIPass(Registry); initializeDAEPass(Registry); initializeDAHPass(Registry); diff --git a/test/Transforms/ConstantMerge/merge-both.ll b/test/Transforms/ConstantMerge/merge-both.ll index 514c789b470..824ad5ab144 100644 --- a/test/Transforms/ConstantMerge/merge-both.ll +++ b/test/Transforms/ConstantMerge/merge-both.ll @@ -1,4 +1,4 @@ -; RUN: opt -constmerge -S < %s | FileCheck %s +; RUN: opt -S < %s -passes=constmerge | FileCheck %s ; Test that in one run var3 is merged into var2 and var1 into var4. ; Test that we merge @var5 and @var6 into one with the higher alignment