 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
85.7% |
30 / 35 |
| Generated: |
2009-05-17 22:47 |
|
Branches Executed: |
100.0% |
35 / 35 |
| |
|
Line Coverage: |
97.6% |
41 / 42 |
| |
 |
|
 |
1 : /* -*- mode: c++; c-basic-offset: 2; -*- */
2 :
3 : #include "Passes.h"
4 :
5 : #include "llvm/Constants.h"
6 : #include "llvm/DerivedTypes.h"
7 : #include "llvm/Function.h"
8 : #include "llvm/InstrTypes.h"
9 : #include "llvm/Instruction.h"
10 : #include "llvm/Instructions.h"
11 : #include "llvm/IntrinsicInst.h"
12 : #include "llvm/Module.h"
13 : #include "llvm/Pass.h"
14 : #include "llvm/Type.h"
15 : #include "llvm/Transforms/Scalar.h"
16 : #include "llvm/Transforms/Utils/BasicBlockUtils.h"
17 : #include "llvm/Target/TargetData.h"
18 :
19 : using namespace llvm;
20 :
21 : namespace klee {
22 :
23 : char IntrinsicCleanerPass::ID;
24 :
25 206: bool IntrinsicCleanerPass::runOnModule(Module &M) {
26 206: bool dirty = false;
2319: branch 1 taken
206: branch 2 taken
27 4844: for (Module::iterator f = M.begin(), fe = M.end(); f != fe; ++f)
20817: branch 1 taken
2319: branch 2 taken
28 46272: for (Function::iterator b = f->begin(), be = f->end(); b != be; ++b)
29 20817: dirty |= runOnBasicBlock(*b);
30 206: return dirty;
31 : }
32 :
33 20817: bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b) {
34 20817: bool dirty = false;
35 :
195215: branch 0 taken
20817: branch 1 taken
36 216032: for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie;) {
37 390430: IntrinsicInst *ii = dyn_cast<IntrinsicInst>(&*i);
38 : // increment now since LowerIntrinsic deletion makes iterator invalid.
39 195215: ++i;
4400: branch 0 taken
190815: branch 1 taken
40 195215: if(ii) {
2: branch 1 taken
3552: branch 2 taken
714: branch 3 taken
120: branch 4 taken
12: branch 5 taken
41 4400: switch (ii->getIntrinsicID()) {
42 : case Intrinsic::vastart:
43 : case Intrinsic::vaend:
44 : break;
45 :
46 : // Lower vacopy so that object resolution etc is handled by
47 : // normal instructions. FIXME: This is broken for non-x86_32.
48 : case Intrinsic::vacopy: { // (dst, src) -> *((i8**) dst) = *((i8**) src)
49 2: Value *dst = ii->getOperand(1);
50 2: Value *src = ii->getOperand(2);
51 6: Type *i8pp = PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty));
52 4: Value *castedDst = CastInst::CreatePointerCast(dst, i8pp, "vacopy.cast.dst", ii);
53 4: Value *castedSrc = CastInst::CreatePointerCast(src, i8pp, "vacopy.cast.src", ii);
54 2: Value *load = new LoadInst(castedSrc, "vacopy.read", ii);
55 2: new StoreInst(load, castedDst, false, ii);
56 2: ii->removeFromParent();
2: branch 0 taken
0: branch 1 not taken
57 2: delete ii;
58 : break;
59 : }
60 :
61 : case Intrinsic::dbg_stoppoint: {
62 : // We can remove this stoppoint if the next instruction is
63 : // sure to be another stoppoint. This is nice for cleanliness
64 : // but also important for switch statements where it can allow
65 : // the targets to be joined.
66 3552: bool erase = false;
3552: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
3552: branch 3 taken
0: branch 4 not taken
3552: branch 5 taken
67 7104: if (isa<DbgStopPointInst>(i) ||
68 : isa<UnreachableInst>(i)) {
69 0: erase = true;
2929: branch 0 taken
623: branch 1 taken
0: branch 2 not taken
2929: branch 3 taken
623: branch 4 taken
2929: branch 5 taken
70 6481: } else if (isa<BranchInst>(i) ||
71 : isa<SwitchInst>(i)) {
72 623: BasicBlock *bb = i->getParent();
73 623: erase = true;
635: branch 0 taken
600: branch 1 taken
74 1235: for (succ_iterator it=succ_begin(bb), ie=succ_end(bb);
75 : it!=ie; ++it) {
23: branch 1 taken
612: branch 2 taken
76 1270: if (!isa<DbgStopPointInst>(it->getFirstNonPHI())) {
77 23: erase = false;
78 23: break;
79 : }
80 : }
81 : }
82 :
600: branch 0 taken
2952: branch 1 taken
83 3552: if (erase) {
84 600: ii->eraseFromParent();
85 600: dirty = true;
86 : }
87 : break;
88 : }
89 :
90 : case Intrinsic::dbg_region_start:
91 : case Intrinsic::dbg_region_end:
92 : case Intrinsic::dbg_func_start:
93 : case Intrinsic::dbg_declare:
94 : // Remove these regardless of lower intrinsics flag. This can
95 : // be removed once IntrinsicLowering is fixed to not have bad
96 : // caches.
97 714: ii->eraseFromParent();
98 714: dirty = true;
99 714: break;
100 :
101 : default:
61: branch 0 taken
59: branch 1 taken
102 120: if (LowerIntrinsics)
103 61: IL->LowerIntrinsicCall(ii);
104 120: dirty = true;
105 : break;
106 : }
107 : }
108 : }
109 :
110 20817: return dirty;
111 : }
112 : }
Generated: 2009-05-17 22:47 by zcov