Skip to content

Commit c173019

Browse files
authored
Merge pull request #1723 from JoelYYoung/refactor
Refactor ae
2 parents 9b813b0 + 2920c5a commit c173019

File tree

3 files changed

+85
-128
lines changed

3 files changed

+85
-128
lines changed

svf/include/AE/Core/ICFGWTO.h

Lines changed: 17 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -45,88 +45,56 @@ typedef WTOComponent<ICFG> ICFGWTOComp;
4545
typedef WTONode<ICFG> ICFGSingletonWTO;
4646
typedef WTOCycle<ICFG> ICFGCycleWTO;
4747

48+
// Added for IWTO
4849
class ICFGWTO : public WTO<ICFG>
4950
{
5051
public:
5152
typedef WTO<ICFG> Base;
5253
typedef WTOComponentVisitor<ICFG>::WTONodeT ICFGWTONode;
54+
Set<const FunObjVar*> scc;
5355

54-
explicit ICFGWTO(ICFG* graph, const ICFGNode* node) : Base(graph, node) {}
56+
explicit ICFGWTO(ICFG* graph,const ICFGNode* node, Set<const FunObjVar*> funcScc = {}) :
57+
Base(graph, node), scc(funcScc){
58+
if (scc.empty()) // if empty funcScc, default use the function of the node
59+
scc.insert(node->getFun());
60+
}
5561

5662
virtual ~ICFGWTO()
5763
{
5864
}
5965

60-
inline void forEachSuccessor(
61-
const ICFGNode* node,
62-
std::function<void(const ICFGNode*)> func) const override
63-
{
64-
if (const auto* callNode = SVFUtil::dyn_cast<CallICFGNode>(node))
65-
{
66-
const ICFGNode* succ = callNode->getRetICFGNode();
67-
func(succ);
68-
}
69-
else
70-
{
71-
for (const auto& e : node->getOutEdges())
72-
{
73-
if (!e->isIntraCFGEdge() ||
74-
node->getFun() != e->getDstNode()->getFun())
75-
continue;
76-
func(e->getDstNode());
77-
}
78-
}
79-
}
80-
};
81-
82-
// Added for IWTO
83-
class ICFGIWTO : public ICFGWTO
84-
{
85-
public:
86-
typedef ICFGWTO Base;
87-
typedef WTOComponentVisitor<ICFG>::WTONodeT ICFGWTONode;
88-
NodeBS &funcPar;
89-
CallGraph *cg;
90-
91-
explicit ICFGIWTO(ICFG* graph, const ICFGNode* node, NodeBS & funcPar, CallGraph* cg) :
92-
Base(graph, node), funcPar(funcPar), cg(cg) {}
93-
94-
virtual ~ICFGIWTO()
66+
inline virtual std::vector<const ICFGNode*> getSuccessors(const ICFGNode* node) override
9567
{
96-
}
68+
std::vector<const ICFGNode*> successors;
9769

98-
inline void forEachSuccessor(
99-
const ICFGNode* node,
100-
std::function<void(const ICFGNode*)> func) const override
101-
{
10270
if (const auto* callNode = SVFUtil::dyn_cast<CallICFGNode>(node))
10371
{
10472

10573
for (const auto &e : callNode->getOutEdges())
10674
{
10775
ICFGNode *calleeEntryICFGNode = e->getDstNode();
108-
CallGraphNode * calleeCGNode = cg->getCallGraphNode(calleeEntryICFGNode->getFun());
76+
const ICFGNode *succ = nullptr;
10977

110-
const ICFGNode* succ = nullptr;
111-
if (funcPar.test(calleeCGNode->getId()))
78+
if (scc.find(calleeEntryICFGNode->getFun()) != scc.end()) // caller & callee in the same SCC
11279
succ = calleeEntryICFGNode;
11380
else
114-
succ = callNode->getRetICFGNode();
81+
succ = callNode->getRetICFGNode(); // caller & callee in different SCC
11582

116-
func(succ);
83+
successors.push_back(succ);
11784
}
11885
}
11986
else
12087
{
12188
for (const auto& e : node->getOutEdges())
12289
{
12390
ICFGNode *succ = e->getDstNode();
124-
CallGraphNode *succCGNode = cg->getCallGraphNode(succ->getFun());
125-
if (!funcPar.test(succCGNode->getId()))
91+
if (scc.find(succ->getFun()) == scc.end()) // if not in the same SCC, skip
12692
continue;
127-
func(succ);
93+
successors.push_back(succ);
12894
}
12995
}
96+
97+
return successors;
13098
}
13199
};
132100

svf/include/Graphs/WTO.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -720,13 +720,15 @@ template <typename GraphT> class WTO
720720
}; // end class WTOCycleDepthBuilder
721721

