From 16b18fdc35cec3510f48cfe01e030d23c84aca55 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 8 Oct 2003 16:55:34 +0000 Subject: [PATCH] Use a set to keep track of which edges have been noticed as executable already to avoid reprocessing PHI nodes needlessly. This speeds up the big bad PHI testcase 43%: from 104.9826 to 73.5157s git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8964 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SCCP.cpp | 42 ++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 16f8da43913..48c116d5f35 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -85,6 +85,11 @@ class SCCP : public FunctionPass, public InstVisitor { std::vector InstWorkList;// The instruction work list std::vector BBWorkList; // The BasicBlock work list + + /// KnownFeasibleEdges - Entries in this set are edges which have already had + /// PHI nodes retriggered. + typedef std::pair Edge; + std::set KnownFeasibleEdges; public: // runOnFunction - Run the Sparse Conditional Constant Propagation algorithm, @@ -153,22 +158,28 @@ private: return ValueState[V]; } - // markExecutable - Mark a basic block as executable, adding it to the BB + // markEdgeExecutable - Mark a basic block as executable, adding it to the BB // work list if it is not already executable... // - void markExecutable(BasicBlock *BB) { - if (BBExecutable.count(BB)) { - // BB is already executable, but we may have just made an edge feasible - // that wasn't before. Add the PHI nodes to the work list so that they - // can be rechecked. - for (BasicBlock::iterator I = BB->begin(); + void markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) { + if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second) + return; // This edge is already known to be executable! + + if (BBExecutable.count(Dest)) { + DEBUG(std::cerr << "Marking Edge Executable: " << Source->getName() + << " -> " << Dest->getName() << "\n"); + + // The destination is already executable, but we just made an edge + // feasible that wasn't before. Add the PHI nodes to the work list so + // that they can be rechecked. + for (BasicBlock::iterator I = Dest->begin(); PHINode *PN = dyn_cast(I); ++I) visitPHINode(*PN); } else { - DEBUG(std::cerr << "Marking BB Executable: " << *BB); - BBExecutable.insert(BB); // Basic block is executable! - BBWorkList.push_back(BB); // Add the block to the work list! + DEBUG(std::cerr << "Marking Block Executable: " << Dest->getName()<<"\n"); + BBExecutable.insert(Dest); // Basic block is executable! + BBWorkList.push_back(Dest); // Add the block to the work list! } } @@ -249,7 +260,8 @@ Pass *createSCCPPass() { // bool SCCP::runOnFunction(Function &F) { // Mark the first block of the function as being executable... - markExecutable(&F.front()); + BBExecutable.insert(F.begin()); // Basic block is executable! + BBWorkList.push_back(F.begin()); // Add the block to the work list! // Process the work lists until their are empty! while (!BBWorkList.empty() || !InstWorkList.empty()) { @@ -494,12 +506,12 @@ void SCCP::visitTerminatorInst(TerminatorInst &TI) { std::vector SuccFeasible; getFeasibleSuccessors(TI, SuccFeasible); + BasicBlock *BB = TI.getParent(); + // Mark all feasible successors executable... for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i) - if (SuccFeasible[i]) { - BasicBlock *Succ = TI.getSuccessor(i); - markExecutable(Succ); - } + if (SuccFeasible[i]) + markEdgeExecutable(BB, TI.getSuccessor(i)); } void SCCP::visitCastInst(CastInst &I) {