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()); } } }
bool PTACallGraphNode::isReachableFromProgEntry() const { std::stack<const PTACallGraphNode*> nodeStack; NodeBS visitedNodes; nodeStack.push(this); visitedNodes.set(getId()); while (nodeStack.empty() == false) { PTACallGraphNode* node = const_cast<PTACallGraphNode*>(nodeStack.top()); nodeStack.pop(); if (analysisUtil::isProgEntryFunction(node->getFunction())) return true; for (const_iterator it = node->InEdgeBegin(), eit = node->InEdgeEnd(); it != eit; ++it) { PTACallGraphEdge* edge = *it; if (visitedNodes.test_and_set(edge->getSrcID())) nodeStack.push(edge->getSrcNode()); } } return false; }