55 Low(low), High(high), BB(bb) { }
58 typedef std::vector<CaseRange> CaseVector;
59 typedef std::vector<CaseRange>::iterator CaseItr;
67 unsigned Clusterify(CaseVector& Cases,
SwitchInst *SI);
73 bool operator () (
const LowerSwitch::CaseRange& C1,
74 const LowerSwitch::CaseRange& C2) {
76 const ConstantInt* CI1 = cast<const ConstantInt>(C1.Low);
77 const ConstantInt* CI2 = cast<const ConstantInt>(C2.High);
85 "Lower SwitchInst's to branches",
false,
false)
91 return new LowerSwitch();
94 bool LowerSwitch::runOnFunction(
Function &
F) {
102 processSwitchInst(SI);
112 const LowerSwitch::CaseVector &
C)
115 const LowerSwitch::CaseVector &
C) {
118 for (LowerSwitch::CaseVector::const_iterator B = C.begin(),
119 E = C.end(); B != E; ) {
120 O << *B->Low <<
" -" << *B->High;
121 if (++B != E) O <<
", ";
130 BasicBlock* LowerSwitch::switchConvert(CaseItr Begin, CaseItr End,
134 unsigned Size = End - Begin;
137 return newLeafBlock(*Begin, Val, OrigBlock, Default);
139 unsigned Mid = Size / 2;
140 std::vector<CaseRange> LHS(Begin, Begin + Mid);
142 std::vector<CaseRange> RHS(Begin + Mid, End);
145 CaseRange& Pivot = *(Begin + Mid);
147 << cast<ConstantInt>(Pivot.Low)->getValue() <<
" -"
148 << cast<ConstantInt>(Pivot.High)->getValue() <<
"\n");
150 BasicBlock* LBranch = switchConvert(LHS.begin(), LHS.end(), Val,
152 BasicBlock* RBranch = switchConvert(RHS.begin(), RHS.end(), Val,
160 F->getBasicBlockList().insert(++FI, NewNode);
163 Val, Pivot.Low,
"Pivot");
186 if (Leaf.Low == Leaf.High) {
189 Leaf.Low,
"SwitchLeaf");
192 if (cast<ConstantInt>(Leaf.Low)->isMinValue(
true )) {
196 }
else if (cast<ConstantInt>(Leaf.Low)->isZero()) {
203 Instruction* Add = BinaryOperator::CreateAdd(Val, NegLo,
221 uint64_t Range = cast<ConstantInt>(Leaf.High)->getSExtValue() -
222 cast<ConstantInt>(Leaf.Low)->getSExtValue();
223 for (uint64_t j = 0; j < Range; ++j) {
228 assert(BlockIdx != -1 &&
"Switch didn't go to this successor??");
236 unsigned LowerSwitch::Clusterify(CaseVector& Cases,
SwitchInst *SI) {
237 unsigned numCmps = 0;
241 Cases.push_back(CaseRange(i.getCaseValue(), i.getCaseValue(),
242 i.getCaseSuccessor()));
244 std::sort(Cases.begin(), Cases.end(), CaseCmp());
248 for (CaseItr
I=Cases.begin(), J=
llvm::next(Cases.begin()); J!=Cases.end(); ) {
249 int64_t nextValue = cast<ConstantInt>(J->Low)->getSExtValue();
250 int64_t currentValue = cast<ConstantInt>(
I->High)->getSExtValue();
256 if ((nextValue-currentValue==1) && (currentBB == nextBB)) {
264 for (CaseItr
I=Cases.begin(), E=Cases.end();
I!=E; ++
I, ++numCmps) {
265 if (
I->Low !=
I->High)
276 void LowerSwitch::processSwitchInst(
SwitchInst *SI) {
302 assert(BlockIdx != -1 &&
"Switch didn't go to this successor??");
308 unsigned numCmps = Clusterify(Cases, SI);
310 DEBUG(
dbgs() <<
"Clusterify finished. Total clusters: " << Cases.size()
311 <<
". Total compares: " << numCmps <<
"\n");
312 DEBUG(
dbgs() <<
"Cases: " << Cases <<
"\n");
315 BasicBlock* SwitchBlock = switchConvert(Cases.begin(), Cases.end(), Val,
316 OrigBlock, NewDefault);
AnalysisUsage & addPreserved()
static PassRegistry * getPassRegistry()
FunctionPass * createLowerSwitchPass()
const Function * getParent() const
Return the enclosing method, or null if none.
StringRef getName() const
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
void push_back(NodeTy *val)
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
const APInt & getValue() const
Return the constant's value.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=0)
ID
LLVM Calling Convention Representation.
AnalysisUsage & addPreservedID(const void *ID)
LLVM Basic Block Representation.
LLVM Constant Representation.
ItTy next(ItTy it, Dist n)
const InstListType & getInstList() const
Return the underlying instruction list container.
Represent an integer comparison operator.
iterator insert(iterator where, NodeTy *New)
LLVMContext & getContext() const
All values hold a context through their type.
iterator erase(iterator where)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const BasicBlockListType & getBasicBlockList() const
Class for constant integers.
void setIncomingBlock(unsigned i, BasicBlock *BB)
bool slt(const APInt &RHS) const
Signed less than comparison.
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
Value * getCondition() const
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
BasicBlock * getDefaultDest() const
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=0, BasicBlock *InsertBefore=0)
Creates a new BasicBlock.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
unsigned getNumCases() const
LLVM Value Representation.
void initializeLowerSwitchPass(PassRegistry &)
int getBasicBlockIndex(const BasicBlock *BB) const
const BasicBlock * getParent() const
#define LLVM_ATTRIBUTE_USED