722722
protected:
723-
724-
inline virtual void forEachSuccessor(const NodeT* node, std::function<void(const NodeT*)> func) const
723+
/// Return the successors of node
724+
inline virtual std::vector<const NodeT *> getSuccessors(const NodeT* node)
725725
{
726+
std::vector<const NodeT *> succssors;
726727
for (const auto& e : node->getOutEdges())
727728
{
728-
func(e->getDstNode());
729+
succssors.push_back(e->getDstNode());
729730
}
731+
return succssors;
730732
}
731733

732734
protected:
@@ -788,13 +790,14 @@ template <typename GraphT> class WTO
788790
virtual const WTOCycleT* component(const NodeT* node)
789791
{
790792
WTOComponentRefList partition;
791-
forEachSuccessor(node, [&](const NodeT* succ)
793+
794+
for (auto succ: getSuccessors(node))
792795
{
793796
if (getCDN(succ) == 0)
794797
{
795798
visit(succ, partition);
796799
}
797-
});
800+
}
798801
const WTONodeT* head = newNode(node);
799802
const WTOCycleT* ptr = newCycle(head, partition);
800803
headRefToCycle.emplace(node, ptr);
@@ -816,7 +819,8 @@ template <typename GraphT> class WTO
816819
head = _num;
817820
setCDN(node, head);
818821
loop = false;
819-
forEachSuccessor(node, [&](const NodeT* succ)
822+
823+
for (auto succ: getSuccessors(node))
820824
{
821825
CycleDepthNumber succ_dfn = getCDN(succ);
822826
if (succ_dfn == CycleDepthNumber(0))
@@ -832,7 +836,7 @@ template <typename GraphT> class WTO
832836
head = min;
833837
loop = true;
834838
}
835-
});
839+
}
836840

837841
if (head == getCDN(node))
838842
{

svf/lib/AE/Svfexe/AbstractInterpretation.cpp

Lines changed: 57 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -96,62 +96,50 @@ void AbstractInterpretation::initWTO()
9696
if (callGraphScc->isInCycle(it->second->getId()))
9797
recursiveFuns.insert(it->second->getFunction()); // Mark the function as recursive
9898

99-
// In TOP mode, calculate the WTO
100-
if (Options::HandleRecur() == TOP)
99+
// Calculate ICFGWTO for each function/recursion
100+
const FunObjVar *fun = it->second->getFunction();
101+
if (fun->isDeclaration())
102+
continue;
103+
104+
NodeID repNodeId = callGraphScc->repNode(it->second->getId());
105+
auto cgSCCNodes = callGraphScc->subNodes(repNodeId);
106+
107+
// Identify if this node is an SCC entry (nodes who have incoming edges
108+
// from nodes outside the SCC). Also identify non-recursive callsites.
109+
bool isEntry = false;
110+
if (it->second->getInEdges().empty())
111+
isEntry = true;
112+
for (auto inEdge: it->second->getInEdges())
101113
{
102-
if (it->second->getFunction()->isDeclaration())
103-
continue;
104-
auto* wto = new ICFGWTO(icfg, icfg->getFunEntryICFGNode(it->second->getFunction()));
105-
wto->init();
106-
funcToWTO[it->second->getFunction()] = wto;
107-
}
108-
// In WIDEN_TOP or WIDEN_NARROW mode, calculate the IWTO
109-
else if (Options::HandleRecur() == WIDEN_ONLY ||
110-
Options::HandleRecur() == WIDEN_NARROW)
111-
{
112-
const FunObjVar *fun = it->second->getFunction();
113-
if (fun->isDeclaration())
114-
continue;
115-
116-
NodeID repNodeId = callGraphScc->repNode(it->second->getId());
117-
auto cgSCCNodes = callGraphScc->subNodes(repNodeId);
118-
119-
// Identify if this node is an SCC entry (nodes who have incoming edges
120-
// from nodes outside the SCC). Also identify non-recursive callsites.
121-
bool isEntry = false;
122-
if (it->second->getInEdges().empty())
123-
isEntry = true;
124-
for (auto inEdge: it->second->getInEdges())
114+
NodeID srcNodeId = inEdge->getSrcID();
115+
if (!cgSCCNodes.test(srcNodeId))
125116
{
126-
NodeID srcNodeId = inEdge->getSrcID();
127-
if (!cgSCCNodes.test(srcNodeId))
128-
{
129-
isEntry = true;
130-
const CallICFGNode *callSite = nullptr;
131-
if (inEdge->isDirectCallEdge())
132-
callSite = *(inEdge->getDirectCalls().begin());
133-
else if (inEdge->isIndirectCallEdge())
134-
callSite = *(inEdge->getIndirectCalls().begin());
135-
else
136-
assert(false && "CallGraphEdge must "
137-
"be either direct or indirect!");
117+
isEntry = true;
118+
const CallICFGNode *callSite = nullptr;
119+
if (inEdge->isDirectCallEdge())
120+
callSite = *(inEdge->getDirectCalls().begin());
121+
else if (inEdge->isIndirectCallEdge())
122+
callSite = *(inEdge->getIndirectCalls().begin());
123+
else
124+
assert(false && "CallGraphEdge must "
125+
"be either direct or indirect!");
138126

139-
nonRecursiveCallSites.insert(
140-
{callSite, inEdge->getDstNode()->getFunction()->getId()});
141-
}
127+
nonRecursiveCallSites.insert(
128+
{callSite, inEdge->getDstNode()->getFunction()->getId()});
142129
}
130+
}
143131

144-
// Compute IWTO for the function partition entered from each partition entry
145-
if (isEntry)
146-
{
147-
ICFGIWTO* iwto = new ICFGIWTO(icfg, icfg->getFunEntryICFGNode(fun),
148-
cgSCCNodes, callGraph);
149-
iwto->init();
150-
funcToWTO[it->second->getFunction()] = iwto;
132+
// Compute IWTO for the function partition entered from each partition entry
133+
if (isEntry)
134+
{
135+
Set<const FunObjVar*> funcScc;
136+
for (const auto& node: cgSCCNodes) {
137+
funcScc.insert(callGraph->getGNode(node)->getFunction());
151138
}
139+
ICFGWTO* iwto = new ICFGWTO(icfg, icfg->getFunEntryICFGNode(fun), funcScc);
140+
iwto->init();
141+
funcToWTO[it->second->getFunction()] = iwto;
152142
}
153-
else
154-
assert(false && "Invalid recursion mode specified!");
155143
}
156144
}
157145

