Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Callgraph #1570

Merged
merged 23 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions svf-llvm/include/SVF-LLVM/LLVMModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class LLVMModuleSet
InstToBlockNodeMapTy InstToBlockNodeMap; ///< map a basic block to its ICFGNode
FunToFunEntryNodeMapTy FunToFunEntryNodeMap; ///< map a function to its FunExitICFGNode
FunToFunExitNodeMapTy FunToFunExitNodeMap; ///< map a function to its FunEntryICFGNode
CallGraph* callgraph;

/// Constructor
LLVMModuleSet();
Expand Down
5 changes: 5 additions & 0 deletions svf-llvm/lib/LLVMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include "SVF-LLVM/ObjTypeInference.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "SVF-LLVM/ICFGBuilder.h"
#include "Graphs/CallGraph.h"
#include "Util/CallGraphBuilder.h"

using namespace std;
using namespace SVF;
Expand Down Expand Up @@ -169,6 +171,9 @@ void LLVMModuleSet::build()
initSVFFunction();
ICFGBuilder icfgbuilder;
icfg = icfgbuilder.build();

CallGraphBuilder callGraphBuilder;
callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);
}

void LLVMModuleSet::createSVFDataStructure()
Expand Down
4 changes: 4 additions & 0 deletions svf-llvm/lib/SVFIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "SVFIR/SVFFileSystem.h"
#include "SVFIR/SVFModule.h"
#include "SVFIR/SVFValue.h"
#include "Util/CallGraphBuilder.h"
#include "Util/Options.h"
#include "Util/SVFUtil.h"

Expand All @@ -62,6 +63,9 @@ SVFIR* SVFIRBuilder::build()
// Build ICFG
pag->setICFG(llvmModuleSet()->getICFG());

// Set callgraph
pag->setCallGraph(llvmModuleSet()->callgraph);

// Set icfgnode in memobj
for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
{
Expand Down
12 changes: 9 additions & 3 deletions svf/include/Graphs/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ class CallGraphNode : public GenericCallGraphNodeTy

}

inline const std::string &getName() const
{
return fun->getName();
}

/// Get function of this call node
inline const SVFFunction* getFunction() const
{
Expand Down Expand Up @@ -254,8 +259,6 @@ class CallGraph : public GenericCallGraphTy
};

private:
CGEK kind;

/// Indirect call map
CallEdgeMap indirectCallMap;

Expand All @@ -270,6 +273,7 @@ class CallGraph : public GenericCallGraphTy

NodeID callGraphNodeNum;
u32_t numOfResolvedIndCallEdge;
CGEK kind;

/// Clean up memory
void destroy();
Expand All @@ -278,7 +282,9 @@ class CallGraph : public GenericCallGraphTy
/// Constructor
CallGraph(CGEK k = NormCallGraph);

/// Add callgraph Node
/// Copy constructor
CallGraph(const CallGraph& other);

void addCallGraphNode(const SVFFunction* fun);

/// Destructor
Expand Down
5 changes: 4 additions & 1 deletion svf/include/Graphs/ThreadCallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ class ThreadCallGraph: public CallGraph
typedef Map<const CallICFGNode*, ParForEdgeSet> CallInstToParForEdgesMap;

/// Constructor
ThreadCallGraph();
ThreadCallGraph(const CallGraph& cg);

ThreadCallGraph(ThreadCallGraph& cg) = delete;

/// Destructor
virtual ~ThreadCallGraph()
{
Expand Down
13 changes: 13 additions & 0 deletions svf/include/SVFIR/SVFIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class SVFIR : public IRGraph
ICFG* icfg; // ICFG
CommonCHGraph* chgraph; // class hierarchy graph
CallSiteSet callSiteSet; /// all the callsites of a program
CallGraph* callGraph; /// call graph

static std::unique_ptr<SVFIR> pag; ///< Singleton pattern here to enable instance of SVFIR can only be created once.

Expand Down Expand Up @@ -182,6 +183,18 @@ class SVFIR : public IRGraph
assert(chgraph && "empty ICFG! Build SVF IR first!");
return chgraph;
}

/// Set/Get CG
inline void setCallGraph(CallGraph* c)
{
callGraph = c;
}
inline CallGraph* getCallGraph()
{
assert(callGraph && "empty CallGraph! Build SVF IR first!");
return callGraph;
}

/// Get/set methods to get SVFStmts based on their kinds and ICFGNodes
//@{
/// Get edges set according to its kind
Expand Down
17 changes: 0 additions & 17 deletions svf/include/SVFIR/SVFModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,6 @@ class SVFModule

/// Iterators
///@{
iterator begin()
{
return FunctionSet.begin();
}
const_iterator begin() const
{
return FunctionSet.begin();
}
iterator end()
{
return FunctionSet.end();
}
const_iterator end() const
{
return FunctionSet.end();
}

