@@ -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