Index: llvm/trunk/include/llvm/Transforms/Scalar/SCCP.h =================================================================== --- llvm/trunk/include/llvm/Transforms/Scalar/SCCP.h +++ llvm/trunk/include/llvm/Transforms/Scalar/SCCP.h @@ -43,6 +43,7 @@ struct AnalysisResultsForFn { std::unique_ptr PredInfo; DominatorTree *DT; + PostDominatorTree *PDT; }; bool runIPSCCP(Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI, Index: llvm/trunk/lib/Transforms/IPO/SCCP.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/SCCP.cpp +++ llvm/trunk/lib/Transforms/IPO/SCCP.cpp @@ -1,5 +1,6 @@ #include "llvm/Transforms/IPO/SCCP.h" #include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar/SCCP.h" @@ -14,7 +15,7 @@ DominatorTree &DT = FAM.getResult(F); return { make_unique(F, DT, FAM.getResult(F)), - &DT}; + &DT, FAM.getCachedResult(F)}; }; if (!runIPSCCP(M, DL, &TLI, getAnalysis)) @@ -22,6 +23,7 @@ PreservedAnalyses PA; PA.preserve(); + PA.preserve(); PA.preserve(); return PA; } @@ -56,8 +58,8 @@ F, DT, this->getAnalysis().getAssumptionCache( F)), - nullptr}; // We cannot preserve the DT with the legacy pass manager, - // so so set it to nullptr. + nullptr, // We cannot preserve the DT or PDT with the legacy pass + nullptr}; // manager, so set them to nullptr. }; return runIPSCCP(M, DL, TLI, getAnalysis); Index: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp +++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp @@ -262,10 +262,10 @@ return A->second.PredInfo->getPredicateInfoFor(I); } - DominatorTree *getDomTree(Function &F) { + DomTreeUpdater getDTU(Function &F) { auto A = AnalysisResults.find(&F); assert(A != AnalysisResults.end() && "Need analysis results for function."); - return A->second.DT; + return {A->second.DT, A->second.PDT, DomTreeUpdater::UpdateStrategy::Lazy}; } SCCPSolver(const DataLayout &DL, const TargetLibraryInfo *tli) @@ -2036,8 +2036,7 @@ } } - DomTreeUpdater DTU(Solver.getDomTree(F), - DomTreeUpdater::UpdateStrategy::Lazy); + DomTreeUpdater DTU = Solver.getDTU(F); // Change dead blocks to unreachable. We do it after replacing constants // in all executable blocks, because changeToUnreachable may remove PHI // nodes in executable blocks we found values for. The function's entry Index: llvm/trunk/test/Transforms/SCCP/ipsccp-preserve-analysis.ll =================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-preserve-analysis.ll +++ llvm/trunk/test/Transforms/SCCP/ipsccp-preserve-analysis.ll @@ -0,0 +1,56 @@ +; Basic test to check that DominatorTreeAnalysis is preserved by IPSCCP and +; the following analysis can re-use it. The test contains two trivial functions +; IPSCCP can simplify, so we can test the case where IPSCCP makes changes. + +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='function(require,require),ipsccp,function(require,require)' -S %s 2>&1 \ +; RUN: | FileCheck -check-prefixes='IR,NEW-PM' %s + +; RUN: opt -passes='function(require),ipsccp,function(verify)' -S %s | FileCheck -check-prefixes='IR' %s + +; NEW-PM: Starting llvm::Module pass manager run. +; NEW-PM: Running analysis: DominatorTreeAnalysis on f1 +; NEW-PM: Running analysis: PostDominatorTreeAnalysis on f1 +; NEW-PM: Running analysis: DominatorTreeAnalysis on f2 +; NEW-PM: Running analysis: PostDominatorTreeAnalysis on f2 +; NEW-PM: Running pass: IPSCCPPass +; NEW-PM-DAG: Running analysis: AssumptionAnalysis on f1 +; NEW-PM-DAG: Running analysis: AssumptionAnalysis on f2 +; NEW-PM-NEXT: Invalidating all non-preserved analyses for: +; NEW-PM-NEXT: Invalidating all non-preserved analyses for: f1 +; NEW-PM-NEXT: Invalidating all non-preserved analyses for: f2 +; NEW-PM-NEXT: Running pass: ModuleToFunctionPassAdaptor +; NEW-PM-NOT: Running analysis: + +; IR-LABEL: @f1 +; IR-LABEL: entry: +; IR-NEXT: br label %bb2 +; IR-LABEL: bb2: +; IR-NEXT: undef + +; IR-LABEL: @f2 +; IR-NOT: icmp +; IR: br label %bbtrue +; IR-LABEL: bbtrue: +; IR-NEXT: ret i32 0 +define internal i32 @f1() readnone { +entry: + br i1 false, label %bb1, label %bb2 +bb1: + ret i32 10 +bb2: + ret i32 10 +} + +define i32 @f2(i32 %n) { + %i = call i32 @f1() + %cmp = icmp eq i32 %i, 10 + br i1 %cmp, label %bbtrue, label %bbfalse + +bbtrue: + ret i32 0 + +bbfalse: + %res = add i32 %n, %i + ret i32 %res +} Index: llvm/trunk/test/Transforms/SCCP/ipsccp-preserve-domtree.ll =================================================================== --- llvm/trunk/test/Transforms/SCCP/ipsccp-preserve-domtree.ll +++ llvm/trunk/test/Transforms/SCCP/ipsccp-preserve-domtree.ll @@ -1,63 +0,0 @@ -; Basic test to check that DominatorTreeAnalysis is preserved by IPSCCP and -; the following analysis can re-use it. The test contains two trivial functions -; IPSCCP can simplify, so we can test the case where IPSCCP makes changes. - -; RUN: opt -disable-verify -debug-pass-manager \ -; RUN: -passes='ipsccp,globalopt' -S %s 2>&1 \ -; RUN: | FileCheck -check-prefixes='IR,NEW-PM' %s - -; RUN: opt -passes='ipsccp,function(verify)' -S %s | FileCheck -check-prefixes='IR' %s - -; NEW-PM: Starting llvm::Module pass manager run. -; NEW-PM-NEXT: Running pass: IPSCCPPass -; NEW-PM-DAG: Running analysis: TargetLibraryAnalysis -; NEW-PM-DAG: Running analysis: InnerAnalysisManagerProxy -; NEW-PM-DAG: Running analysis: AssumptionAnalysis on f1 -; NEW-PM-DAG: Running analysis: DominatorTreeAnalysis on f1 -; NEW-PM-DAG: Running analysis: PassInstrumentationAnalysis on f1 -; NEW-PM-DAG: Running analysis: DominatorTreeAnalysis on f2 -; NEW-PM-DAG: Running analysis: AssumptionAnalysis on f2 -; NEW-PM-DAG: Running analysis: PassInstrumentationAnalysis on f2 -; NEW-PM-NEXT: Invalidating all non-preserved analyses for: -; NEW-PM-NEXT: Invalidating all non-preserved analyses for: f1 -; NEW-PM-NEXT: Invalidating all non-preserved analyses for: f2 -; NEW-PM-NEXT: Running pass: GlobalOptPass on -; NEW-PM-DAG: Running analysis: BlockFrequencyAnalysis on f2 -; NEW-PM-DAG: Running analysis: LoopAnalysis on f2 -; NEW-PM-DAG: Running analysis: BranchProbabilityAnalysis on f2 -; NEW-PM-DAG: Running analysis: TargetLibraryAnalysis on f2 -; NEW-PM-NEXT: Running analysis: TargetIRAnalysis on f1 -; NEW-PM-NEXT: Invalidating all non-preserved analyses for: - -; IR-LABEL: @f1 -; IR-LABEL: entry: -; IR-NEXT: br label %bb2 -; IR-LABEL: bb2: -; IR-NEXT: undef - -; IR-LABEL: @f2 -; IR-NOT: icmp -; IR: br label %bbtrue -; IR-LABEL: bbtrue: -; IR-NEXT: ret i32 0 -define internal i32 @f1() readnone { -entry: - br i1 false, label %bb1, label %bb2 -bb1: - ret i32 10 -bb2: - ret i32 10 -} - -define i32 @f2(i32 %n) { - %i = call i32 @f1() - %cmp = icmp eq i32 %i, 10 - br i1 %cmp, label %bbtrue, label %bbfalse - -bbtrue: - ret i32 0 - -bbfalse: - %res = add i32 %n, %i - ret i32 %res -}