void PTAStat::callgraphStat() { PTACallGraph* graph = pta->getPTACallGraph(); PointerAnalysis::CallGraphSCC* callgraphSCC = new PointerAnalysis::CallGraphSCC(graph); callgraphSCC->find(); unsigned totalNode = 0; unsigned totalCycle = 0; unsigned nodeInCycle = 0; unsigned maxNodeInCycle = 0; unsigned totalEdge = 0; unsigned edgeInCycle = 0; std::set<NodeID> sccRepNodeSet; PTACallGraph::iterator it = graph->begin(); PTACallGraph::iterator eit = graph->end(); for (; it != eit; ++it) { totalNode++; if(callgraphSCC->isInCycle(it->first)) { sccRepNodeSet.insert(callgraphSCC->repNode(it->first)); nodeInCycle++; const NodeBS& subNodes = callgraphSCC->subNodes(it->first); if(subNodes.count() > maxNodeInCycle) maxNodeInCycle = subNodes.count(); } PTACallGraphNode::const_iterator edgeIt = it->second->InEdgeBegin(); PTACallGraphNode::const_iterator edgeEit = it->second->InEdgeEnd(); for (; edgeIt != edgeEit; ++edgeIt) { PTACallGraphEdge *edge = *edgeIt; totalEdge+= edge->getDirectCalls().size() + edge->getIndirectCalls().size(); if(callgraphSCC->repNode(edge->getSrcID()) == callgraphSCC->repNode(edge->getDstID())) { edgeInCycle+=edge->getDirectCalls().size() + edge->getIndirectCalls().size(); } } } totalCycle = sccRepNodeSet.size(); PTNumStatMap["TotalNode"] = totalNode; PTNumStatMap["TotalCycle"] = totalCycle; PTNumStatMap["NodeInCycle"] = nodeInCycle; PTNumStatMap["MaxNodeInCycle"] = maxNodeInCycle; PTNumStatMap["TotalEdge"] = totalEdge; PTNumStatMap["CalRetPairInCycle"] = edgeInCycle; std::cout << "\n****CallGraph SCC Stat****\n"; PTAStat::printStat(); PTNumStatMap.clear(); delete callgraphSCC; }
/*! * Call site mod-ref analysis * Compute mod-ref of all callsites invoking this call graph node */ void MRGenerator::modRefAnalysis(PTACallGraphNode* callGraphNode, WorkList& worklist) { /// add ref/mod set of callee to its invocation callsites at caller for(PTACallGraphNode::iterator it = callGraphNode->InEdgeBegin(), eit = callGraphNode->InEdgeEnd(); it!=eit; ++it) { PTACallGraphEdge* edge = *it; /// handle direct callsites for(PTACallGraphEdge::CallInstSet::iterator cit = edge->getDirectCalls().begin(), ecit = edge->getDirectCalls().end(); cit!=ecit; ++cit) { NodeBS mod = getModSideEffectOfFunction(callGraphNode->getFunction()); NodeBS ref = getRefSideEffectOfFunction(callGraphNode->getFunction()); /// ref set include all mods ref |= mod; CallSite cs = analysisUtil::getLLVMCallSite(*cit); // add ref set bool refchanged = addRefSideEffectOfCallSite(cs, ref); // add mod set bool modchanged = addModSideEffectOfCallSite(cs, mod); if(refchanged || modchanged) worklist.push(edge->getSrcID()); } /// handle indirect callsites for(PTACallGraphEdge::CallInstSet::iterator cit = edge->getIndirectCalls().begin(), ecit = edge->getIndirectCalls().end(); cit!=ecit; ++cit) { NodeBS mod = getModSideEffectOfFunction(callGraphNode->getFunction()); NodeBS ref = getRefSideEffectOfFunction(callGraphNode->getFunction()); /// ref set include all mods ref |= mod; CallSite cs = analysisUtil::getLLVMCallSite(*cit); // add ref set bool refchanged = addRefSideEffectOfCallSite(cs, ref); // add mod set bool modchanged = addModSideEffectOfCallSite(cs, mod); if(refchanged || modchanged) worklist.push(edge->getSrcID()); } } }
static std::string getEdgeAttributes(PTACallGraphNode *node, EdgeIter EI, PTACallGraph *PTACallGraph) { //TODO: mark indirect call of Fork with different color PTACallGraphEdge* edge = *(EI.getCurrent()); assert(edge && "No edge found!!"); std::string color; if (edge->getEdgeKind() == PTACallGraphEdge::TDJoinEdge) { color = "color=green"; } else if (edge->getEdgeKind() == PTACallGraphEdge::TDForkEdge) { color = "color=blue"; } else { color = "color=black"; } if (0 != edge->getIndirectCalls().size()) { color = "color=red"; } return color; }