klee
LowerSwitch.cpp
Go to the documentation of this file.
1//===-- LowerSwitch.cpp - Eliminate Switch instructions -------------------===//
2//
3// The KLEE Symbolic Virtual Machine
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Derived from LowerSwitch.cpp in LLVM, heavily modified by piotrek
11// to get rid of the binary search transform, as it was creating
12// multiple paths through the program (i.e., extra paths that didn't
13// exist in the original program).
14//
15//===----------------------------------------------------------------------===//
16
17#include "Passes.h"
18#include "klee/Config/Version.h"
19#include "llvm/IR/IRBuilder.h"
20#include "llvm/IR/LLVMContext.h"
21#include <algorithm>
22
23using namespace llvm;
24
25namespace klee {
26
27char LowerSwitchPass::ID = 0;
28
29// The comparison function for sorting the switch case values in the vector.
33
34 const ConstantInt* CI1 = cast<const ConstantInt>(C1.value);
35 const ConstantInt* CI2 = cast<const ConstantInt>(C2.value);
36 return CI1->getValue().slt(CI2->getValue());
37 }
38};
39
41 bool changed = false;
42
43 for (Function::iterator I = F.begin(), E = F.end(); I != E; ) {
44 BasicBlock *cur = &*I;
45 I++; // Advance over block so we don't traverse new blocks
46
47 if (SwitchInst *SI = dyn_cast<SwitchInst>(cur->getTerminator())) {
48 changed = true;
50 }
51 }
52
53 return changed;
54}
55
56// switchConvert - Convert the switch statement into a linear scan
57// through all the case values
59 Value* value, BasicBlock* origBlock,
60 BasicBlock* defaultBlock)
61{
62 BasicBlock *curHead = defaultBlock;
63 Function *F = origBlock->getParent();
64 llvm::IRBuilder<> Builder(defaultBlock);
65
66 // iterate through all the cases, creating a new BasicBlock for each
67 for (CaseItr it = begin; it < end; ++it) {
68 BasicBlock *newBlock = BasicBlock::Create(F->getContext(), "NodeBlock");
69 Function::iterator FI = origBlock->getIterator();
70 F->getBasicBlockList().insert(++FI, newBlock);
71 Builder.SetInsertPoint(newBlock);
72 auto cmpValue = Builder.CreateICmpEQ(value, it->value, "case.cmp");
73 Builder.CreateCondBr(cmpValue, it->block, curHead);
74
75 // If there were any PHI nodes in this successor, rewrite one entry
76 // from origBlock to come from newBlock.
77 for (BasicBlock::iterator bi = it->block->begin(); isa<PHINode>(bi); ++bi) {
78 PHINode* PN = cast<PHINode>(bi);
79
80 int blockIndex = PN->getBasicBlockIndex(origBlock);
81 assert(blockIndex != -1 && "Switch didn't go to this successor??");
82 PN->setIncomingBlock((unsigned)blockIndex, newBlock);
83 }
84
85 curHead = newBlock;
86 }
87
88 // Branch to our shiny new if-then stuff...
89 Builder.SetInsertPoint(origBlock);
90 Builder.CreateBr(curHead);
91}
92
93// processSwitchInst - Replace the specified switch instruction with a sequence
94// of chained if-then instructions.
95//
97 BasicBlock *origBlock = SI->getParent();
98 BasicBlock *defaultBlock = SI->getDefaultDest();
99 Function *F = origBlock->getParent();
100 Value *switchValue = SI->getCondition();
101
102 // Create a new, empty default block so that the new hierarchy of
103 // if-then statements go to this and the PHI nodes are happy.
104 BasicBlock* newDefault = BasicBlock::Create(F->getContext(), "newDefault");
105 llvm::IRBuilder<> Builder(newDefault);
106
107 F->getBasicBlockList().insert(defaultBlock->getIterator(), newDefault);
108 Builder.CreateBr(defaultBlock);
109
110 // If there is an entry in any PHI nodes for the default edge, make sure
111 // to update them as well.
112 for (BasicBlock::iterator I = defaultBlock->begin(); isa<PHINode>(I); ++I) {
113 PHINode *PN = cast<PHINode>(I);
114 int BlockIdx = PN->getBasicBlockIndex(origBlock);
115 assert(BlockIdx != -1 && "Switch didn't go to this successor??");
116 PN->setIncomingBlock((unsigned)BlockIdx, newDefault);
117 }
118
119 CaseVector cases;
120
121 for (auto i : SI->cases())
122 cases.push_back(SwitchCase(i.getCaseValue(),
123 i.getCaseSuccessor()));
124
125 // reverse cases, as switchConvert constructs a chain of
126 // basic blocks by appending to the front. if we reverse,
127 // the if comparisons will happen in the same order
128 // as the cases appear in the switch
129 std::reverse(cases.begin(), cases.end());
130
131 switchConvert(cases.begin(), cases.end(), switchValue, origBlock, newDefault);
132
133 // We are now done with the switch instruction, so delete it
134 origBlock->getInstList().erase(SI);
135}
136
137}
void processSwitchInst(llvm::SwitchInst *SI)
Definition: LowerSwitch.cpp:96
std::vector< SwitchCase > CaseVector
Definition: Passes.h:143
bool runOnFunction(llvm::Function &F) override
Definition: LowerSwitch.cpp:40
static char ID
Definition: Passes.h:130
void switchConvert(CaseItr begin, CaseItr end, llvm::Value *value, llvm::BasicBlock *origBlock, llvm::BasicBlock *defaultBlock)
Definition: LowerSwitch.cpp:58
std::vector< SwitchCase >::iterator CaseItr
Definition: Passes.h:144
Definition: main.cpp:291
bool operator()(const LowerSwitchPass::SwitchCase &C1, const LowerSwitchPass::SwitchCase &C2)
Definition: LowerSwitch.cpp:31