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