diff --git a/llvm/include/llvm-c/Transforms/Scalar.h b/llvm/include/llvm-c/Transforms/Scalar.h index 06f20e5eaaa4f9..5aaeb9470168f6 100644 --- a/llvm/include/llvm-c/Transforms/Scalar.h +++ b/llvm/include/llvm-c/Transforms/Scalar.h @@ -97,6 +97,9 @@ void LLVMAddPartiallyInlineLibCallsPass(LLVMPassManagerRef PM); /** See llvm::createReassociatePass function. */ void LLVMAddReassociatePass(LLVMPassManagerRef PM); +/** See llvm::createSCCPPass function. */ +void LLVMAddSCCPPass(LLVMPassManagerRef PM); + /** See llvm::createSROAPass function. */ void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM); diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h index 45a9f472543364..8d1d1883972a28 100644 --- a/llvm/include/llvm/LinkAllPasses.h +++ b/llvm/include/llvm/LinkAllPasses.h @@ -135,6 +135,7 @@ namespace { (void) llvm::createRegionOnlyViewerPass(); (void) llvm::createRegionPrinterPass(); (void) llvm::createRegionViewerPass(); + (void) llvm::createSCCPPass(); (void) llvm::createSafeStackPass(); (void) llvm::createSROAPass(); (void) llvm::createSingleLoopExtractorPass(); diff --git a/llvm/include/llvm/Transforms/Scalar.h b/llvm/include/llvm/Transforms/Scalar.h index 1845084d6e51a3..2dea75291d4c7c 100644 --- a/llvm/include/llvm/Transforms/Scalar.h +++ b/llvm/include/llvm/Transforms/Scalar.h @@ -31,6 +31,12 @@ class Pass; // FunctionPass *createAlignmentFromAssumptionsPass(); +//===----------------------------------------------------------------------===// +// +// SCCP - Sparse conditional constant propagation. +// +FunctionPass *createSCCPPass(); + //===----------------------------------------------------------------------===// // // RedundantDbgInstElimination - This pass removes redundant dbg intrinsics diff --git a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp index 894fc90cef1b6b..841e6080790184 100644 --- a/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp +++ b/llvm/lib/Transforms/IPO/PassManagerBuilder.cpp @@ -167,6 +167,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses( MPM.add(createMergedLoadStoreMotionPass()); // Merge ld/st in diamonds MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies } + MPM.add(createSCCPPass()); // Constant prop with SCCP // Delete dead bit computations (instcombine runs after to fold away the dead // computations, and then ADCE will run later to exploit any new DCE @@ -235,6 +236,7 @@ void PassManagerBuilder::addVectorPasses(legacy::PassManagerBase &PM, .sinkCommonInsts(true))); if (IsFullLTO) { + PM.add(createSCCPPass()); // Propagate exposed constants PM.add(createInstructionCombiningPass()); // Clean up again PM.add(createBitTrackingDCEPass()); } diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index fcdc503c54a424..7b396c6ee0746a 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -41,6 +41,7 @@ #include "llvm/IR/Type.h" #include "llvm/IR/User.h" #include "llvm/IR/Value.h" +#include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" @@ -135,3 +136,54 @@ PreservedAnalyses SCCPPass::run(Function &F, FunctionAnalysisManager &AM) { PA.preserve(); return PA; } + +namespace { + +//===--------------------------------------------------------------------===// +// +/// SCCP Class - This class uses the SCCPSolver to implement a per-function +/// Sparse Conditional Constant Propagator. +/// +class SCCPLegacyPass : public FunctionPass { +public: + // Pass identification, replacement for typeid + static char ID; + + SCCPLegacyPass() : FunctionPass(ID) { + initializeSCCPLegacyPassPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired(); + AU.addPreserved(); + AU.addPreserved(); + } + + // runOnFunction - Run the Sparse Conditional Constant Propagation + // algorithm, and return true if the function was modified. + bool runOnFunction(Function &F) override { + if (skipFunction(F)) + return false; + const DataLayout &DL = F.getParent()->getDataLayout(); + const TargetLibraryInfo *TLI = + &getAnalysis().getTLI(F); + auto *DTWP = getAnalysisIfAvailable(); + DomTreeUpdater DTU(DTWP ? &DTWP->getDomTree() : nullptr, + DomTreeUpdater::UpdateStrategy::Lazy); + return runSCCP(F, DL, TLI, DTU); + } +}; + +} // end anonymous namespace + +char SCCPLegacyPass::ID = 0; + +INITIALIZE_PASS_BEGIN(SCCPLegacyPass, "sccp", + "Sparse Conditional Constant Propagation", false, false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_END(SCCPLegacyPass, "sccp", + "Sparse Conditional Constant Propagation", false, false) + +// createSCCPPass - This is the public interface to this file. +FunctionPass *llvm::createSCCPPass() { return new SCCPLegacyPass(); } + diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp index b59f333360eb09..e07471f75dae20 100644 --- a/llvm/lib/Transforms/Scalar/Scalar.cpp +++ b/llvm/lib/Transforms/Scalar/Scalar.cpp @@ -83,6 +83,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) { initializeRegToMemLegacyPass(Registry); initializeRewriteStatepointsForGCLegacyPassPass(Registry); initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry); + initializeSCCPLegacyPassPass(Registry); initializeSROALegacyPassPass(Registry); initializeCFGSimplifyPassPass(Registry); initializeStructurizeCFGLegacyPassPass(Registry); @@ -195,6 +196,10 @@ void LLVMAddReassociatePass(LLVMPassManagerRef PM) { unwrap(PM)->add(createReassociatePass()); } +void LLVMAddSCCPPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createSCCPPass()); +} + void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createSROAPass()); }