41template<
class SVFGGraph>
45 solveGraph(solveGraph)
49template<
class SVFGGraph>
56template<
class SVFGGraph>
68template<
class SVFGGraph>
85template<
class SVFGGraph>
93 else if (
const GepSVFGNode*
gep = SVFUtil::dyn_cast<GepSVFGNode>(node))
96 else if (
const PHISVFGNode*
phi = SVFUtil::dyn_cast<PHISVFGNode>(node))
97 for (
auto it =
phi->opVerBegin(),
eit =
phi->opVerEnd(); it !=
eit; ++it)
100 else if (
const LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
101 demandTopLevelPointer(load->getSrcNode(), graph,
demandedVars,
103 else if (
const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
105 demandTopLevelPointer(store->getDstNode(), graph,
demandedVars,
107 demandTopLevelPointer(store->getSrcNode(), graph,
demandedVars,
111 SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
115 SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
120template<
class SVFGGraph>
124 if (graph ==
nullptr || preAnalysis ==
nullptr)
126 SVFUtil::errs() <<
"[ERROR] FSMPTA execution closure requires a BaseSVFG "
127 <<
"and Andersen targets\n";
163 SVFUtil::dyn_cast<ActualParmSVFGNode>(node))
166 SVFUtil::dyn_cast<ActualRetSVFGNode>(node))
169 SVFUtil::dyn_cast<ActualINSVFGNode>(node))
172 SVFUtil::dyn_cast<ActualOUTSVFGNode>(node))
175 SVFUtil::dyn_cast<FormalParmSVFGNode>(node))
178 SVFUtil::dyn_cast<FormalRetSVFGNode>(node))
181 SVFUtil::dyn_cast<FormalINSVFGNode>(node))
183 formal->getFunEntryNode()->getFun()) > 0;
185 SVFUtil::dyn_cast<FormalOUTSVFGNode>(node))
187 formal->getFunExitNode()->getFun()) > 0;
189 SVFUtil::dyn_cast<InterMSSAPHISVFGNode>(node))
199 if (
const GepSVFGNode*
gep = SVFUtil::dyn_cast<GepSVFGNode>(node))
201 const GepStmt* stmt = SVFUtil::cast<GepStmt>(
gep->getSVFStmt());
220 collectNodeInputDependencies(
226template<
class SVFGGraph>
235 if (!supportsCurrentConfiguration())
237 SVFUtil::errs() <<
"[ERROR] FSMPTA does not support clustered Andersen, "
238 <<
"clustered FS, or plain FS mappings\n";
249 solveSCC = std::make_unique<SCCDetection<SVFGGraph>>(solveGraph);
250 if constexpr (SolveGraphTraits::isFilteredGraph)
251 buildRetainedAdjacency();
254template<
class SVFGGraph>
258 svfg->dump(
"fs_solved",
true);
262template<
class SVFGGraph>
265 if (SolveGraphTraits::containsEdge(solveGraph,
edge) &&
266 retainedEdgeSet.insert(
edge).second)
267 retainedOutEdges[
edge->getSrcID()].push_back(
edge);
270template<
class SVFGGraph>
276 if (!SolveGraphTraits::containsNode(solveGraph, node))
279 cacheRetainedEdge(
edge);
283template<
class SVFGGraph>
286 const double start = stat->getClk();
288 assert(solveNodeStack.empty() &&
"FSMPTA SCC stack was not fully consumed");
295 const NodeBS& subNodes = solveSCC->subNodes(rep);
296 for (
NodeID id : subNodes)
297 solveNodeStack.push(
id);
300 assert(solveNodeStack.size() == SolveGraphTraits::graphSize(solveGraph) &&
301 "FSMPTA SCC topology must contain exactly the solve graph");
303 const double end = stat->getClk();
305 return solveNodeStack;
308template<
class SVFGGraph>
312 assert(SolveGraphTraits::containsNode(solveGraph, node) &&
313 "FSMPTA worklist must never contain a node outside the solve graph");
315 if (processSVFGNode(node))
317 if constexpr (SolveGraphTraits::isFilteredGraph)
320 if (
found != retainedOutEdges.end())
324 if (propFromSrcToDst(
edge))
326 pushIntoWorklist(
edge->getDstID());
335 if (propFromSrcToDst(
edge))
337 pushIntoWorklist(
edge->getDstID());
342 clearAllDFOutVarFlag(node);
345template<
class SVFGGraph>
348 if constexpr (SolveGraphTraits::isFilteredGraph)
352 if (SolveGraphTraits::containsEdge(solveGraph,
edge))
354 keptEdges.insert(
edge);
355 cacheRetainedEdge(
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.
NodeStack & SCCDetect() override
SCC detection.
static void demandTopLevelPointer(const SVFVar *var, SVFG *graph, NodeBS &demandedVars, NodeBS &retained, std::deque< NodeID > &worklist)
static bool supportsCurrentConfiguration()
void initialize() override
Initialize analysis.
static void collectNodeInputDependencies(const SVFGNode *node, SVFG *graph, NodeBS &demandedVars, NodeBS &retained, std::deque< NodeID > &worklist)
virtual void updateConnectedNodes(const SVFGEdgeSetTy &edges)
Update nodes connected during updating call graph.
SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
iterator begin()
Iterators.
IDToNodeMapTy::const_iterator const_iterator
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
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.
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
bool hasDefSVFGNode(const ValVar *valVar) const
Given a valVar, return whether it has definition site.
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
const CallSiteToFunPtrMap & getIndirectCallsites() const
Add/get indirect callsites.
NodeID getId() const
Get ID.
SVFIR * getPAG() const
Return SVFIR.
std::ostream & errs()
Overwrite llvm::errs()
std::stack< NodeID > NodeStack
llvm::IRBuilder IRBuilder