diff options
| author | Florian Hahn <florian.hahn@arm.com> | 2018-11-09 11:52:27 +0000 |
|---|---|---|
| committer | Florian Hahn <florian.hahn@arm.com> | 2018-11-09 11:52:27 +0000 |
| commit | a1062f4b68c5a750a5b66e56753b10a3a72d7129 (patch) | |
| tree | fdbd0282510dfd65eb3741d22a248a98c03e19a5 /llvm/lib/Transforms/Scalar | |
| parent | 5f5bc993407cf9ec0850ce8edd14f4e129e4b46c (diff) | |
| download | bcm5719-llvm-a1062f4b68c5a750a5b66e56753b10a3a72d7129.tar.gz bcm5719-llvm-a1062f4b68c5a750a5b66e56753b10a3a72d7129.zip | |
[IPSCCP,PM] Preserve DT in the new pass manager.
After D45330, Dominators are required for IPSCCP and can be preserved.
This patch preserves DominatorTreeAnalysis in the new pass manager. AFAIK the legacy pass manager cannot preserve function analysis required by a module analysis.
Reviewers: davide, dberlin, chandlerc, efriedma, kuhar, NutshellySima
Reviewed By: chandlerc, kuhar, NutshellySima
Differential Revision: https://reviews.llvm.org/D47259
llvm-svn: 346486
Diffstat (limited to 'llvm/lib/Transforms/Scalar')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/SCCP.cpp | 65 |
1 files changed, 38 insertions, 27 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp index 1f98128f923..1d75e58e31f 100644 --- a/llvm/lib/Transforms/Scalar/SCCP.cpp +++ b/llvm/lib/Transforms/Scalar/SCCP.cpp @@ -247,19 +247,25 @@ class SCCPSolver : public InstVisitor<SCCPSolver> { using Edge = std::pair<BasicBlock *, BasicBlock *>; DenseSet<Edge> KnownFeasibleEdges; - DenseMap<Function *, std::unique_ptr<PredicateInfo>> PredInfos; + DenseMap<Function *, AnalysisResultsForFn> AnalysisResults; DenseMap<Value *, SmallPtrSet<User *, 2>> AdditionalUsers; public: - void addPredInfo(Function &F, std::unique_ptr<PredicateInfo> PI) { - PredInfos[&F] = std::move(PI); + void addAnalysis(Function &F, AnalysisResultsForFn A) { + AnalysisResults.insert({&F, std::move(A)}); } const PredicateBase *getPredicateInfoFor(Instruction *I) { - auto PI = PredInfos.find(I->getFunction()); - if (PI == PredInfos.end()) + auto A = AnalysisResults.find(I->getParent()->getParent()); + if (A == AnalysisResults.end()) return nullptr; - return PI->second->getPredicateInfoFor(I); + return A->second.PredInfo->getPredicateInfoFor(I); + } + + DominatorTree *getDomTree(Function &F) { + auto A = AnalysisResults.find(&F); + assert(A != AnalysisResults.end() && "Need analysis results for function."); + return A->second.DT; } SCCPSolver(const DataLayout &DL, const TargetLibraryInfo *tli) @@ -1927,10 +1933,9 @@ static void forceIndeterminateEdge(Instruction* I, SCCPSolver &Solver) { } } - bool llvm::runIPSCCP( Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI, - function_ref<std::unique_ptr<PredicateInfo>(Function &)> getPredicateInfo) { + function_ref<AnalysisResultsForFn(Function &)> getAnalysis) { SCCPSolver Solver(DL, TLI); // Loop over all functions, marking arguments to those with their addresses @@ -1939,7 +1944,8 @@ bool llvm::runIPSCCP( if (F.isDeclaration()) continue; - Solver.addPredInfo(F, getPredicateInfo(F)); + Solver.addAnalysis(F, getAnalysis(F)); + // Determine if we can track the function's return values. If so, add the // function to the solver's set of return-tracked functions. if (canTrackReturnsInterprocedurally(&F)) @@ -1988,12 +1994,13 @@ bool llvm::runIPSCCP( // Iterate over all of the instructions in the module, replacing them with // constants if we have found them to be of constant values. - SmallVector<BasicBlock*, 512> BlocksToErase; for (Function &F : M) { if (F.isDeclaration()) continue; + SmallVector<BasicBlock *, 512> BlocksToErase; + if (Solver.isBlockExecutable(&F.front())) for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); AI != E; ++AI) { @@ -2029,23 +2036,27 @@ bool llvm::runIPSCCP( } } - // 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 block is - // not part of BlocksToErase, so we have to handle it separately. - for (BasicBlock *BB : BlocksToErase) + DomTreeUpdater DTU(Solver.getDomTree(F), + DomTreeUpdater::UpdateStrategy::Lazy); + // 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 + // block is not part of BlocksToErase, so we have to handle it separately. + for (BasicBlock *BB : BlocksToErase) { NumInstRemoved += - changeToUnreachable(BB->getFirstNonPHI(), /*UseLLVMTrap=*/false); + changeToUnreachable(BB->getFirstNonPHI(), /*UseLLVMTrap=*/false, + /*PreserveLCSSA=*/false, &DTU); + } if (!Solver.isBlockExecutable(&F.front())) NumInstRemoved += changeToUnreachable(F.front().getFirstNonPHI(), - /*UseLLVMTrap=*/false); + /*UseLLVMTrap=*/false, + /*PreserveLCSSA=*/false, &DTU); - // Now that all instructions in the function are constant folded, erase dead - // blocks, because we can now use ConstantFoldTerminator to get rid of - // in-edges. - for (unsigned i = 0, e = BlocksToErase.size(); i != e; ++i) { + // Now that all instructions in the function are constant folded, + // use ConstantFoldTerminator to get rid of in-edges, record DT updates and + // delete dead BBs. + for (BasicBlock *DeadBB : BlocksToErase) { // If there are any PHI nodes in this successor, drop entries for BB now. - BasicBlock *DeadBB = BlocksToErase[i]; for (Value::user_iterator UI = DeadBB->user_begin(), UE = DeadBB->user_end(); UI != UE;) { @@ -2060,16 +2071,16 @@ bool llvm::runIPSCCP( // If we have forced an edge for an indeterminate value, then force the // terminator to fold to that edge. forceIndeterminateEdge(I, Solver); - bool Folded = ConstantFoldTerminator(I->getParent()); + bool Folded = ConstantFoldTerminator(I->getParent(), + /*DeleteDeadConditions=*/false, + /*TLI=*/nullptr, &DTU); assert(Folded && "Expect TermInst on constantint or blockaddress to be folded"); (void) Folded; } - - // Finally, delete the basic block. - F.getBasicBlockList().erase(DeadBB); + // Mark dead BB for deletion. + DTU.deleteBB(DeadBB); } - BlocksToErase.clear(); for (BasicBlock &BB : F) { for (BasicBlock::iterator BI = BB.begin(), E = BB.end(); BI != E;) { |

