예제 #1
0
/*!
 * get CallGraph edge via nodes
 */
PTACallGraphEdge* PTACallGraph::getGraphEdge(PTACallGraphNode* src, PTACallGraphNode* dst,PTACallGraphEdge::CEDGEK kind) {
    for (PTACallGraphEdge::CallGraphEdgeSet::iterator iter = src->OutEdgeBegin();
            iter != src->OutEdgeEnd(); ++iter) {
        PTACallGraphEdge* edge = (*iter);
        if (edge->getEdgeKind() == kind && edge->getDstID() == dst->getId())
            return edge;
    }
    return NULL;
}
예제 #2
0
    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;
    }
예제 #3
0
/*!
 * Add indirect call edge to update call graph
 */
void PTACallGraph::addIndirectCallGraphEdge(const llvm::Instruction* call, const llvm::Function* calleefun) {
    PTACallGraphNode* caller = getCallGraphNode(call->getParent()->getParent());
    PTACallGraphNode* callee = getCallGraphNode(calleefun);

    numOfResolvedIndCallEdge++;

    if(PTACallGraphEdge* callEdge = hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge)) {
        callEdge->addInDirectCallSite(call);
        addCallGraphEdgeSetMap(call,callEdge);
    }
    else {
        assert(call->getParent()->getParent() == caller->getFunction()
               && "callee instruction not inside caller??");

        PTACallGraphEdge* edge = new PTACallGraphEdge(caller,callee,PTACallGraphEdge::CallRetEdge);
        edge->addInDirectCallSite(call);

        addEdge(edge);
        addCallGraphEdgeSetMap(call,edge);
    }
}
예제 #4
0
/*!
 * Add direct call edges
 */
void PTACallGraph::addDirectCallGraphEdge(const llvm::Instruction* call) {
    assert(getCallee(call) && "no callee found");

    PTACallGraphNode* caller = getCallGraphNode(call->getParent()->getParent());
    PTACallGraphNode* callee = getCallGraphNode(getCallee(call));

    if(PTACallGraphEdge* callEdge = hasGraphEdge(caller,callee, PTACallGraphEdge::CallRetEdge)) {
        callEdge->addDirectCallSite(call);
        addCallGraphEdgeSetMap(call,callEdge);
    }
    else {
        assert(call->getParent()->getParent() == caller->getFunction()
               && "callee instruction not inside caller??");

        PTACallGraphEdge* edge = new PTACallGraphEdge(caller,callee,PTACallGraphEdge::CallRetEdge);
        edge->addDirectCallSite(call);

        addEdge(edge);
        addCallGraphEdgeSetMap(call,edge);
    }
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
/*!
 * 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());
        }
    }
}