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

Split callsite and return site in a CFBBNode #1227

Merged
merged 4 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
63 changes: 50 additions & 13 deletions svf/include/AbstractExecution/WTO.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,11 +492,12 @@ class CFBasicBlockGWTO
NodeRefToCycleDepthNumber _nodeToCDN;
CycleDepthNumber _num;
CFBasicBlockNodes _stack;
CFBasicBlockGraph* _graph;

public:
explicit CFBasicBlockGWTO() : _num(0) {}

explicit CFBasicBlockGWTO(const CFBasicBlockNode *entry) : _num(0)
explicit CFBasicBlockGWTO(CFBasicBlockGraph* graph, const CFBasicBlockNode *entry) : _num(0), _graph(graph)
{
build(entry);
}
Expand Down Expand Up @@ -652,12 +653,13 @@ class CFBasicBlockGWTO
const CFBasicBlockGWTOCycleDepth &_headWTOCycleDepth;
const CFBasicBlockNode *_head;
NodeRefToWTOCycleDepthPtr &_nodeToWTOCycleDepth;
CFBasicBlockGraph* _graph;

public:

explicit TailBuilder(NodeRefToWTOCycleDepthPtr &nodeToWTOCycleDepth, NodeRefSet &tails, const CFBasicBlockNode *head,
explicit TailBuilder(CFBasicBlockGraph* graph, NodeRefToWTOCycleDepthPtr &nodeToWTOCycleDepth, NodeRefSet &tails, const CFBasicBlockNode *head,
const CFBasicBlockGWTOCycleDepth &headWTOCycleDepth) : _tails(tails), _headWTOCycleDepth(headWTOCycleDepth), _head(head), _nodeToWTOCycleDepth(
nodeToWTOCycleDepth)
nodeToWTOCycleDepth), _graph(graph)
{
}

Expand All @@ -671,14 +673,23 @@ class CFBasicBlockGWTO

virtual void visit(const CFBasicBlockGWTONode &node) override
{
for (const auto &edge: node.node()->getOutEdges())
{
const CFBasicBlockNode *succ = edge->getDstNode();
if(const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node.node()->getICFGNodes().front())) {
const CFBasicBlockNode *succ = _graph->getCFBasicBlockNode(callNode->getRetICFGNode()->getId());
const CFBasicBlockGWTOCycleDepth &succNesting = getWTOCycleDepth(succ);
if (succ != _head && succNesting <= _headWTOCycleDepth)
{
_tails.insert(node.node());
}
} else {
for (const auto &edge: node.node()->getOutEdges())
{
const CFBasicBlockNode *succ = edge->getDstNode();
const CFBasicBlockGWTOCycleDepth &succNesting = getWTOCycleDepth(succ);
if (succ != _head && succNesting <= _headWTOCycleDepth)
{
_tails.insert(node.node());
}
}
}
}

