From d52c261cf801331bebda9711acd54c7c5377a6bd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 24 Feb 2004 07:23:58 +0000 Subject: [PATCH] Implement SimplifyCFG/switch_switch_fold.ll This case occurs many times in various benchmarks, especially when combined with the previous patch. This allows it to get stuff like: if (X == 4 || X == 3) if (X == 5 || X == 8) and switch (X) { case 4: case 5: case 6: if (X == 4 || X == 5) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11797 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Utils/SimplifyCFG.cpp | 152 ++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-) diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp index c4702b6af72..15124003d24 100644 --- a/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/lib/Transforms/Utils/SimplifyCFG.cpp @@ -18,6 +18,7 @@ #include "llvm/Support/CFG.h" #include #include +#include using namespace llvm; // PropagatePredecessorsForPHIs - This gets "Succ" ready to have the @@ -286,6 +287,47 @@ static void ErasePossiblyDeadInstructionTree(Instruction *I) { } } +/// SafeToMergeTerminators - Return true if it is safe to merge these two +/// terminator instructions together. +/// +static bool SafeToMergeTerminators(TerminatorInst *SI1, TerminatorInst *SI2) { + if (SI1 == SI2) return false; // Can't merge with self! + + // It is not safe to merge these two switch instructions if they have a common + // successor, and if that successor has a PHI node, and if that PHI node has + // conflicting incoming values from the two switch blocks. + BasicBlock *SI1BB = SI1->getParent(); + BasicBlock *SI2BB = SI2->getParent(); + std::set SI1Succs(succ_begin(SI1BB), succ_end(SI1BB)); + + for (succ_iterator I = succ_begin(SI2BB), E = succ_end(SI2BB); I != E; ++I) + if (SI1Succs.count(*I)) + for (BasicBlock::iterator BBI = (*I)->begin(); + PHINode *PN = dyn_cast(BBI); ++BBI) + if (PN->getIncomingValueForBlock(SI1BB) != + PN->getIncomingValueForBlock(SI2BB)) + return false; + + return true; +} + +/// AddPredecessorToBlock - Update PHI nodes in Succ to indicate that there will +/// now be entries in it from the 'NewPred' block. The values that will be +/// flowing into the PHI nodes will be the same as those coming in from +/// ExistPred, and existing predecessor of Succ. +static void AddPredecessorToBlock(BasicBlock *Succ, BasicBlock *NewPred, + BasicBlock *ExistPred) { + assert(std::find(succ_begin(ExistPred), succ_end(ExistPred), Succ) != + succ_end(ExistPred) && "ExistPred is not a predecessor of Succ!"); + if (!isa(Succ->begin())) return; // Quick exit if nothing to do + + for (BasicBlock::iterator I = Succ->begin(); + PHINode *PN = dyn_cast(I); ++I) { + Value *V = PN->getIncomingValueForBlock(ExistPred); + PN->addIncoming(V, NewPred); + } +} + // SimplifyCFG - This function is used to do simplification of a CFG. For // example, it adjusts branches to branches to eliminate the extra hop, it // eliminates unreachable basic blocks, and does other "peephole" optimization @@ -302,7 +344,8 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { assert(&BB->getParent()->front() != BB && "Can't Simplify entry block!"); // Remove basic blocks that have no predecessors... which are unreachable. - if (pred_begin(BB) == pred_end(BB)) { + if (pred_begin(BB) == pred_end(BB) || + *pred_begin(BB) == BB && ++pred_begin(BB) == pred_end(BB)) { //cerr << "Removing BB: \n" << BB; // Loop through all of our successors and make sure they know that one @@ -439,7 +482,6 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { // We know there are no successors, so just nuke the block. M->getBasicBlockList().erase(BB); - return true; } } @@ -470,6 +512,112 @@ bool llvm::SimplifyCFG(BasicBlock *BB) { Preds.pop_back(); } + } else if (SwitchInst *SI = dyn_cast(BB->begin())) { + // If the only instruction in this block is a switch instruction, see if we + // can fold the switch instruction into a switch in a predecessor block. + std::vector Preds(pred_begin(BB), pred_end(BB)); + while (!Preds.empty()) { + BasicBlock *Pred = Preds.back(); + Preds.pop_back(); + + // If the two blocks are switching on the same value, we can merge this + // switch into the predecessor's switch. + if (SwitchInst *PSI = dyn_cast(Pred->getTerminator())) + if (PSI->getCondition() == SI->getCondition() && + SafeToMergeTerminators(SI, PSI)) { + // Figure out which 'cases' to copy from SI to PSI. + std::vector > Cases; + BasicBlock *NewDefault = 0; + if (PSI->getDefaultDest() == BB) { + // If this is the default destination from PSI, only the edges in SI + // that don't occur in PSI, or that branch to BB will be activated. + std::set PSIHandled; + for (unsigned i = 1, e = PSI->getNumSuccessors(); i != e; ++i) + if (PSI->getSuccessor(i) != BB) + PSIHandled.insert(PSI->getCaseValue(i)); + else { + // This entry will be replaced. + PSI->removeCase(i); + --i; --e; + } + + NewDefault = SI->getDefaultDest(); + for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) { + Constant *C = SI->getCaseValue(i); + if (!PSIHandled.count(C)) + Cases.push_back(std::make_pair(C, SI->getSuccessor(i))); + } + + } else { + // If this is not the default destination from PSI, only the edges + // in SI that occur in PSI with a destination of BB will be + // activated. + std::set PSIHandled; + for (unsigned i = 1, e = PSI->getNumSuccessors(); i != e; ++i) + if (PSI->getSuccessor(i) == BB) { + // We know that BB doesn't have any PHI nodes in it, so just + // drop the edges. + PSIHandled.insert(PSI->getCaseValue(i)); + PSI->removeCase(i); + --i; --e; + } + + // Okay, now we know which constants were sent to BB from the + // predecessor. Figure out where they will all go now. + for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) { + Constant *C = SI->getCaseValue(i); + if (PSIHandled.count(C)) { + // If this is one we are capable of getting... + Cases.push_back(std::make_pair(C, SI->getSuccessor(i))); + PSIHandled.erase(C); // This constant is taken care of + } + } + + // If there are any constants vectored to BB that SI doesn't handle, + // they must go to the default destination of SI. + for (std::set::iterator I = PSIHandled.begin(), + E = PSIHandled.end(); I != E; ++I) + Cases.push_back(std::make_pair(*I, SI->getDefaultDest())); + } + + // Okay, at this point, we know which cases need to be added to the + // PSI switch and which destinations they go to. If PSI needs its + // default destination changed, NewDefault is set. Start changing + // stuff now. + if (NewDefault) { + AddPredecessorToBlock(NewDefault, Pred, BB); + PSI->setSuccessor(0, NewDefault); + } + + // Okay, add all of the cases now. + for (unsigned i = 0, e = Cases.size(); i != e; ++i) { + AddPredecessorToBlock(Cases[i].second, Pred, BB); + PSI->addCase(Cases[i].first, Cases[i].second); + } + + // Okay, last check. If BB is still a successor of PSI, then we must + // have an infinite loop case. If so, add an infinitely looping block + // to handle the case to preserve the behavior of the code. + BasicBlock *InfLoopBlock = 0; + for (unsigned i = 0, e = PSI->getNumSuccessors(); i != e; ++i) + if (PSI->getSuccessor(i) == BB) { + if (InfLoopBlock == 0) { + // Insert it at the end of the loop, because it's either code, + // or it won't matter if it's hot. :) + InfLoopBlock = new BasicBlock("infloop", BB->getParent()); + new BranchInst(InfLoopBlock, InfLoopBlock); + } + PSI->setSuccessor(i, InfLoopBlock); + } + + Changed = true; + } + } + + // If we removed all predecessors of this block, recursively call + // SimplifyCFG to remove it. + if (pred_begin(BB) == pred_end(BB)) + return SimplifyCFG(BB); } // Merge basic blocks into their predecessor if there is only one distinct