global_iterator global_begin()
{
return GlobalSet.begin();
Expand Down
26 changes: 5 additions & 21 deletions svf/include/Util/CallGraphBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,34 +38,18 @@ namespace SVF
{

class ICFG;
class SVFModule;

class CallGraphBuilder
{

protected:
CallGraph* callgraph;
ICFG* icfg;
public:
CallGraphBuilder(CallGraph* cg, ICFG* i): callgraph(cg),icfg(i)
{
}

/// Build normal callgraph
CallGraph* buildCallGraph(SVFModule* svfModule);

};
CallGraphBuilder()=default;

class ThreadCallGraphBuilder : public CallGraphBuilder
{

public:
ThreadCallGraphBuilder(ThreadCallGraph* cg, ICFG* i): CallGraphBuilder(cg,i)
{
}
/// Buidl SVFIR callgraoh
CallGraph* buildSVFIRCallGraph(SVFModule* svfModule);

/// Build thread-aware callgraph
CallGraph* buildThreadCallGraph(SVFModule* svfModule);

ThreadCallGraph* buildThreadCallGraph();
};

} // End namespace SVF
Expand Down
26 changes: 4 additions & 22 deletions svf/include/Util/SVFUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,29 +327,11 @@ inline bool isProgEntryFunction(const SVFFunction* fun)
return fun && fun->getName() == "main";
}

/// Get program entry function from module.
inline const SVFFunction* getProgFunction(SVFModule* svfModule, const std::string& funName)
{
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
{
const SVFFunction *fun = *it;
if (fun->getName()==funName)
return fun;
}
return nullptr;
}
/// Get program entry function from function name.
const SVFFunction* getProgFunction(const std::string& funName);

/// Get program entry function from module.
inline const SVFFunction* getProgEntryFunction(SVFModule* svfModule)
{
for (SVFModule::const_iterator it = svfModule->begin(), eit = svfModule->end(); it != eit; ++it)
{
const SVFFunction *fun = *it;
if (isProgEntryFunction(fun))
return (fun);
}
return nullptr;
}
/// Get program entry function.
const SVFFunction* getProgEntryFunction();

/// Return true if this is a program exit function call
//@{
Expand Down
43 changes: 37 additions & 6 deletions svf/lib/Graphs/CallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,38 @@ CallGraph::CallGraph(CGEK k): kind(k)
numOfResolvedIndCallEdge = 0;
}

/// Copy constructor
CallGraph::CallGraph(const CallGraph& other) {
callGraphNodeNum = other.callGraphNodeNum;
numOfResolvedIndCallEdge = 0;
kind = other.kind;

/// copy call graph nodes
for (const auto& item : other)
{
const CallGraphNode* cgn = item.second;
CallGraphNode* callGraphNode = new CallGraphNode(cgn->getId(), cgn->getFunction());
addGNode(cgn->getId(),callGraphNode);
funToCallGraphNodeMap[cgn->getFunction()] = callGraphNode;
}

/// copy edges
for (const auto& item : other.callinstToCallGraphEdgesMap)
{
const CallICFGNode* cs = item.first;
for (const CallGraphEdge* edge : item.second)
{
CallGraphNode* src = getCallGraphNode(edge->getSrcID());
CallGraphNode* dst = getCallGraphNode(edge->getDstID());
CallGraphEdge* newEdge = new CallGraphEdge(src,dst,CallGraphEdge::CallRetEdge,edge->getCallSiteID());
newEdge->addDirectCallSite(cs);
addEdge(newEdge);
callinstToCallGraphEdgesMap[cs].insert(newEdge);
}
}

}

