41template<
class SVFGGraph>
49template<
class SVFGGraph>
56template<
class SVFGGraph>
59 std::deque<NodeID>& nodeWorklist)
61 if (node !=
nullptr && !retained.
test(node->
getId()))
64 nodeWorklist.push_back(node->
getId());
68template<
class SVFGGraph>
71 std::deque<NodeID>& nodeWorklist)
78 if (
graph->hasDefSVFGNode(val))
85template<
class SVFGGraph>
88 NodeBS& retained, std::deque<NodeID>& nodeWorklist)
92 retained, nodeWorklist);
95 retained, nodeWorklist);
97 for (
auto it = phi->opVerBegin(), eit = phi->opVerEnd(); it != eit; ++it)
99 retained, nodeWorklist);
102 retained, nodeWorklist);
106 retained, nodeWorklist);
108 retained, nodeWorklist);
113 retained, nodeWorklist);
117 retained, nodeWorklist);
120template<
class SVFGGraph>
126 SVFUtil::errs() <<
"[ERROR] FSMPTA execution closure requires a BaseSVFG "
127 <<
"and Andersen targets\n";
131 std::deque<NodeID> nodeWorklist;
132 for (
NodeID id : dependencyNodes)
133 nodeWorklist.push_back(
id);
140 for (
const auto& callsiteAndPtr :
pag->getIndirectCallsites())
142 const SVFVar* funPtr =
pag->getGNode(callsiteAndPtr.second);
144 dependencyNodes, nodeWorklist);
149 for (
const auto& callsiteAndPtr :
pag->getIndirectCallsites())
150 indirectSites.insert(callsiteAndPtr.first);
151 for (
const auto& callsiteAndTargets :
preAnalysis->getIndCallMap())
152 for (
const FunObjVar* target : callsiteAndTargets.second)
153 indirectTargets.insert(target);
161 bool boundary =
false;
164 boundary = indirectSites.count(actual->getCallSite()) > 0;
167 boundary = indirectSites.count(actual->getCallSite()) > 0;
170 boundary = indirectSites.count(actual->getCallSite()) > 0;
173 boundary = indirectSites.count(actual->getCallSite()) > 0;
176 boundary = indirectTargets.count(formal->getFun()) > 0;
179 boundary = indirectTargets.count(formal->getFun()) > 0;
182 boundary = indirectTargets.count(
183 formal->getFunEntryNode()->getFun()) > 0;
186 boundary = indirectTargets.count(
187 formal->getFunExitNode()->getFun()) > 0;
190 boundary = phi->isFormalINPHI()
191 ? indirectTargets.count(phi->getFun()) > 0
192 : indirectSites.count(phi->getCallSite()) > 0;
210 while (!nodeWorklist.empty())
212 const NodeID id = nodeWorklist.front();
213 nodeWorklist.pop_front();
218 edge->getSrcNode(), dependencyNodes, nodeWorklist);
221 node,
graph, demandedVars, dependencyNodes, nodeWorklist);
223 return dependencyNodes;
226template<
class SVFGGraph>
237 SVFUtil::errs() <<
"[ERROR] FSMPTA does not support clustered Andersen, "
238 <<
"clustered FS, or plain FS mappings\n";
250 if constexpr (SolveGraphTraits::isFilteredGraph)
254template<
class SVFGGraph>
258 svfg->dump(
"fs_solved",
true);
262template<
class SVFGGraph>
265 if (SolveGraphTraits::containsEdge(
solveGraph, edge) &&
270template<
class SVFGGraph>
276 if (!SolveGraphTraits::containsNode(
solveGraph, node))
283template<
class SVFGGraph>
286 const double start =
stat->getClk();
288 assert(
solveNodeStack.empty() &&
"FSMPTA SCC stack was not fully consumed");
291 while (!revTopo.
empty())
296 for (
NodeID id : subNodes)
301 "FSMPTA SCC topology must contain exactly the solve graph");
303 const double end =
stat->getClk();
308template<
class SVFGGraph>
312 assert(SolveGraphTraits::containsNode(
solveGraph, node) &&
313 "FSMPTA worklist must never contain a node outside the solve graph");
317 if constexpr (SolveGraphTraits::isFilteredGraph)
322 for (
SVFGEdge* edge : found->second)
345template<
class SVFGGraph>
348 if constexpr (SolveGraphTraits::isFilteredGraph)
352 if (SolveGraphTraits::containsEdge(
solveGraph, edge))
354 keptEdges.insert(edge);
void finalize() override
Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
void cacheRetainedEdge(SVFGEdge *edge)
static NodeBS buildExecutionDependencyClosure(SVFG *graph, AndersenBase *preAnalysis, NodeBS dependencyNodes)
static void enqueueSVFGNode(const SVFGNode *node, NodeBS &retained, std::deque< NodeID > &worklist)
void processNode(NodeID nodeId) override
Handle various constraints.
FSMPTA(AndersenWaveDiff &preAnalysis, SVFG &backingGraph, SVFGGraph solveGraph)
void finalize() override
Finalize analysis.
void buildRetainedAdjacency()
void updateConnectedNodes(const SVFGEdgeSetTy &edges) override
Update nodes connected during updating call graph.
Map< NodeID, std::vector< SVFGEdge * > > retainedOutEdges
std::unique_ptr< SCCDetection< SVFGGraph > > solveSCC
NodeStack & SCCDetect() override
SCC detection.
static void demandTopLevelPointer(const SVFVar *var, SVFG *graph, NodeBS &demandedVars, NodeBS &retained, std::deque< NodeID > &worklist)
AndersenWaveDiff * preAnalysis
static bool supportsCurrentConfiguration()
void initialize() override
Initialize analysis.
static void collectNodeInputDependencies(const SVFGNode *node, SVFG *graph, NodeBS &demandedVars, NodeBS &retained, std::deque< NodeID > &worklist)
Set< const SVFGEdge * > retainedEdgeSet
virtual void updateConnectedNodes(const SVFGEdgeSetTy &edges)
Update nodes connected during updating call graph.
SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
bool propFromSrcToDst(SVFGEdge *edge) override
Propagation.
friend class FlowSensitiveStat
void clearAllDFOutVarFlag(const SVFGNode *stmt)
bool processSVFGNode(SVFGNode *node)
FlowSensitive(SVFIR *_pag, PTATY type=PTATY::FSSPARSE_WPA)
Constructor.
double sccTime
time of SCC detection.
NodeID getSrcID() const
get methods of the components
const GEdgeSetTy & getOutEdges() const
const GEdgeSetTy & getInEdges() const
bool isVariantFieldGep() const
Gep statement with a variant field index (pointer arithmetic) for struct field access.
static const Option< bool > PlainMappingFs
Use an explicitly plain mapping with flow-sensitive (not null).
static const Option< bool > ClusterAnder
Whether to stage Andersen's with Steensgaard and cluster based on that data.
static const Option< bool > ClusterFs
Whether to cluster FS or VFS with the auxiliary Andersen's.
static const Option< bool > DumpVFG
virtual void initialize()
Initialization of a pointer analysis, including building symbol table and SVFIR etc.
PTAStat * stat
Statistics.
void disablePrintStat()
Whether print statistics.
NodeID getId() const
Get ID.
virtual bool isPointer() const
Check if this variable represents a pointer.
bool test(unsigned Idx) const
VFGNodeIDToNodeMapTy::const_iterator const_iterator
VFGNodeIDToNodeMapTy::iterator iterator
virtual void pushIntoWorklist(NodeID id)
void setGraph(GraphType g)
const GraphType graph()
Get/Set graph methods.
std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > cast(const Y &Val)
std::ostream & errs()
Overwrite llvm::errs().
LLVM_NODISCARD std::enable_if_t<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type > dyn_cast(const Y &Val)
ActualParmVFGNode ActualParmSVFGNode
std::stack< NodeID > NodeStack
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
StoreVFGNode StoreSVFGNode
ActualRetVFGNode ActualRetSVFGNode
FormalParmVFGNode FormalParmSVFGNode
FormalRetVFGNode FormalRetSVFGNode