klee
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
CallPathManager.cpp
Go to the documentation of this file.
1 //===-- CallPathManager.cpp -----------------------------------------------===//
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 #include "CallPathManager.h"
11 
12 #include "klee/Statistics.h"
13 
14 #include <map>
15 #include <vector>
16 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
17 #include "llvm/IR/Function.h"
18 #else
19 #include "llvm/Function.h"
20 #endif
21 
22 #include "llvm/Support/raw_ostream.h"
23 
24 using namespace llvm;
25 using namespace klee;
26 
28 
29 CallPathNode::CallPathNode(CallPathNode *_parent,
30  Instruction *_callSite,
31  Function *_function)
32  : parent(_parent),
33  callSite(_callSite),
34  function(_function),
35  count(0) {
36 }
37 
39  llvm::errs() << " (Function: " << this->function->getName() << ", "
40  << "Callsite: " << callSite << ", "
41  << "Count: " << this->count << ")";
42  if (parent && parent->callSite) {
43  llvm::errs() << ";\n";
44  parent->print();
45  }
46  else llvm::errs() << "\n";
47 }
48 
50 
52 }
53 
55  for (std::vector<CallPathNode*>::iterator it = paths.begin(),
56  ie = paths.end(); it != ie; ++it)
57  delete *it;
58 }
59 
61  results.clear();
62 
63  for (std::vector<CallPathNode*>::iterator it = paths.begin(),
64  ie = paths.end(); it != ie; ++it)
65  (*it)->summaryStatistics = (*it)->statistics;
66 
67  // compute summary bottom up, while building result table
68  for (std::vector<CallPathNode*>::reverse_iterator it = paths.rbegin(),
69  ie = paths.rend(); it != ie; ++it) {
70  CallPathNode *cp = *it;
72 
73  CallSiteInfo &csi = results[cp->callSite][cp->function];
74  csi.count += cp->count;
75  csi.statistics += cp->summaryStatistics;
76  }
77 }
78 
79 
81  Instruction *cs,
82  Function *f) {
83  for (CallPathNode *p=parent; p; p=p->parent)
84  if (cs==p->callSite && f==p->function)
85  return p;
86 
87  CallPathNode *cp = new CallPathNode(parent, cs, f);
88  paths.push_back(cp);
89  return cp;
90 }
91 
93  Instruction *cs,
94  Function *f) {
95  std::pair<Instruction*,Function*> key(cs, f);
96  if (!parent)
97  parent = &root;
98 
99  CallPathNode::children_ty::iterator it = parent->children.find(key);
100  if (it==parent->children.end()) {
101  CallPathNode *cp = computeCallPath(parent, cs, f);
102  parent->children.insert(std::make_pair(key, cp));
103  return cp;
104  } else {
105  return it->second;
106  }
107 }
108 
llvm::Function * function
StatisticRecord statistics
children_ty children
CallPathNode * parent
llvm::Instruction * callSite
CallPathNode * computeCallPath(CallPathNode *parent, llvm::Instruction *callSite, llvm::Function *f)
StatisticRecord summaryStatistics
CallPathNode * getCallPath(CallPathNode *parent, llvm::Instruction *callSite, llvm::Function *f)
std::vector< CallPathNode * > paths
std::map< llvm::Instruction *, std::map< llvm::Function *, CallSiteInfo > > CallSiteSummaryTable
void getSummaryStatistics(CallSiteSummaryTable &result)