 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
58.9% |
53 / 90 |
| Generated: |
2009-05-17 22:47 |
|
Branches Executed: |
66.7% |
60 / 90 |
| |
|
Line Coverage: |
95.6% |
86 / 90 |
| |
 |
|
 |
1 : #include "klee/Internal/Module/InstructionInfoTable.h"
2 :
3 : #include "llvm/Function.h"
4 : #include "llvm/Instructions.h"
5 : #include "llvm/IntrinsicInst.h"
6 : #include "llvm/Linker.h"
7 : #include "llvm/Module.h"
8 : #include "llvm/Assembly/AsmAnnotationWriter.h"
9 : #include "llvm/Support/CFG.h"
10 : #include "llvm/Support/InstIterator.h"
11 : #include "llvm/Support/raw_ostream.h"
12 : #include "llvm/Analysis/ValueTracking.h"
13 :
14 : #include <map>
15 : #include <iostream>
16 : #include <fstream>
17 : #include <sstream>
18 : #include <string>
19 :
20 : #include "klee/Internal/FIXME/sugar.h"
21 :
22 : using namespace llvm;
23 : using namespace klee;
24 :
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
103: branch 6 taken
25 309: class InstructionToLineAnnotator : public llvm::AssemblyAnnotationWriter {
26 : public:
27 92853: void emitInstructionAnnot(const Instruction *i, llvm::raw_ostream &os) {
28 92853: os << "%%%" << (uintptr_t) i;
29 92853: }
30 : };
31 :
32 : static void buildInstructionToLineMap(Module *m,
33 103: std::map<const Instruction*, unsigned> &out) {
34 : InstructionToLineAnnotator a;
35 103: std::ostringstream buffer;
36 103: m->print(buffer, &a);
37 103: std::string str = buffer.str();
38 : const char *s;
39 :
40 103: unsigned line = 1;
11612873: branch 0 taken
103: branch 1 taken
41 11612976: for (s=str.c_str(); *s; s++) {
124270: branch 0 taken
11488603: branch 1 taken
42 11612873: if (*s=='\n') {
43 124270: line++;
92853: branch 0 taken
31417: branch 1 taken
92853: branch 2 taken
0: branch 3 not taken
92853: branch 4 taken
0: branch 5 not taken
44 124270: if (s[1]=='%' && s[2]=='%' && s[3]=='%') {
45 92853: s += 4;
46 : char *end;
47 92853: unsigned long long value = strtoull(s, &end, 10);
92853: branch 0 taken
0: branch 1 not taken
48 92853: if (end!=s) {
49 92853: out.insert(std::make_pair((const Instruction*) value, line));
50 : }
51 92853: s = end;
52 : }
53 : }
54 103: }
55 103: }
56 :
57 1382: static std::string getDSPIPath(DbgStopPointInst *dspi) {
58 : std::string dir, file;
59 1382: bool res = GetConstantStringInfo(dspi->getDirectory(), dir);
0: branch 0 not taken
1382: branch 1 taken
60 1382: assert(res && "GetConstantStringInfo failed");
61 1382: res = GetConstantStringInfo(dspi->getFileName(), file);
0: branch 0 not taken
1382: branch 1 taken
62 1382: assert(res && "GetConstantStringInfo failed");
0: branch 0 not taken
1382: branch 1 taken
63 1382: if (dir.empty()) {
64 0: return file;
0: branch 1 not taken
1382: branch 2 taken
65 2764: } else if (*dir.rbegin() == '/') {
66 0: return dir + file;
67 : } else {
68 2764: return dir + "/" + file;
69 1382: }
70 : }
71 :
72 103: InstructionInfoTable::InstructionInfoTable(Module *m)
73 412: : dummyString(""), dummyInfo(0, dummyString, 0, 0) {
74 103: unsigned id = 0;
75 : std::map<const Instruction*, unsigned> lineTable;
76 103: buildInstructionToLineMap(m, lineTable);
77 :
1088: branch 1 taken
103: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
78 2279: foreach(fnIt, m->begin(), m->end()) {
79 1088: const std::string *initialFile = &dummyString;
80 1088: unsigned initialLine = 0;
81 :
82 : // It may be better to look for the closest stoppoint to the entry
83 : // following the CFG, but it is not clear that it ever matters in
84 : // practice.
85342: branch 3 taken
983: branch 4 taken
0: branch 8 not taken
0: branch 9 not taken
85 87413: foreach(it, inst_begin(fnIt), inst_end(fnIt)) {
105: branch 1 taken
85237: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
86 85342: if (DbgStopPointInst *dspi = dyn_cast<DbgStopPointInst>(&*it)) {
87 105: initialFile = internString(getDSPIPath(dspi));
88 105: initialLine = dspi->getLine();
89 105: break;
90 : }
91 : }
92 :
93 : std::map<BasicBlock*,
94 : std::pair<const std::string*,unsigned> > sourceInfo;
8981: branch 1 taken
1088: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
95 20138: foreach(bbIt, fnIt->begin(), fnIt->end()) {
96 26943: let(res, sourceInfo.insert(std::make_pair(bbIt,
97 : std::make_pair(initialFile,
98 : initialLine))));
8461: branch 0 taken
520: branch 1 taken
520: branch 2 taken
520: branch 3 taken
99 8981: if (!res.second)
100 8461: continue;
101 :
102 : std::vector<BasicBlock*> worklist;
103 520: worklist.push_back(bbIt);
104 :
8461: branch 0 taken
520: branch 1 taken
520: branch 2 taken
520: branch 3 taken
105 8981: do {
106 8981: BasicBlock *bb = worklist.back();
107 : worklist.pop_back();
108 :
109 : let(si, sourceInfo.find(bb));
0: branch 0 not taken
8981: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
110 8981: assert(si != sourceInfo.end());
111 8981: const std::string *file = si->second.first;
112 8981: unsigned line = si->second.second;
113 :
92853: branch 1 taken
8981: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
114 221630: foreach(it, bb->begin(), bb->end()) {
115 92853: Instruction *instr = it;
116 92853: unsigned assemblyLine = 0;
117 92853: let(ltit, lineTable.find(instr));
92853: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
118 92853: if (ltit!=lineTable.end())
119 92853: assemblyLine = ltit->second;
1277: branch 1 taken
91576: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
120 92853: if (DbgStopPointInst *dspi = dyn_cast<DbgStopPointInst>(instr)) {
121 1277: file = internString(getDSPIPath(dspi));
122 1277: line = dspi->getLine();
123 : }
124 : infos.insert(std::make_pair(instr,
125 : InstructionInfo(id++,
126 : *file,
127 : line,
128 278559: assemblyLine)));
129 : }
130 :
13337: branch 2 taken
8981: branch 3 taken
0: branch 6 not taken
0: branch 7 not taken
131 31299: foreach(it, succ_begin(bb), succ_end(bb)) {
8461: branch 1 taken
4876: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
132 40011: if (sourceInfo.insert(std::make_pair(*it,
133 : std::make_pair(file, line))).second)
134 8461: worklist.push_back(*it);
135 : }
136 : } while (!worklist.empty());
137 : }
138 : }
139 103: }
140 :
141 103: InstructionInfoTable::~InstructionInfoTable() {
76: branch 0 taken
103: branch 1 taken
103: branch 2 taken
103: branch 3 taken
142 385: foreach(it, internedStrings.begin(), internedStrings.end())
76: branch 0 taken
0: branch 1 not taken
76: branch 4 taken
76: branch 5 taken
143 76: delete *it;
144 309: }
145 :
146 1382: const std::string *InstructionInfoTable::internString(std::string s) {
147 1382: let(it, internedStrings.find(&s));
76: branch 0 taken
1306: branch 1 taken
148 2764: if (it==internedStrings.end()) {
149 76: std::string *interned = new std::string(s);
150 76: internedStrings.insert(interned);
151 76: return interned;
152 : } else {
153 1306: return *it;
154 : }
155 : }
156 :
157 103: unsigned InstructionInfoTable::getMaxID() const {
158 206: return infos.size();
159 : }
160 :
161 : const InstructionInfo &
162 205973: InstructionInfoTable::getInfo(const Instruction *inst) const {
163 205973: let(it, infos.find(inst));
0: branch 0 not taken
205973: branch 1 taken
164 411946: if (it==infos.end()) {
165 0: return dummyInfo;
166 : } else {
167 205973: return it->second;
168 : }
169 : }
170 :
171 : const InstructionInfo &
172 330: InstructionInfoTable::getFunctionInfo(const Function *f) const {
0: branch 1 not taken
330: branch 2 taken
173 330: if (f->isDeclaration()) {
174 0: return dummyInfo;
175 : } else {
176 330: return getInfo(f->begin()->begin());
177 : }
103: branch 0 taken
0: branch 1 not taken
103: branch 2 taken
0: branch 3 not taken
178 206: }
Generated: 2009-05-17 22:47 by zcov