CallPathManager.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "CallPathManager.h"
00011
00012 #include "klee/Statistics.h"
00013
00014 #include <map>
00015 #include <vector>
00016 #include "llvm/Function.h"
00017 #include "llvm/Support/Streams.h"
00018
00019 using namespace llvm;
00020 using namespace klee;
00021
00023
00024 CallPathNode::CallPathNode(CallPathNode *_parent,
00025 Instruction *_callSite,
00026 Function *_function)
00027 : parent(_parent),
00028 callSite(_callSite),
00029 function(_function),
00030 count(0) {
00031 }
00032
00033 void CallPathNode::print() {
00034 llvm::cerr << " (Function: " << this->function->getName() << ", "
00035 << "Callsite: " << callSite << ", "
00036 << "Count: " << this->count << ")";
00037 if (parent && parent->callSite) {
00038 llvm::cerr << ";\n";
00039 parent->print();
00040 }
00041 else llvm::cerr << "\n";
00042 }
00043
00045
00046 CallPathManager::CallPathManager() : root(0, 0, 0) {
00047 }
00048
00049 CallPathManager::~CallPathManager() {
00050 for (std::vector<CallPathNode*>::iterator it = paths.begin(),
00051 ie = paths.end(); it != ie; ++it)
00052 delete *it;
00053 }
00054
00055 void CallPathManager::getSummaryStatistics(CallSiteSummaryTable &results) {
00056 results.clear();
00057
00058 for (std::vector<CallPathNode*>::iterator it = paths.begin(),
00059 ie = paths.end(); it != ie; ++it)
00060 (*it)->summaryStatistics = (*it)->statistics;
00061
00062
00063 for (std::vector<CallPathNode*>::reverse_iterator it = paths.rbegin(),
00064 ie = paths.rend(); it != ie; ++it) {
00065 CallPathNode *cp = *it;
00066 cp->parent->summaryStatistics += cp->summaryStatistics;
00067
00068 CallSiteInfo &csi = results[cp->callSite][cp->function];
00069 csi.count += cp->count;
00070 csi.statistics += cp->summaryStatistics;
00071 }
00072 }
00073
00074
00075 CallPathNode *CallPathManager::computeCallPath(CallPathNode *parent,
00076 Instruction *cs,
00077 Function *f) {
00078 for (CallPathNode *p=parent; p; p=p->parent)
00079 if (cs==p->callSite && f==p->function)
00080 return p;
00081
00082 CallPathNode *cp = new CallPathNode(parent, cs, f);
00083 paths.push_back(cp);
00084 return cp;
00085 }
00086
00087 CallPathNode *CallPathManager::getCallPath(CallPathNode *parent,
00088 Instruction *cs,
00089 Function *f) {
00090 std::pair<Instruction*,Function*> key(cs, f);
00091 if (!parent)
00092 parent = &root;
00093
00094 CallPathNode::children_ty::iterator it = parent->children.find(key);
00095 if (it==parent->children.end()) {
00096 CallPathNode *cp = computeCallPath(parent, cs, f);
00097 parent->children.insert(std::make_pair(key, cp));
00098 return cp;
00099 } else {
00100 return it->second;
00101 }
00102 }
00103