/*!
* Memory has been cleaned up at GenericGraph
*/
Expand All @@ -122,12 +154,11 @@ void CallGraph::destroy()
/*!
* Add call graph node
*/
void CallGraph::addCallGraphNode(const SVFFunction* fun)
{
NodeID id = callGraphNodeNum;
CallGraphNode* callGraphNode = new CallGraphNode(id, fun);
addGNode(id,callGraphNode);
funToCallGraphNodeMap[fun] = callGraphNode;
void CallGraph::addCallGraphNode(const SVFFunction* fun) {
NodeID id = callGraphNodeNum;
CallGraphNode *callGraphNode = new CallGraphNode(id, fun);
addGNode(id, callGraphNode);
funToCallGraphNodeMap[callGraphNode->getFunction()] = callGraphNode;
callGraphNodeNum++;
}

Expand Down
4 changes: 1 addition & 3 deletions svf/lib/Graphs/SVFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,7 @@ void SVFG::connectIndirectSVFGEdges()
*/
void SVFG::connectFromGlobalToProgEntry()
{
SVFModule* svfModule = mssa->getPTA()->getModule();
const SVFFunction* mainFunc =
SVFUtil::getProgEntryFunction(svfModule);
const SVFFunction* mainFunc = SVFUtil::getProgEntryFunction();
FormalINSVFGNodeSet& formalIns = getFormalINSVFGNodes(mainFunc);
if (formalIns.empty())
return;
Expand Down
5 changes: 3 additions & 2 deletions svf/lib/Graphs/ThreadCallGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ using namespace SVFUtil;
/*!
* Constructor
*/
ThreadCallGraph::ThreadCallGraph() :
CallGraph(ThdCallGraph), tdAPI(ThreadAPI::getThreadAPI())
ThreadCallGraph::ThreadCallGraph(const CallGraph& cg) :
CallGraph(cg), tdAPI(ThreadAPI::getThreadAPI())
{
kind = ThdCallGraph;
DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Building ThreadCallGraph\n"));
}

Expand Down
7 changes: 3 additions & 4 deletions svf/lib/MSSA/MemRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,10 @@ SVFIR::SVFStmtList& MRGenerator::getPAGEdgesFromInst(const ICFGNode* node)
void MRGenerator::collectModRefForLoadStore()
{

SVFModule* svfModule = pta->getModule();
for (SVFModule::const_iterator fi = svfModule->begin(), efi = svfModule->end(); fi != efi;
++fi)
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
for (const auto& item: *svfirCallGraph)
{
const SVFFunction& fun = **fi;
const SVFFunction& fun = *item.second->getFunction();

/// if this function does not have any caller, then we do not care its MSSA
if (Options::IgnoreDeadFun() && fun.isUncalledFunction())
Expand Down
6 changes: 3 additions & 3 deletions svf/lib/MSSA/MemSSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -575,10 +575,10 @@ u32_t MemSSA::getBBPhiNum() const
void MemSSA::dumpMSSA(OutStream& Out)
{

for (SVFModule::iterator fit = pta->getModule()->begin(), efit = pta->getModule()->end();
fit != efit; ++fit)
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
for (const auto& item: *svfirCallGraph)
{
const SVFFunction* fun = *fit;
const SVFFunction* fun = item.second->getFunction();
if(Options::MSSAFun()!="" && Options::MSSAFun()!=fun->getName())
continue;

Expand Down
7 changes: 3 additions & 4 deletions svf/lib/MSSA/SVFGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,11 @@ std::unique_ptr<MemSSA> SVFGBuilder::buildMSSA(BVDataPTAImpl* pta, bool ptrOnlyM

auto mssa = std::make_unique<MemSSA>(pta, ptrOnlyMSSA);

SVFModule* svfModule = mssa->getPTA()->getModule();
for (SVFModule::const_iterator iter = svfModule->begin(), eiter = svfModule->end();
iter != eiter; ++iter)
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
for (const auto& item: *svfirCallGraph)
{

const SVFFunction *fun = *iter;
const SVFFunction *fun = item.second->getFunction();
if (isExtCall(fun))
continue;

Expand Down
5 changes: 3 additions & 2 deletions svf/lib/MTA/TCT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,10 @@ void TCT::markRelProcs(const SVFFunction* svffun)
*/
void TCT::collectEntryFunInCallGraph()
{
for(SVFModule::const_iterator it = getSVFModule()->begin(), eit = getSVFModule()->end(); it!=eit; ++it)
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
for (const auto& item: *svfirCallGraph)
{
const SVFFunction* fun = (*it);
const SVFFunction* fun = item.second->getFunction();
if (SVFUtil::isExtCall(fun))
continue;
CallGraphNode* node = tcg->getCallGraphNode(fun);
Expand Down
10 changes: 4 additions & 6 deletions svf/lib/MemoryModel/PointerAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,13 @@ void PointerAnalysis::initialize()
/// initialise pta call graph for every pointer analysis instance
if(Options::EnableThreadCallGraph())
{
ThreadCallGraph* cg = new ThreadCallGraph();
ThreadCallGraphBuilder bd(cg, pag->getICFG());
callgraph = bd.buildThreadCallGraph(pag->getModule());
CallGraphBuilder bd;
callgraph = bd.buildThreadCallGraph();
}
else
{
CallGraph* cg = new CallGraph();
CallGraphBuilder bd(cg,pag->getICFG());
callgraph = bd.buildCallGraph(pag->getModule());
CallGraph* cg = pag->getCallGraph();
callgraph = new CallGraph(*cg);
}
callGraphSCCDetection();

Expand Down
4 changes: 3 additions & 1 deletion svf/lib/SABER/SaberCondAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ void SaberCondAllocator::allocate(const SVFModule *M)
{
DBOUT(DGENERAL, outs() << pasMsg("path condition allocation starts\n"));

for (const auto &func: *M)
CallGraph* svfirCallGraph = PAG::getPAG()->getCallGraph();
for (const auto& item: *svfirCallGraph)
{
const SVFFunction *func = (item.second)->getFunction();
if (!SVFUtil::isExtCall(func))
{
// Allocate conditions for a program.
Expand Down
Loading
Loading