 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
67.3% |
152 / 226 |
| Generated: |
2009-05-17 22:47 |
|
Branches Executed: |
69.0% |
156 / 226 |
| |
|
Line Coverage: |
84.8% |
190 / 224 |
| |
 |
|
 |
1 : /* -*- mode: c++; c-basic-offset: 2; -*- */
2 :
3 : // FIXME: This does not belong here.
4 : #include "../Core/Common.h"
5 :
6 : #include "klee/Internal/Module/KModule.h"
7 :
8 : #include "Passes.h"
9 :
10 : #include "klee/Interpreter.h"
11 : #include "klee/Internal/Module/Cell.h"
12 : #include "klee/Internal/Module/KInstruction.h"
13 : #include "klee/Internal/Module/InstructionInfoTable.h"
14 : #include "klee/Internal/Support/ModuleUtil.h"
15 :
16 : #include "llvm/Bitcode/ReaderWriter.h"
17 : #include "llvm/Instructions.h"
18 : #include "llvm/Module.h"
19 : #include "llvm/PassManager.h"
20 : #include "llvm/ValueSymbolTable.h"
21 : #include "llvm/Support/CommandLine.h"
22 : #include "llvm/Target/TargetData.h"
23 : #include "llvm/Transforms/Scalar.h"
24 :
25 : #include <sstream>
26 :
27 : #include "klee/Internal/FIXME/sugar.h"
28 :
29 : using namespace llvm;
30 : using namespace klee;
31 :
32 : namespace {
33 : enum SwitchImplType {
34 : eSwitchTypeSimple,
35 : eSwitchTypeLLVM,
36 : eSwitchTypeInternal
37 : };
38 :
39 : cl::list<std::string>
40 103: MergeAtExit("merge-at-exit");
41 :
42 : cl::opt<bool>
43 103: NoTruncateSourceLines("no-truncate-source-lines",
44 : cl::desc("Don't truncate long lines in the output source"));
45 :
46 : cl::opt<bool>
47 103: OutputSource("output-source",
48 : cl::desc("Write the assembly for the final transformed source"),
49 206: cl::init(true));
50 :
51 : cl::opt<bool>
52 103: OutputModule("output-module",
53 : cl::desc("Write the bitcode for the final transformed module"),
54 206: cl::init(false));
55 :
56 : cl::opt<SwitchImplType>
57 103: SwitchType("switch-type", cl::desc("Select the implementation of switch"),
58 : cl::values(clEnumValN(eSwitchTypeSimple, "simple",
59 : "lower to ordered branches"),
60 : clEnumValN(eSwitchTypeLLVM, "llvm",
61 : "lower using LLVM"),
62 : clEnumValN(eSwitchTypeInternal, "internal",
63 : "execute switch internally"),
64 : clEnumValEnd),
65 206: cl::init(eSwitchTypeInternal));
66 :
67 : cl::opt<bool>
68 103: DebugPrintEscapingFunctions("debug-print-escaping-functions",
69 : cl::desc("Print functions whose address is taken."));
70 : }
71 :
72 103: KModule::KModule(Module *_module)
73 : : module(_module),
74 : targetData(new TargetData(module)),
75 : dbgStopPointFn(0),
76 : kleeMergeFn(0),
77 : infos(0),
78 618: constantTable(0) {
79 103: }
80 :
81 103: KModule::~KModule() {
103: branch 0 taken
0: branch 1 not taken
4762: branch 2 taken
103: branch 3 taken
103: branch 5 taken
103: branch 6 taken
103: branch 7 taken
103: branch 8 taken
82 206: delete[] constantTable;
103: branch 0 taken
0: branch 1 not taken
103: branch 4 taken
103: branch 5 taken
83 103: delete infos;
84 :
520: branch 0 taken
103: branch 1 taken
103: branch 2 taken
103: branch 3 taken
85 829: foreach(it, functions.begin(), functions.end())
520: branch 0 taken
0: branch 1 not taken
520: branch 4 taken
520: branch 5 taken
86 520: delete *it;
87 :
103: branch 0 taken
0: branch 1 not taken
103: branch 3 taken
103: branch 4 taken
88 103: delete targetData;
103: branch 0 taken
0: branch 1 not taken
103: branch 4 taken
103: branch 5 taken
89 103: delete module;
90 618: }
91 :
92 : /***/
93 :
94 : namespace llvm {
95 : extern void Optimize(Module*);
96 : }
97 :
98 : // what a hack
99 : static Function *getStubFunctionForCtorList(Module *m,
100 : GlobalVariable *gv,
101 4: std::string name) {
102 : assert(!gv->isDeclaration() && !gv->hasInternalLinkage() &&
4: branch 1 taken
0: branch 2 not taken
0: branch 3 not taken
4: branch 4 taken
103 8: "do not support old LLVM style constructor/destructor lists");
104 :
105 : std::vector<const Type*> nullary;
106 :
107 : Function *fn = Function::Create(FunctionType::get(Type::VoidTy,
108 : nullary, false),
109 : GlobalVariable::InternalLinkage,
110 : name,
111 8: m);
112 8: BasicBlock *bb = BasicBlock::Create("entry", fn);
113 :
114 : // From lli:
115 : // Should be an array of '{ int, void ()* }' structs. The first value is
116 : // the init priority, which we ignore.
117 8: ConstantArray *arr = dyn_cast<ConstantArray>(gv->getInitializer());
4: branch 0 taken
0: branch 1 not taken
118 4: if (arr) {
4: branch 0 taken
4: branch 1 taken
119 16: for (unsigned i=0; i<arr->getNumOperands(); i++) {
120 4: ConstantStruct *cs = cast<ConstantStruct>(arr->getOperand(i));
0: branch 0 not taken
4: branch 1 taken
121 4: assert(cs->getNumOperands()==2 && "unexpected element in ctor initializer list");
122 :
123 4: Constant *fp = cs->getOperand(1);
4: branch 1 taken
0: branch 2 not taken
124 4: if (!fp->isNullValue()) {
0: branch 0 not taken
4: branch 1 taken
125 4: if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(fp))
126 0: fp = ce->getOperand(0);
127 :
4: branch 0 taken
0: branch 1 not taken
128 4: if (Function *f = dyn_cast<Function>(fp)) {
129 4: CallInst::Create(f, "", bb);
130 : } else {
131 0: assert(0 && "unable to get function pointer from ctor initializer list");
132 : }
133 : }
134 : }
135 : }
136 :
137 : ReturnInst::Create(bb);
138 :
139 4: return fn;
140 : }
141 :
142 103: static void injectStaticConstructorsAndDestructors(Module *m) {
143 206: GlobalVariable *ctors = m->getNamedGlobal("llvm.global_ctors");
144 206: GlobalVariable *dtors = m->getNamedGlobal("llvm.global_dtors");
145 :
2: branch 0 taken
101: branch 1 taken
146 103: if (ctors || dtors) {
147 2: Function *mainFn = m->getFunction("main");
0: branch 0 not taken
2: branch 1 taken
148 2: assert(mainFn && "unable to find main function");
149 :
2: branch 0 taken
0: branch 1 not taken
150 2: if (ctors)
151 : CallInst::Create(getStubFunctionForCtorList(m, ctors, "klee.ctor_stub"),
152 8: "", mainFn->begin()->begin());
2: branch 0 taken
0: branch 1 not taken
153 2: if (dtors) {
154 2: Function *dtorStub = getStubFunctionForCtorList(m, dtors, "klee.dtor_stub");
6: branch 1 taken
2: branch 2 taken
155 14: foreach(bbIt, mainFn->begin(), mainFn->end()) {
2: branch 1 taken
4: branch 2 taken
156 12: if (isa<ReturnInst>(bbIt->getTerminator()))
157 4: CallInst::Create(dtorStub, "", bbIt->getTerminator());
158 : }
159 : }
160 : }
161 103: }
162 :
163 309: static void forceImport(Module *m, const char *name, const Type *retType, ...) {
164 : // If module lacks an externally visible symbol for the name then we
165 : // need to create one. We have to look in the symbol table because
166 : // we want to check everything (global variables, functions, and
167 : // aliases).
168 :
169 618: Value *v = m->getValueSymbolTable().lookup(name);
170 309: GlobalValue *gv = dyn_cast_or_null<GlobalValue>(v);
171 :
4: branch 0 taken
305: branch 1 taken
0: branch 2 not taken
4: branch 3 taken
305: branch 4 taken
4: branch 5 taken
172 313: if (!gv || gv->hasInternalLinkage()) {
173 : va_list ap;
174 :
175 305: va_start(ap, retType);
176 : std::vector<const Type *> argTypes;
915: branch 0 taken
305: branch 1 taken
177 1220: while (const Type *t = va_arg(ap, const Type*))
178 : argTypes.push_back(t);
179 305: va_end(ap);
180 :
181 915: m->getOrInsertFunction(name, FunctionType::get(retType, argTypes, false));
182 : }
183 309: }
184 :
185 : // FIXME: I don't belong here (or anywhere?)
186 :
187 : #include <sys/stat.h>
188 : static const char *mostRecent(const char *a, const char *b) {
189 : struct stat a_st, b_st;
0: branch 0 not taken
103: branch 1 taken
190 103: if (stat(a, &a_st)==-1) return b;
0: branch 0 not taken
103: branch 1 taken
191 103: if (stat(b, &b_st)==-1) return a;
0: branch 0 not taken
103: branch 1 taken
192 103: return (a_st.st_mtime < b_st.st_mtime) ? b : a;
193 : }
194 :
195 : void KModule::prepare(const Interpreter::ModuleOptions &opts,
196 103: InterpreterHandler *ih) {
0: branch 0 not taken
103: branch 1 taken
197 103: if (!MergeAtExit.empty()) {
198 0: Function *mergeFn = module->getFunction("klee_merge");
0: branch 0 not taken
0: branch 1 not taken
199 0: if (!mergeFn) {
200 : mergeFn = Function::Create(FunctionType::get(Type::VoidTy,
201 : std::vector<const Type*>(), false),
202 : GlobalVariable::ExternalLinkage,
203 : "klee_merge",
204 0: module);
205 : }
206 :
0: branch 0 not taken
0: branch 1 not taken
207 0: foreach(it, MergeAtExit.begin(), MergeAtExit.end()) {
208 0: std::string &name = *it;
209 0: Function *f = module->getFunction(name);
0: branch 0 not taken
0: branch 1 not taken
210 0: if (!f) {
211 : klee_error("cannot insert merge-at-exit for: %s (cannot find)",
212 0: name.c_str());
0: branch 1 not taken
0: branch 2 not taken
213 0: } else if (f->isDeclaration()) {
214 : klee_error("cannot insert merge-at-exit for: %s (external)",
215 0: name.c_str());
216 : }
217 :
218 0: BasicBlock *exit = BasicBlock::Create("exit", f);
219 0: PHINode *result = 0;
0: branch 1 not taken
0: branch 2 not taken
220 0: if (f->getReturnType() != Type::VoidTy)
221 0: result = PHINode::Create(f->getReturnType(), "retval", exit);
222 0: CallInst::Create(mergeFn, "", exit);
223 0: ReturnInst::Create(result, exit);
224 :
225 : llvm::cerr << "KLEE: adding klee_merge at exit of: " << name << "\n";
0: branch 1 not taken
0: branch 2 not taken
226 0: foreach(bb, f->begin(), f->end()) {
0: branch 1 not taken
0: branch 2 not taken
227 0: if (&*bb != exit) {
228 0: Instruction *i = bb->getTerminator();
0: branch 0 not taken
0: branch 1 not taken
229 0: if (i->getOpcode()==Instruction::Ret) {
0: branch 0 not taken
0: branch 1 not taken
230 0: if (result) {
231 0: result->addIncoming(i->getOperand(0), bb);
232 : }
233 0: i->eraseFromParent();
234 0: BranchInst::Create(exit, bb);
235 : }
236 : }
237 : }
238 : }
239 : }
240 :
241 : // Inject checks prior to optimization... we also perform the
242 : // invariant transformations that we will end up doing later so that
243 : // optimize is seeing what is as close as possible to the final
244 : // module.
245 103: PassManager pm;
246 206: pm.add(new RaiseAsmPass());
103: branch 0 taken
0: branch 1 not taken
247 206: if (opts.CheckDivZero) pm.add(new DivCheckPass());
248 : // FIXME: This false here is to work around a bug in
249 : // IntrinsicLowering which caches values which may eventually be
250 : // deleted (via RAUW). This can be removed once LLVM fixes this
251 : // issue.
252 103: pm.add(new IntrinsicCleanerPass(*targetData, false));
253 103: pm.run(*module);
254 :
3: branch 0 taken
100: branch 1 taken
255 103: if (opts.Optimize)
256 3: Optimize(module);
257 :
258 : // Force importing functions required by intrinsic lowering. Kind of
259 : // unfortunate clutter when we don't need them but we won't know
260 : // that until after all linking and intrinsic lowering is
261 : // done. After linking and passes we just try to manually trim these
262 : // by name. We only add them if such a function doesn't exist to
263 : // avoid creating stale uses.
264 :
265 : forceImport(module, "memcpy", PointerType::getUnqual(Type::Int8Ty),
266 : PointerType::getUnqual(Type::Int8Ty),
267 : PointerType::getUnqual(Type::Int8Ty),
268 412: targetData->getIntPtrType(), (Type*) 0);
269 : forceImport(module, "memmove", PointerType::getUnqual(Type::Int8Ty),
270 : PointerType::getUnqual(Type::Int8Ty),
271 : PointerType::getUnqual(Type::Int8Ty),
272 412: targetData->getIntPtrType(), (Type*) 0);
273 : forceImport(module, "memset", PointerType::getUnqual(Type::Int8Ty),
274 : PointerType::getUnqual(Type::Int8Ty),
275 : Type::Int32Ty,
276 309: targetData->getIntPtrType(), (Type*) 0);
277 :
278 : // FIXME: Missing force import for various math functions.
279 :
280 : // FIXME: Find a way that we can test programs without requiring
281 : // this to be linked in, it makes low level debugging much more
282 : // annoying.
283 : module = linkWithLibrary(module,
284 : mostRecent(KLEE_DIR"/Release/lib/libintrinsic.bca",
285 103: KLEE_DIR"/Debug/lib/libintrinsic.bca"));
286 :
287 : // Needs to happen after linking (since ctors/dtors can be modified)
288 : // and optimization (since global optimization can rewrite lists).
289 103: injectStaticConstructorsAndDestructors(module);
290 :
291 : // Finally, run the passes that maintain invariants we expect during
292 : // interpretation. We run the intrinsic cleaner just in case we
293 : // linked in something with intrinsics but any external calls are
294 : // going to be unresolved. We really need to handle the intrinsics
295 : // directly I think?
296 103: PassManager pm3;
297 103: pm3.add(createCFGSimplificationPass());
1: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
102: branch 3 taken
298 103: switch(SwitchType) {
299 : case eSwitchTypeInternal: break;
300 2: case eSwitchTypeSimple: pm3.add(new LowerSwitchPass()); break;
301 0: case eSwitchTypeLLVM: pm3.add(createLowerSwitchPass()); break;
302 0: default: klee_error("invalid --switch-type");
303 : }
304 103: pm3.add(new IntrinsicCleanerPass(*targetData));
305 206: pm3.add(new PhiCleanerPass());
306 103: pm3.run(*module);
307 :
308 : // For cleanliness see if we can discard any of the functions we
309 : // forced to import.
310 : Function *f;
311 103: f = module->getFunction("memcpy");
103: branch 0 taken
0: branch 1 not taken
95: branch 2 taken
8: branch 3 taken
95: branch 4 taken
8: branch 5 taken
312 206: if (f && f->use_empty()) f->eraseFromParent();
313 103: f = module->getFunction("memmove");
103: branch 0 taken
0: branch 1 not taken
97: branch 2 taken
6: branch 3 taken
97: branch 4 taken
6: branch 5 taken
314 206: if (f && f->use_empty()) f->eraseFromParent();
315 103: f = module->getFunction("memset");
103: branch 0 taken
0: branch 1 not taken
94: branch 2 taken
9: branch 3 taken
94: branch 4 taken
9: branch 5 taken
316 206: if (f && f->use_empty()) f->eraseFromParent();
317 :
103: branch 0 taken
0: branch 1 not taken
318 103: if (OutputSource) {
319 206: std::ostream *os = ih->openOutputFile("assembly.ll");
103: branch 0 taken
0: branch 1 not taken
0: branch 2 not taken
103: branch 3 taken
320 206: assert(os && os->good() && "unable to open source output");
321 :
0: branch 0 not taken
103: branch 1 taken
322 103: if (NoTruncateSourceLines) {
323 0: *os << *module;
324 : } else {
325 103: bool truncated = false;
326 103: std::stringstream buffer;
327 103: buffer << *module;
328 103: std::string string = buffer.str();
329 103: const char *position = string.c_str();
330 :
331 124270: for (;;) {
332 124373: const char *end = index(position, '\n');
103: branch 0 taken
124270: branch 1 taken
333 124373: if (!end) {
334 103: *os << position;
335 : break;
336 : } else {
337 124270: unsigned count = (end - position) + 1;
120384: branch 0 taken
3886: branch 1 taken
338 124270: if (count<255) {
339 120384: os->write(position, count);
340 : } else {
341 3886: os->write(position, 254);
342 3886: *os << "\n";
343 3886: truncated = true;
344 : }
345 124270: position = end+1;
346 : }
347 : }
35: branch 0 taken
68: branch 1 taken
348 103: if (truncated)
349 103: llvm::cerr << "KLEE: truncated long lines in output source, use --no-truncate-source-lines to disable\n";
350 : }
351 :
103: branch 0 taken
0: branch 1 not taken
352 103: delete os;
353 : }
354 :
0: branch 0 not taken
103: branch 1 taken
355 103: if (OutputModule) {
356 0: std::ostream *f = ih->openOutputFile("final.bc");
357 0: WriteBitcodeToFile(module, *f);
0: branch 0 not taken
0: branch 1 not taken
358 0: delete f;
359 : }
360 :
361 103: dbgStopPointFn = module->getFunction("llvm.dbg.stoppoint");
362 103: kleeMergeFn = module->getFunction("klee_merge");
363 :
364 : /* Build shadow structures */
365 :
366 103: infos = new InstructionInfoTable(module);
367 :
1088: branch 1 taken
103: branch 2 taken
368 2485: foreach(it, module->begin(), module->end()) {
568: branch 1 taken
520: branch 2 taken
369 1088: if (it->isDeclaration())
370 568: continue;
371 :
372 520: KFunction *kf = new KFunction(it, this);
373 :
92853: branch 0 taken
520: branch 1 taken
374 93373: for (unsigned i=0; i<kf->numInstructions; ++i) {
375 92853: KInstruction *ki = kf->instructions[i];
376 92853: ki->info = &infos->getInfo(ki->inst);
377 : }
378 :
379 520: functions.push_back(kf);
380 1040: functionMap.insert(std::make_pair(it, kf));
381 : }
382 :
383 : /* Compute various interesting properties */
384 :
520: branch 0 taken
103: branch 1 taken
385 829: foreach(it, functions.begin(), functions.end()) {
386 520: KFunction *kf = *it;
22: branch 1 taken
498: branch 2 taken
387 520: if (functionEscapes(kf->function))
388 22: escapingFunctions.insert(kf->function);
389 : }
390 :
0: branch 0 not taken
103: branch 1 taken
103: branch 2 taken
103: branch 3 taken
0: branch 4 not taken
103: branch 5 taken
391 103: if (DebugPrintEscapingFunctions && !escapingFunctions.empty()) {
392 : llvm::cerr << "KLEE: escaping functions: [";
0: branch 0 not taken
0: branch 1 not taken
393 0: foreach(it, escapingFunctions.begin(), escapingFunctions.end()) {
394 0: llvm::cerr << (*it)->getName() << ", ";
395 : }
396 : llvm::cerr << "]\n";
397 103: }
398 103: }
399 :
400 35850: KConstant* KModule::getKConstant(Constant *c) {
401 35850: std::map<llvm::Constant*, KConstant*>::iterator it = constantMap.find(c);
31088: branch 0 taken
4762: branch 1 taken
402 71700: if (it != constantMap.end())
403 31088: return it->second;
404 4762: return NULL;
405 : }
406 :
407 35850: unsigned KModule::getConstantID(Constant *c, KInstruction* ki) {
408 35850: KConstant *kc = getKConstant(c);
31088: branch 0 taken
4762: branch 1 taken
409 35850: if (kc)
410 31088: return kc->id;
411 :
412 9524: unsigned id = constants.size();
413 4762: kc = new KConstant(c, id, ki);
414 9524: constantMap.insert(std::make_pair(c, kc));
415 4762: constants.push_back(c);
416 4762: return id;
417 :
418 : #if 0
419 : let(res, constantMap.insert(std::make_pair(c, constants.size())));
420 : if (res.second)
421 : constants.push_back(c);
422 : return res.first->second;
423 : #endif
424 : }
425 :
426 : /***/
427 :
428 4762: KConstant::KConstant(llvm::Constant* _ct, unsigned _id, KInstruction* _ki) {
429 4762: ct = _ct;
430 4762: id = _id;
431 4762: ki = _ki;
432 4762: }
433 :
434 : /***/
435 :
436 : KFunction::KFunction(llvm::Function *_function,
437 520: KModule *km)
438 : : function(_function),
439 : numArgs(function->arg_size()),
440 : numInstructions(0),
441 1040: trackCoverage(true) {
8981: branch 1 taken
520: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
442 19522: foreach(bbit, function->begin(), function->end()) {
443 8981: BasicBlock *bb = bbit;
444 8981: basicBlockEntry[bb] = numInstructions;
445 8981: numInstructions += bb->size();
446 : }
447 :
448 520: instructions = new KInstruction*[numInstructions];
449 :
450 : std::map<Instruction*, unsigned> registerMap;
451 :
452 : // The first arg_size() registers are reserved for formals.
453 520: unsigned rnum = numArgs;
8981: branch 1 taken
520: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
454 19522: foreach(bbit, function->begin(), function->end()) {
92853: branch 1 taken
8981: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
455 203668: foreach(it, bbit->begin(), bbit->end()) {
456 92853: registerMap[it] = rnum++;
457 : }
458 : }
459 520: numRegisters = rnum;
460 :
461 520: unsigned i = 0;
8981: branch 1 taken
520: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
462 19522: foreach(bbit, function->begin(), function->end()) {
92853: branch 1 taken
8981: branch 2 taken
0: branch 4 not taken
0: branch 5 not taken
463 203668: foreach(it, bbit->begin(), bbit->end()) {
464 : KInstruction *ki;
465 :
4061: branch 0 taken
88792: branch 1 taken
88792: branch 2 taken
88792: branch 3 taken
466 92853: switch(it->getOpcode()) {
467 : case Instruction::GetElementPtr:
468 8122: ki = new KGEPInstruction(); break;
469 : default:
470 177584: ki = new KInstruction(); break;
471 : }
472 :
473 185706: unsigned numOperands = it->getNumOperands();
474 92853: ki->inst = it;
475 92853: ki->operands = new int[numOperands];
476 92853: ki->dest = registerMap[it];
147219: branch 0 taken
92853: branch 1 taken
92853: branch 2 taken
92853: branch 3 taken
477 240072: for (unsigned j=0; j<numOperands; j++) {
478 147219: Value *v = it->getOperand(j);
479 :
96666: branch 0 taken
50553: branch 1 taken
50553: branch 2 taken
50553: branch 3 taken
480 147219: if (Instruction *inst = dyn_cast<Instruction>(v)) {
481 96666: ki->operands[j] = registerMap[inst];
1055: branch 0 taken
49498: branch 1 taken
49498: branch 2 taken
49498: branch 3 taken
482 50553: } else if (Argument *a = dyn_cast<Argument>(v)) {
483 1055: ki->operands[j] = a->getArgNo();
35850: branch 0 taken
13648: branch 1 taken
0: branch 2 not taken
35850: branch 3 taken
13648: branch 4 taken
35850: branch 5 taken
35850: branch 6 taken
35850: branch 7 taken
35850: branch 8 taken
35850: branch 9 taken
35850: branch 10 taken
35850: branch 11 taken
484 85348: } else if (isa<BasicBlock>(v) || isa<InlineAsm>(v)) {
485 13648: ki->operands[j] = -1;
486 : } else {
0: branch 0 not taken
35850: branch 1 taken
0: branch 3 not taken
0: branch 4 not taken
487 35850: assert(isa<Constant>(v));
488 35850: Constant *c = cast<Constant>(v);
489 35850: ki->operands[j] = -(km->getConstantID(c, ki) + 2);
490 : }
491 : }
492 :
493 92853: instructions[i++] = ki;
494 : }
495 : }
496 520: }
497 :
498 520: KFunction::~KFunction() {
92853: branch 0 taken
520: branch 1 taken
520: branch 2 taken
520: branch 3 taken
499 93373: for (unsigned i=0; i<numInstructions; ++i)
92853: branch 0 taken
0: branch 1 not taken
92853: branch 3 taken
92853: branch 4 taken
500 92853: delete instructions[i];
520: branch 0 taken
0: branch 1 not taken
520: branch 3 taken
520: branch 4 taken
501 520: delete[] instructions;
103: branch 0 taken
0: branch 1 not taken
103: branch 2 taken
0: branch 3 not taken
502 1349: }
Generated: 2009-05-17 22:47 by zcov