summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Scalar
diff options
context:
space:
mode:
authorFlorian Hahn <florian.hahn@arm.com>2018-11-09 11:52:27 +0000
committerFlorian Hahn <florian.hahn@arm.com>2018-11-09 11:52:27 +0000
commita1062f4b68c5a750a5b66e56753b10a3a72d7129 (patch)
treefdbd0282510dfd65eb3741d22a248a98c03e19a5 /llvm/lib/Transforms/Scalar
parent5f5bc993407cf9ec0850ce8edd14f4e129e4b46c (diff)
downloadbcm5719-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.cpp65
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;) {
OpenPOWER on IntegriCloud