Expand Down Expand Up @@ -751,13 +762,21 @@ class CFBasicBlockGWTO
const CFBasicBlockGWTOCycle *component(const CFBasicBlockNode *node)
{
WTOCompRefList partition;
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
if (const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node->getICFGNodes().front())) {
const CFBasicBlockNode *succ = _graph->getCFBasicBlockNode(callNode->getRetICFGNode()->getId());
if (getCDN(succ) == 0)
{
visit(succ, partition);
}
} else {
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
if (getCDN(succ) == 0)
{
visit(succ, partition);
}
}
}
const CFBasicBlockGWTOCycle *ptr = newCycle(node, partition);
_headToCycle.emplace(node, ptr);
Expand All @@ -776,9 +795,8 @@ class CFBasicBlockGWTO
head = _num;
setCDN(node, head);
loop = false;
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
if (const CallICFGNode* callNode = SVFUtil::dyn_cast<CallICFGNode>(node->getICFGNodes().front())) {
const CFBasicBlockNode *succ = _graph->getCFBasicBlockNode(callNode->getRetICFGNode()->getId());
CycleDepthNumber succ_dfn = getCDN(succ);
if (succ_dfn == CycleDepthNumber(0))
{
Expand All @@ -793,6 +811,25 @@ class CFBasicBlockGWTO
head = min;
loop = true;
}
} else {
for (auto it = node->getOutEdges().begin(), et = node->getOutEdges().end(); it != et; ++it)
{
const CFBasicBlockNode *succ = (*it)->getDstNode();
CycleDepthNumber succ_dfn = getCDN(succ);
if (succ_dfn == CycleDepthNumber(0))
{
min = visit(succ, partition);
}
else
{
min = succ_dfn;
}
if (min <= head)
{
head = min;
loop = true;
}
}
}
if (head == getCDN(node))
{
Expand Down Expand Up @@ -831,7 +868,7 @@ class CFBasicBlockGWTO
for (const auto &head: _headToCycle)
{
NodeRefSet tails;
TailBuilder builder(_nodeToDepth, tails, head.first, getWTOCycleDepth(head.first));
TailBuilder builder(_graph, _nodeToDepth, tails, head.first, getWTOCycleDepth(head.first));
for (auto it = head.second->begin(), eit = head.second->end(); it != eit; ++it)
{
(*it)->accept(&builder);
Expand Down
79 changes: 73 additions & 6 deletions svf/include/Graphs/CFBasicBlockG.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ class CFBasicBlockNode : public GenericCFBasicBlockNodeTy
return (*_icfgNodes.begin())->getBB();
}

inline const std::vector<const ICFGNode*>& getICFGNodes() const
{
return _icfgNodes;
}

inline const SVFFunction *getFunction() const
{
assert(!_icfgNodes.empty() && "no ICFG nodes in CFBB");
Expand Down Expand Up @@ -493,6 +498,9 @@ class CFBasicBlockGraph : public GenericCFBasicBlockGTy
class CFBasicBlockGBuilder
{

public:
typedef Map<const SVFBasicBlock*, std::vector<CFBasicBlockNode*>> SVFBBToCFBBNodes;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the input of CFBasicBlock is ICFG, we need to remove "SVFBasicBlock" from CFBasicBlockG. Clean up code and remove unnecessary data structures of SVF.


private:
CFBasicBlockGraph* _CFBasicBlockG;

Expand All @@ -507,6 +515,14 @@ class CFBasicBlockGBuilder
{
return _CFBasicBlockG;
}
private:
void initCFBasicBlockGNodes(ICFG* icfg, SVFBBToCFBBNodes& bbToNodes);

void addInterBBEdge(ICFG* icfg, SVFBBToCFBBNodes& bbToNodes);

void addIntraBBEdge(ICFG* icfg, SVFBBToCFBBNodes& bbToNodes);

void addInterProceduralEdge(ICFG* icfg, SVFBBToCFBBNodes& bbToNodes);
};
}

Expand Down Expand Up @@ -537,14 +553,17 @@ struct GenericGraphTraits<SVF::CFBasicBlockGraph *>
typedef SVF::CFBasicBlockNode *NodeRef;
};

} // End namespace SVF

namespace SVF {
template<>
struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVFIR *>
{

typedef SVF::CFBasicBlockNode NodeType;

DOTGraphTraits(bool isSimple = false) :
DOTGraphTraits<SVF::SVFIR *>(isSimple)
DOTGraphTraits<SVF::SVFIR *>(isSimple)
{
}

Expand Down Expand Up @@ -574,22 +593,70 @@ struct DOTGraphTraits<SVF::CFBasicBlockGraph *> : public DOTGraphTraits<SVF::SVF
{
std::string str;
std::stringstream rawstr(str);
rawstr << "color=black";
if(node->getICFGNodes().size() == 1) {
const ICFGNode* n = node->getICFGNodes()[0];
if(SVFUtil::isa<IntraICFGNode>(n))
{
rawstr << "color=black";
}
else if(SVFUtil::isa<FunEntryICFGNode>(n))
{
rawstr << "color=yellow";
}
else if(SVFUtil::isa<FunExitICFGNode>(n))
{
rawstr << "color=green";
}
else if(SVFUtil::isa<CallICFGNode>(n))
{
rawstr << "color=red";
}
else if(SVFUtil::isa<RetICFGNode>(n))
{
rawstr << "color=blue";
}
else if(SVFUtil::isa<GlobalICFGNode>(n))
{
rawstr << "color=purple";
}
else
assert(false && "no such kind of node!!");
} else {
rawstr << "color=black";
}
rawstr << "";
return rawstr.str();
}

template<class EdgeIter>
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, SVF::CFBasicBlockGraph *)
{
return "style=solid";
CFBasicBlockEdge* edge = *(EI.getCurrent());
assert(edge && "No edge found!!");
if (SVFUtil::isa<CallCFGEdge>(edge->getICFGEdge()))
return "style=solid,color=red";
else if (SVFUtil::isa<RetCFGEdge>(edge->getICFGEdge()))
return "style=solid,color=blue";
else
return "style=solid";
return "";
}

template<class EdgeIter>
static std::string getEdgeSourceLabel(NodeType *, EdgeIter EI)
{
return "";
CFBasicBlockEdge* edge = *(EI.getCurrent());
assert(edge && "No edge found!!");

std::string str;
std::stringstream rawstr(str);
if (const CallCFGEdge* dirCall = SVFUtil::dyn_cast<CallCFGEdge>(edge->getICFGEdge()))
rawstr << dirCall->getCallSite();
else if (const RetCFGEdge* dirRet = SVFUtil::dyn_cast<RetCFGEdge>(edge->getICFGEdge()))
rawstr << dirRet->getCallSite();

return rawstr.str();
}
};

} // End namespace SVF
}
#endif //SVF_CFBASICBLOCKG_H
Loading