//===-- SCCP.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements Interprocedural Sparse Conditional Constant Propagation. // //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO/SCCP.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/InitializePasses.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar/SCCP.h" #include "llvm/Transforms/Utils/SCCPSolver.h" using namespace llvm; PreservedAnalyses IPSCCPPass::run(Module &M, ModuleAnalysisManager &AM) { const DataLayout &DL = M.getDataLayout(); auto &FAM = AM.getResult(M).getManager(); auto GetTLI = [&FAM](Function &F) -> const TargetLibraryInfo & { return FAM.getResult(F); }; auto getAnalysis = [&FAM](Function &F) -> AnalysisResultsForFn { DominatorTree &DT = FAM.getResult(F); return { std::make_unique(F, DT, FAM.getResult(F)), &DT, FAM.getCachedResult(F)}; }; if (!runIPSCCP(M, DL, GetTLI, getAnalysis)) return PreservedAnalyses::all(); PreservedAnalyses PA; PA.preserve(); PA.preserve(); PA.preserve(); return PA; } namespace { //===--------------------------------------------------------------------===// // /// IPSCCP Class - This class implements interprocedural Sparse Conditional /// Constant Propagation. /// class IPSCCPLegacyPass : public ModulePass { public: static char ID; IPSCCPLegacyPass() : ModulePass(ID) { initializeIPSCCPLegacyPassPass(*PassRegistry::getPassRegistry()); } bool runOnModule(Module &M) override { if (skipModule(M)) return false; const DataLayout &DL = M.getDataLayout(); auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & { return this->getAnalysis().getTLI(F); }; auto getAnalysis = [this](Function &F) -> AnalysisResultsForFn { DominatorTree &DT = this->getAnalysis(F).getDomTree(); return { std::make_unique( F, DT, this->getAnalysis().getAssumptionCache( F)), nullptr, // We cannot preserve the DT or PDT with the legacy pass nullptr}; // manager, so set them to nullptr. }; return runIPSCCP(M, DL, GetTLI, getAnalysis); } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); AU.addRequired(); } }; } // end anonymous namespace char IPSCCPLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN(IPSCCPLegacyPass, "ipsccp", "Interprocedural Sparse Conditional Constant Propagation", false, false) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 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(); } PreservedAnalyses FunctionSpecializationPass::run(Module &M, ModuleAnalysisManager &AM) { const DataLayout &DL = M.getDataLayout(); auto &FAM = AM.getResult(M).getManager(); auto GetTLI = [&FAM](Function &F) -> TargetLibraryInfo & { return FAM.getResult(F); }; auto GetTTI = [&FAM](Function &F) -> TargetTransformInfo & { return FAM.getResult(F); }; auto GetAC = [&FAM](Function &F) -> AssumptionCache & { return FAM.getResult(F); }; auto GetAnalysis = [&FAM](Function &F) -> AnalysisResultsForFn { DominatorTree &DT = FAM.getResult(F); return {std::make_unique( F, DT, FAM.getResult(F)), &DT, FAM.getCachedResult(F)}; }; if (!runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis)) return PreservedAnalyses::all(); PreservedAnalyses PA; PA.preserve(); PA.preserve(); PA.preserve(); return PA; } namespace { struct FunctionSpecializationLegacyPass : public ModulePass { static char ID; // Pass identification, replacement for typeid FunctionSpecializationLegacyPass() : ModulePass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired(); AU.addRequired(); AU.addRequired(); AU.addRequired(); } bool runOnModule(Module &M) override { if (skipModule(M)) return false; const DataLayout &DL = M.getDataLayout(); auto GetTLI = [this](Function &F) -> TargetLibraryInfo & { return this->getAnalysis().getTLI(F); }; auto GetTTI = [this](Function &F) -> TargetTransformInfo & { return this->getAnalysis().getTTI(F); }; auto GetAC = [this](Function &F) -> AssumptionCache & { return this->getAnalysis().getAssumptionCache(F); }; auto GetAnalysis = [this](Function &F) -> AnalysisResultsForFn { DominatorTree &DT = this->getAnalysis(F).getDomTree(); return { std::make_unique( F, DT, this->getAnalysis().getAssumptionCache( F)), nullptr, // We cannot preserve the DT or PDT with the legacy pass nullptr}; // manager, so set them to nullptr. }; return runFunctionSpecialization(M, DL, GetTLI, GetTTI, GetAC, GetAnalysis); } }; } // namespace char FunctionSpecializationLegacyPass::ID = 0; INITIALIZE_PASS_BEGIN( FunctionSpecializationLegacyPass, "function-specialization", "Propagate constant arguments by specializing the function", false, false) INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) INITIALIZE_PASS_END(FunctionSpecializationLegacyPass, "function-specialization", "Propagate constant arguments by specializing the function", false, false) ModulePass *llvm::createFunctionSpecializationPass() { return new FunctionSpecializationLegacyPass(); }