diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 8eed24e63420..7df5c7f429d9 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -146,7 +146,7 @@ void initializeGlobalDCELegacyPassPass(PassRegistry&); void initializeGlobalOptLegacyPassPass(PassRegistry&); void initializeGlobalsAAWrapperPassPass(PassRegistry&); void initializeIPCPPass(PassRegistry&); -void initializeIPSCCPPass(PassRegistry&); +void initializeIPSCCPLegacyPassPass(PassRegistry &); void initializeIVUsersPass(PassRegistry&); void initializeIfConverterPass(PassRegistry&); void initializeInductiveRangeCheckEliminationPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO/SCCP.h b/llvm/include/llvm/Transforms/IPO/SCCP.h new file mode 100644 index 000000000000..dd50d8378b6c --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/SCCP.h @@ -0,0 +1,34 @@ +//===- SCCP.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 implements interprocedural sparse conditional constant +// propagation and merging. +// +// Specifically, this: +// * Assumes values are constant unless proven otherwise +// * Assumes BasicBlocks are dead unless proven otherwise +// * Proves values to be constant, and replaces them with constants +// * Proves conditional branches to be unconditional +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_SCCP_H +#define LLVM_TRANSFORMS_IPO_SCCP_H + +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { +/// Pass to perform interprocedural constant propagation. +class IPSCCPPass : public PassInfoMixin { +public: + PreservedAnalyses run(Module &M, AnalysisManager &AM); +}; +} +#endif // LLVM_TRANSFORMS_IPO_SCCP_H diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 77b827a294bf..226004a3353a 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -97,7 +97,7 @@ void LTOCodeGenerator::initializeLTOPasses() { PassRegistry &R = *PassRegistry::getPassRegistry(); initializeInternalizeLegacyPassPass(R); - initializeIPSCCPPass(R); + initializeIPSCCPLegacyPassPass(R); initializeGlobalOptLegacyPassPass(R); initializeConstantMergeLegacyPassPass(R); initializeDAHPass(R); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index bc03cc1059ac..d26e796bb544 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -54,6 +54,7 @@ #include "llvm/Transforms/IPO/GlobalOpt.h" #include "llvm/Transforms/IPO/InferFunctionAttrs.h" #include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/IPO/SCCP.h" #include "llvm/Transforms/IPO/StripDeadPrototypes.h" #include "llvm/Transforms/InstCombine/InstCombine.h" #include "llvm/Transforms/InstrProfiling.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index 37ef2245f43c..d8c56070ce01 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -44,6 +44,7 @@ MODULE_PASS("inferattrs", InferFunctionAttrsPass()) MODULE_PASS("internalize", InternalizePass()) MODULE_PASS("instrprof", InstrProfiling()) MODULE_PASS("invalidate", InvalidateAllAnalysesPass()) +MODULE_PASS("ipsccp", IPSCCPPass()) MODULE_PASS("no-op-module", NoOpModulePass()) MODULE_PASS("print", PrintModulePass(dbgs())) MODULE_PASS("print-callgraph", CallGraphPrinterPass(dbgs())) diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index f1f36b7425e5..75414ef3864d 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -17,15 +17,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar.h" +#include "llvm/Transforms/IPO/SCCP.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" -#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/GlobalsModRef.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" @@ -38,6 +38,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Local.h" #include using namespace llvm; @@ -1644,39 +1645,6 @@ bool SCCP::runOnFunction(Function &F) { return MadeChanges; } -namespace { - //===--------------------------------------------------------------------===// - // - /// IPSCCP Class - This class implements interprocedural Sparse Conditional - /// Constant Propagation. - /// - struct IPSCCP : public ModulePass { - void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.addRequired(); - } - static char ID; - IPSCCP() : ModulePass(ID) { - initializeIPSCCPPass(*PassRegistry::getPassRegistry()); - } - bool runOnModule(Module &M) override; - }; -} // end anonymous namespace - -char IPSCCP::ID = 0; -INITIALIZE_PASS_BEGIN(IPSCCP, "ipsccp", - "Interprocedural Sparse Conditional Constant Propagation", - false, false) -INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) -INITIALIZE_PASS_END(IPSCCP, "ipsccp", - "Interprocedural Sparse Conditional Constant Propagation", - false, false) - -// createIPSCCPPass - This is the public interface to this file. -ModulePass *llvm::createIPSCCPPass() { - return new IPSCCP(); -} - - static bool AddressIsTaken(const GlobalValue *GV) { // Delete any dead constantexpr klingons. GV->removeDeadConstantUsers(); @@ -1704,13 +1672,8 @@ static bool AddressIsTaken(const GlobalValue *GV) { return false; } -bool IPSCCP::runOnModule(Module &M) { - if (skipModule(M)) - return false; - - const DataLayout &DL = M.getDataLayout(); - const TargetLibraryInfo *TLI = - &getAnalysis().getTLI(); +static bool runIPSCCP(Module &M, const DataLayout &DL, + const TargetLibraryInfo *TLI) { SCCPSolver Solver(DL, TLI); // AddressTakenFunctions - This set keeps track of the address-taken functions @@ -1955,3 +1918,51 @@ bool IPSCCP::runOnModule(Module &M) { return MadeChanges; } + +PreservedAnalyses IPSCCPPass::run(Module &M, AnalysisManager &AM) { + const DataLayout &DL = M.getDataLayout(); + auto &TLI = AM.getResult(M); + if (!runIPSCCP(M, DL, &TLI)) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); +} + +namespace { +//===--------------------------------------------------------------------===// +// +/// IPSCCP Class - This class implements interprocedural Sparse Conditional +/// Constant Propagation. +/// +struct IPSCCPLegacyPass : public ModulePass { + static char ID; + + IPSCCPLegacyPass() : ModulePass(ID) { + initializeIPSCCPLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + bool runOnModule(Module &M) override { + if (skipModule(M)) + return false; + const DataLayout &DL = M.getDataLayout(); + const TargetLibraryInfo *TLI = + &getAnalysis().getTLI(); + return runIPSCCP(M, DL, TLI); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + } +}; +} // end anonymous namespace + +char IPSCCPLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(IPSCCPLegacyPass, "ipsccp", + "Interprocedural Sparse Conditional Constant Propagation", + false, false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_END(IPSCCPLegacyPass, "ipsccp", + "Interprocedural Sparse Conditional Constant Propagation", + false, false) + +// createIPSCCPPass - This is the public interface to this file. +ModulePass *llvm::createIPSCCPPass() { return new IPSCCPLegacyPass(); } diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp index f1204c30403b..5fe794c4449b 100644 --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -71,7 +71,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeRegToMemPass(Registry); initializeRewriteStatepointsForGCPass(Registry); initializeSCCPPass(Registry); - initializeIPSCCPPass(Registry); + initializeIPSCCPLegacyPassPass(Registry); initializeSROALegacyPassPass(Registry); initializeSROA_DTPass(Registry); initializeSROA_SSAUpPass(Registry); diff --git a/llvm/test/Transforms/IPConstantProp/global.ll b/llvm/test/Transforms/IPConstantProp/global.ll index d3ba14658f6e..5e34696d5662 100644 --- a/llvm/test/Transforms/IPConstantProp/global.ll +++ b/llvm/test/Transforms/IPConstantProp/global.ll @@ -1,3 +1,4 @@ +; RUN: opt < %s -S -passes=ipsccp | FileCheck %s ; RUN: opt < %s -S -ipsccp | FileCheck %s @_ZL6test1g = internal global i32 42, align 4