 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
90.9% |
20 / 22 |
| Generated: |
2009-05-17 22:47 |
|
Branches Executed: |
100.0% |
22 / 22 |
| |
|
Line Coverage: |
92.9% |
26 / 28 |
| |
 |
|
 |
1 : #include "Passes.h"
2 :
3 : #include <set>
4 :
5 : using namespace llvm;
6 :
7 : char klee::PhiCleanerPass::ID = 0;
8 :
9 806: bool klee::PhiCleanerPass::runOnFunction(Function &f) {
10 806: bool changed = false;
11 :
10227: branch 1 taken
806: branch 2 taken
12 21260: for (Function::iterator b = f.begin(), be = f.end(); b != be; ++b) {
13 : BasicBlock::iterator it = b->begin();
14 :
470: branch 0 taken
9757: branch 1 taken
15 10227: if (it->getOpcode() == Instruction::PHI) {
16 470: PHINode *reference = cast<PHINode>(it);
17 :
18 : std::set<Value*> phis;
19 470: phis.insert(reference);
20 :
21 470: unsigned numBlocks = reference->getNumIncomingValues();
50: branch 3 taken
470: branch 4 taken
22 1040: for (++it; isa<PHINode>(*it); ++it) {
23 50: PHINode *pi = cast<PHINode>(it);
24 :
0: branch 0 not taken
50: branch 1 taken
25 50: assert(numBlocks == pi->getNumIncomingValues());
26 :
27 : // see if it is out of order
28 : unsigned i;
115: branch 0 taken
49: branch 1 taken
29 164: for (i=0; i<numBlocks; i++)
1: branch 0 taken
114: branch 1 taken
30 115: if (pi->getIncomingBlock(i) != reference->getIncomingBlock(i))
31 1: break;
32 :
1: branch 0 taken
49: branch 1 taken
33 50: if (i!=numBlocks) {
34 : std::vector<Value*> values;
35 1: values.reserve(numBlocks);
2: branch 0 taken
1: branch 1 taken
36 3: for (unsigned i=0; i<numBlocks; i++)
37 2: values[i] = pi->getIncomingValueForBlock(reference->getIncomingBlock(i));
2: branch 0 taken
1: branch 1 taken
38 3: for (unsigned i=0; i<numBlocks; i++) {
39 : pi->setIncomingBlock(i, reference->getIncomingBlock(i));
40 2: pi->setIncomingValue(i, values[i]);
41 : }
42 1: changed = true;
43 : }
44 :
45 : // see if it uses any previously defined phi nodes
116: branch 0 taken
50: branch 1 taken
46 166: for (i=0; i<numBlocks; i++) {
47 116: Value *value = pi->getIncomingValue(i);
48 :
0: branch 0 not taken
116: branch 1 taken
49 116: if (phis.find(value) != phis.end()) {
50 : // fix by making a "move" at the end of the incoming block
51 : // to a new temporary, which is thus known not to be a phi
52 : // result. we could be somewhat more efficient about this
53 : // by sharing temps and by reordering phi instructions so
54 : // this isn't completely necessary, but in the end this is
55 : // just a pathological case which does not occur very
56 : // often.
57 : Instruction *tmp =
58 : new BitCastInst(value,
59 : value->getType(),
60 : value->getName() + ".phiclean",
61 0: pi->getIncomingBlock(i)->getTerminator());
62 0: pi->setIncomingValue(i, tmp);
63 : }
64 :
65 116: changed = true;
66 : }
67 :
68 50: phis.insert(pi);
69 : }
70 : }
71 : }
72 :
73 806: return changed;
74 : }
Generated: 2009-05-17 22:47 by zcov