@@ -716,9 +704,19 @@ void AbstractInterpretation::directCallFunPass(const CallICFGNode *callNode)
716704
const FunObjVar *calleeFun =callNode->getCalledFunction();
717705
if (Options::HandleRecur() == WIDEN_ONLY || Options::HandleRecur() == WIDEN_NARROW)
718706
{
707+
// If this CallICFGNode is a recursive callsite (i.e. this Node
708+
// resides in a recursive function 'fun' and its callee function is
709+
// in the same SCC with the fun), then skip it. Since the callee
710+
// function is handled during the handling of WTO of the whole recursion.
719711
if (isRecursiveCallSite(callNode, calleeFun))
720712
return;
721713
}
714+
else
715+
{
716+
// When Options::HandleRecur() == TOP, skipRecursiveCall will handle recursions,
717+
// thus should not reach this branch
718+
assert(false && "Recursion mode TOP should not reach here!");
719+
}
722720

723721
callSiteStack.push_back(callNode);
724722

@@ -790,32 +788,19 @@ void AbstractInterpretation::handleCycleWTO(const ICFGCycleWTO*cycle)
790788
AbstractState cur_head_state = abstractTrace[cycle_head];
791789
if (increasing)
792790
{
793-
// Widening, use different modes for nodes within recursions
794-
if (isRecursiveFun(cycle->head()->getICFGNode()->getFun()))
791+
792+
if (isRecursiveFun(cycle->head()->getICFGNode()->getFun()) &&
793+
!(Options::HandleRecur() == WIDEN_ONLY ||
794+
Options::HandleRecur() == WIDEN_NARROW))
795795
{
796-
// For nodes in recursions, widen to top in WIDEN_TOP mode
797-
if (Options::HandleRecur() == WIDEN_ONLY)
798-
{
799-
abstractTrace[cycle_head] = prev_head_state.widening(cur_head_state);
800-
}
801-
// Perform normal widening in WIDEN_NARROW mode
802-
else if (Options::HandleRecur() == WIDEN_NARROW)
803-
{
804-
abstractTrace[cycle_head] = prev_head_state.widening(cur_head_state);
805-
}
806-
// In TOP mode, skipRecursiveCall will handle recursions,
796+
// When Options::HandleRecur() == TOP, skipRecursiveCall will handle recursions,
807797
// thus should not reach this branch
808-
else
809-
{
810-
assert(false && "Recursion mode TOP should not reach here!");
811-
}
812-
}
813-
// For nodes outside recursions, perform normal widening
814-
else
815-
{
816-
abstractTrace[cycle_head] = prev_head_state.widening(cur_head_state);
798+
assert(false && "Recursion mode TOP should not reach here!");
817799
}
818800

801+
// Widening
802+
abstractTrace[cycle_head] = prev_head_state.widening(cur_head_state);
803+
819804
if (abstractTrace[cycle_head] == prev_head_state)
820805
{
821806
increasing = false;
@@ -843,7 +828,7 @@ void AbstractInterpretation::handleCycleWTO(const ICFGCycleWTO*cycle)
843828
break;
844829
}
845830
}
846-
// In TOP mode, skipRecursiveCall will handle recursions,
831+
// When Options::HandleRecur() == TOP, skipRecursiveCall will handle recursions,
847832
// thus should not reach this branch
848833
else
849834
{

0 commit comments

Comments
 (0)