| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 1 | //===- LowerSwitch.cpp - Eliminate Switch instructions --------------------===// | 
| John Criswell | 482202a | 2003-10-20 19:43:21 +0000 | [diff] [blame] | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file was developed by the LLVM research group and is distributed under | 
|  | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 9 | // | 
|  | 10 | // The LowerSwitch transformation rewrites switch statements with a sequence of | 
|  | 11 | // branches, which allows targets to get away with not implementing the switch | 
|  | 12 | // statement until it is convenient. | 
|  | 13 | // | 
|  | 14 | //===----------------------------------------------------------------------===// | 
|  | 15 |  | 
|  | 16 | #include "llvm/Transforms/Scalar.h" | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 17 | #include "llvm/Constants.h" | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 18 | #include "llvm/Function.h" | 
| Misha Brukman | 2b3387a | 2004-07-29 17:05:13 +0000 | [diff] [blame] | 19 | #include "llvm/Instructions.h" | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 20 | #include "llvm/Pass.h" | 
| Reid Spencer | 7c16caa | 2004-09-01 22:55:40 +0000 | [diff] [blame] | 21 | #include "llvm/Support/Debug.h" | 
|  | 22 | #include "llvm/ADT/Statistic.h" | 
| Alkis Evlogimenos | a5c04ee | 2004-09-03 18:19:51 +0000 | [diff] [blame] | 23 | #include <algorithm> | 
| Chris Lattner | 49525f8 | 2004-01-09 06:02:20 +0000 | [diff] [blame] | 24 | using namespace llvm; | 
| Brian Gaeke | 960707c | 2003-11-11 22:41:34 +0000 | [diff] [blame] | 25 |  | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 26 | namespace { | 
|  | 27 | Statistic<> NumLowered("lowerswitch", "Number of SwitchInst's replaced"); | 
|  | 28 |  | 
|  | 29 | /// LowerSwitch Pass - Replace all SwitchInst instructions with chained branch | 
|  | 30 | /// instructions.  Note that this cannot be a BasicBlock pass because it | 
|  | 31 | /// modifies the CFG! | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 32 | class LowerSwitch : public FunctionPass { | 
|  | 33 | public: | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 34 | bool runOnFunction(Function &F); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 35 | typedef std::pair<Constant*, BasicBlock*> Case; | 
|  | 36 | typedef std::vector<Case>::iterator       CaseItr; | 
|  | 37 | private: | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 38 | void processSwitchInst(SwitchInst *SI); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 39 |  | 
|  | 40 | BasicBlock* switchConvert(CaseItr Begin, CaseItr End, Value* Val, | 
|  | 41 | BasicBlock* OrigBlock, BasicBlock* Default); | 
|  | 42 | BasicBlock* newLeafBlock(Case& Leaf, Value* Val, | 
|  | 43 | BasicBlock* OrigBlock, BasicBlock* Default); | 
|  | 44 | }; | 
|  | 45 |  | 
|  | 46 | /// The comparison function for sorting the switch case values in the vector. | 
|  | 47 | struct CaseCmp { | 
|  | 48 | bool operator () (const LowerSwitch::Case& C1, | 
|  | 49 | const LowerSwitch::Case& C2) { | 
|  | 50 | if (const ConstantUInt* U1 = dyn_cast<const ConstantUInt>(C1.first)) | 
|  | 51 | return U1->getValue() < cast<const ConstantUInt>(C2.first)->getValue(); | 
|  | 52 |  | 
|  | 53 | const ConstantSInt* S1 = dyn_cast<const ConstantSInt>(C1.first); | 
|  | 54 | return S1->getValue() < cast<const ConstantSInt>(C2.first)->getValue(); | 
|  | 55 | } | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 56 | }; | 
|  | 57 |  | 
|  | 58 | RegisterOpt<LowerSwitch> | 
|  | 59 | X("lowerswitch", "Lower SwitchInst's to branches"); | 
|  | 60 | } | 
|  | 61 |  | 
|  | 62 | // createLowerSwitchPass - Interface to this file... | 
| Chris Lattner | 49525f8 | 2004-01-09 06:02:20 +0000 | [diff] [blame] | 63 | FunctionPass *llvm::createLowerSwitchPass() { | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 64 | return new LowerSwitch(); | 
|  | 65 | } | 
|  | 66 |  | 
|  | 67 | bool LowerSwitch::runOnFunction(Function &F) { | 
|  | 68 | bool Changed = false; | 
|  | 69 |  | 
|  | 70 | for (Function::iterator I = F.begin(), E = F.end(); I != E; ) { | 
|  | 71 | BasicBlock *Cur = I++; // Advance over block so we don't traverse new blocks | 
|  | 72 |  | 
|  | 73 | if (SwitchInst *SI = dyn_cast<SwitchInst>(Cur->getTerminator())) { | 
|  | 74 | Changed = true; | 
|  | 75 | processSwitchInst(SI); | 
|  | 76 | } | 
|  | 77 | } | 
|  | 78 |  | 
|  | 79 | return Changed; | 
|  | 80 | } | 
|  | 81 |  | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 82 | // operator<< - Used for debugging purposes. | 
|  | 83 | // | 
| Chris Lattner | 49525f8 | 2004-01-09 06:02:20 +0000 | [diff] [blame] | 84 | std::ostream& operator<<(std::ostream &O, | 
|  | 85 | const std::vector<LowerSwitch::Case> &C) { | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 86 | O << "["; | 
|  | 87 |  | 
| Chris Lattner | 49525f8 | 2004-01-09 06:02:20 +0000 | [diff] [blame] | 88 | for (std::vector<LowerSwitch::Case>::const_iterator B = C.begin(), | 
|  | 89 | E = C.end(); B != E; ) { | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 90 | O << *B->first; | 
|  | 91 | if (++B != E) O << ", "; | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | return O << "]"; | 
|  | 95 | } | 
|  | 96 |  | 
|  | 97 | // switchConvert - Convert the switch statement into a binary lookup of | 
|  | 98 | // the case values. The function recursively builds this tree. | 
|  | 99 | // | 
|  | 100 | BasicBlock* LowerSwitch::switchConvert(CaseItr Begin, CaseItr End, | 
|  | 101 | Value* Val, BasicBlock* OrigBlock, | 
|  | 102 | BasicBlock* Default) | 
|  | 103 | { | 
|  | 104 | unsigned Size = End - Begin; | 
|  | 105 |  | 
|  | 106 | if (Size == 1) | 
|  | 107 | return newLeafBlock(*Begin, Val, OrigBlock, Default); | 
|  | 108 |  | 
|  | 109 | unsigned Mid = Size / 2; | 
|  | 110 | std::vector<Case> LHS(Begin, Begin + Mid); | 
|  | 111 | DEBUG(std::cerr << "LHS: " << LHS << "\n"); | 
|  | 112 | std::vector<Case> RHS(Begin + Mid, End); | 
|  | 113 | DEBUG(std::cerr << "RHS: " << RHS << "\n"); | 
|  | 114 |  | 
|  | 115 | Case& Pivot = *(Begin + Mid); | 
|  | 116 | DEBUG(std::cerr << "Pivot ==> " | 
| Chris Lattner | 9c6833c | 2004-02-25 15:15:04 +0000 | [diff] [blame] | 117 | << (int64_t)cast<ConstantInt>(Pivot.first)->getRawValue() | 
|  | 118 | << "\n"); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 119 |  | 
|  | 120 | BasicBlock* LBranch = switchConvert(LHS.begin(), LHS.end(), Val, | 
|  | 121 | OrigBlock, Default); | 
|  | 122 | BasicBlock* RBranch = switchConvert(RHS.begin(), RHS.end(), Val, | 
|  | 123 | OrigBlock, Default); | 
|  | 124 |  | 
|  | 125 | // Create a new node that checks if the value is < pivot. Go to the | 
|  | 126 | // left branch if it is and right branch if not. | 
|  | 127 | Function* F = OrigBlock->getParent(); | 
|  | 128 | BasicBlock* NewNode = new BasicBlock("NodeBlock"); | 
|  | 129 | F->getBasicBlockList().insert(OrigBlock->getNext(), NewNode); | 
|  | 130 |  | 
|  | 131 | SetCondInst* Comp = new SetCondInst(Instruction::SetLT, Val, Pivot.first, | 
|  | 132 | "Pivot"); | 
|  | 133 | NewNode->getInstList().push_back(Comp); | 
| Chris Lattner | 2af5172 | 2003-11-20 18:25:24 +0000 | [diff] [blame] | 134 | new BranchInst(LBranch, RBranch, Comp, NewNode); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 135 | return NewNode; | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | // newLeafBlock - Create a new leaf block for the binary lookup tree. It | 
|  | 139 | // checks if the switch's value == the case's value. If not, then it | 
|  | 140 | // jumps to the default branch. At this point in the tree, the value | 
|  | 141 | // can't be another valid case value, so the jump to the "default" branch | 
|  | 142 | // is warranted. | 
|  | 143 | // | 
|  | 144 | BasicBlock* LowerSwitch::newLeafBlock(Case& Leaf, Value* Val, | 
|  | 145 | BasicBlock* OrigBlock, | 
|  | 146 | BasicBlock* Default) | 
|  | 147 | { | 
|  | 148 | Function* F = OrigBlock->getParent(); | 
|  | 149 | BasicBlock* NewLeaf = new BasicBlock("LeafBlock"); | 
|  | 150 | F->getBasicBlockList().insert(OrigBlock->getNext(), NewLeaf); | 
|  | 151 |  | 
|  | 152 | // Make the seteq instruction... | 
|  | 153 | SetCondInst* Comp = new SetCondInst(Instruction::SetEQ, Val, | 
|  | 154 | Leaf.first, "SwitchLeaf"); | 
|  | 155 | NewLeaf->getInstList().push_back(Comp); | 
|  | 156 |  | 
|  | 157 | // Make the conditional branch... | 
|  | 158 | BasicBlock* Succ = Leaf.second; | 
| Chris Lattner | 2af5172 | 2003-11-20 18:25:24 +0000 | [diff] [blame] | 159 | new BranchInst(Succ, Default, Comp, NewLeaf); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 160 |  | 
|  | 161 | // If there were any PHI nodes in this successor, rewrite one entry | 
|  | 162 | // from OrigBlock to come from NewLeaf. | 
| Reid Spencer | 6614946 | 2004-09-15 17:06:42 +0000 | [diff] [blame] | 163 | for (BasicBlock::iterator I = Succ->begin(); isa<PHINode>(I); ++I) { | 
|  | 164 | PHINode* PN = cast<PHINode>(I); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 165 | int BlockIdx = PN->getBasicBlockIndex(OrigBlock); | 
|  | 166 | assert(BlockIdx != -1 && "Switch didn't go to this successor??"); | 
|  | 167 | PN->setIncomingBlock((unsigned)BlockIdx, NewLeaf); | 
|  | 168 | } | 
|  | 169 |  | 
|  | 170 | return NewLeaf; | 
|  | 171 | } | 
|  | 172 |  | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 173 | // processSwitchInst - Replace the specified switch instruction with a sequence | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 174 | // of chained if-then insts in a balanced binary search. | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 175 | // | 
|  | 176 | void LowerSwitch::processSwitchInst(SwitchInst *SI) { | 
|  | 177 | BasicBlock *CurBlock = SI->getParent(); | 
|  | 178 | BasicBlock *OrigBlock = CurBlock; | 
|  | 179 | Function *F = CurBlock->getParent(); | 
|  | 180 | Value *Val = SI->getOperand(0);  // The value we are switching on... | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 181 | BasicBlock* Default = SI->getDefaultDest(); | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 182 |  | 
| Chris Lattner | f1b1c5e | 2003-08-23 22:54:34 +0000 | [diff] [blame] | 183 | // If there is only the default destination, don't bother with the code below. | 
|  | 184 | if (SI->getNumOperands() == 2) { | 
| Chris Lattner | a296000 | 2003-11-21 16:52:05 +0000 | [diff] [blame] | 185 | new BranchInst(SI->getDefaultDest(), CurBlock); | 
| Chris Lattner | b686595 | 2004-03-14 04:14:31 +0000 | [diff] [blame] | 186 | CurBlock->getInstList().erase(SI); | 
| Chris Lattner | f1b1c5e | 2003-08-23 22:54:34 +0000 | [diff] [blame] | 187 | return; | 
|  | 188 | } | 
|  | 189 |  | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 190 | // Create a new, empty default block so that the new hierarchy of | 
|  | 191 | // if-then statements go to this and the PHI nodes are happy. | 
|  | 192 | BasicBlock* NewDefault = new BasicBlock("NewDefault"); | 
|  | 193 | F->getBasicBlockList().insert(Default, NewDefault); | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 194 |  | 
| Chris Lattner | a296000 | 2003-11-21 16:52:05 +0000 | [diff] [blame] | 195 | new BranchInst(Default, NewDefault); | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 196 |  | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 197 | // If there is an entry in any PHI nodes for the default edge, make sure | 
|  | 198 | // to update them as well. | 
| Reid Spencer | 6614946 | 2004-09-15 17:06:42 +0000 | [diff] [blame] | 199 | for (BasicBlock::iterator I = Default->begin(); isa<PHINode>(I); ++I) { | 
|  | 200 | PHINode *PN = cast<PHINode>(I); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 201 | int BlockIdx = PN->getBasicBlockIndex(OrigBlock); | 
|  | 202 | assert(BlockIdx != -1 && "Switch didn't go to this successor??"); | 
|  | 203 | PN->setIncomingBlock((unsigned)BlockIdx, NewDefault); | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 204 | } | 
|  | 205 |  | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 206 | std::vector<Case> Cases; | 
|  | 207 |  | 
|  | 208 | // Expand comparisons for all of the non-default cases... | 
|  | 209 | for (unsigned i = 1; i < SI->getNumSuccessors(); ++i) | 
|  | 210 | Cases.push_back(Case(SI->getSuccessorValue(i), SI->getSuccessor(i))); | 
|  | 211 |  | 
|  | 212 | std::sort(Cases.begin(), Cases.end(), CaseCmp()); | 
|  | 213 | DEBUG(std::cerr << "Cases: " << Cases << "\n"); | 
|  | 214 | BasicBlock* SwitchBlock = switchConvert(Cases.begin(), Cases.end(), Val, | 
|  | 215 | OrigBlock, NewDefault); | 
|  | 216 |  | 
|  | 217 | // Branch to our shiny new if-then stuff... | 
| Chris Lattner | a296000 | 2003-11-21 16:52:05 +0000 | [diff] [blame] | 218 | new BranchInst(SwitchBlock, OrigBlock); | 
| Chris Lattner | ed92216 | 2003-10-07 18:46:23 +0000 | [diff] [blame] | 219 |  | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 220 | // We are now done with the switch instruction, delete it. | 
| Chris Lattner | b686595 | 2004-03-14 04:14:31 +0000 | [diff] [blame] | 221 | CurBlock->getInstList().erase(SI); | 
| Chris Lattner | 1b094a0 | 2003-04-23 16:23:59 +0000 | [diff] [blame] | 222 | } |