41using namespace SVFUtil;
52template <
class BaseMRG>
66 if (
const ThreadCallGraph* tcg = SVFUtil::dyn_cast<ThreadCallGraph>(this->getCallGraph()))
67 if (tcg->hasThreadForkEdge(cs))
69 ref = this->getRefSideEffectOfFunction(
callee);
86 ThreadCallGraph* tcg = SVFUtil::dyn_cast<ThreadCallGraph>(this->getCallGraph());
91 if (joinsites.empty())
99 worklist.push(
this->getCallGraph()->getCallGraphNode(cs->getCaller())->getId());
111 return std::make_unique<ThreadMRG<DistinctMRG>>(pta, ptrOnlyMSSA);
113 return std::make_unique<ThreadMRG<IntraDisjointMRG>>(pta, ptrOnlyMSSA);
115 return std::make_unique<ThreadMRG<InterDisjointMRG>>(pta, ptrOnlyMSSA);
117 assert(
false &&
"unrecognised memory partition strategy");
150 SVFUtil::cast<RetIndSVFGEdge>(
edge)->addPointsTo(cpts);
169 SVFUtil::dyn_cast<ThreadCallGraph>(
svfg->getMSSA()->getPTA()->getCallGraph());
190 SVFUtil::cast<ActualOUTSVFGNode>(
svfg->getSVFGNode(
aoId));
205 const bool isLoad = SVFUtil::isa<LoadSVFGNode>(
snode);
206 if (!isLoad && !SVFUtil::isa<StoreSVFGNode>(
snode))
233 assert(SVFUtil::isa<IndirectSVFGEdge>(
edge) &&
"should be an indirect value-flow edge!");
234 return (SVFUtil::cast<IndirectSVFGEdge>(
edge)->addPointsTo(
pts.toNodeBS()) ?
edge :
nullptr);
257 for (SVFGEdge::SVFGEdgeSetTy::iterator
iter =
n->InEdgeBegin();
iter !=
n->InEdgeEnd(); ++
iter)
260 if (
edge->isIndirectVFGEdge())
261 worklist.insert(
edge->getSrcNode());
264 while (!worklist.empty())
266 const SVFGNode* node = *worklist.begin();
267 worklist.erase(worklist.begin());
268 visited.insert(node);
269 if (SVFUtil::isa<StoreSVFGNode>(node))
276 if (
edge->isIndirectVFGEdge() && visited.find(
edge->getSrcNode()) == visited.end())
277 worklist.insert(
edge->getSrcNode());
297 for (SVFGEdge::SVFGEdgeSetTy::iterator
iter =
n->OutEdgeBegin();
iter !=
n->OutEdgeEnd(); ++
iter)
300 if (
edge->isIndirectVFGEdge())
301 worklist.insert(
edge->getDstNode());
304 while (!worklist.empty())
306 const SVFGNode* node = *worklist.begin();
307 worklist.erase(worklist.begin());
308 visited.insert(node);
309 if (SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(node))
316 if (
edge->isIndirectVFGEdge() && visited.find(
edge->getDstNode()) == visited.end())
317 worklist.insert(
edge->getDstNode());
352 assert(SVFUtil::isa<StoreSVFGNode>(
n) &&
"tail test only for store nodes");
361 if (SVFUtil::isa<LoadSVFGNode>(
sn))
394 if (!SVFUtil::isa<StoreSVFGNode>(
sn))
const FunObjVar * getFunction() const
Get function of this call node.
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
IDToNodeMapTy::const_iterator const_iterator
iterator OutEdgeBegin()
iterators
virtual const FunObjVar * getFun() const
Return the function of this ICFGNode.
bool isProtectedByCommonLock(const ICFGNode *i1, const ICFGNode *i2)
bool isInSameSpan(const ICFGNode *I1, const ICFGNode *I2)
virtual bool mayHappenInParallel(const ICFGNode *i1, const ICFGNode *i2)
Interface to query whether two instructions may happen-in-parallel.
static u32_t numOfNewSVFGEdges
Number of thread-aware (interference) SVFG edges added.
void connectMHPEdges(PointerAnalysis *pta)
Connect inter-thread (interference) value-flow edges for MHP pairs.
std::unique_ptr< MRGenerator > createMRGenerator(BVDataPTAImpl *pta, bool ptrOnlyMSSA) override
void handleStoreLoad(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Map< const StmtSVFGNode *, SVFGNodeIDSet > prevset
void handleStoreStore(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
SVFGEdge * addTDEdge(NodeID srcId, NodeID dstId, const PointsTo &pts)
Add a thread-MHP indirect value-flow edge srcId -> dstId carrying pts.
bool isHeadOfSpan(const StmtSVFGNode *n)
void recordThreadVFSource(const StmtSVFGNode *s, const StmtSVFGNode *sp, bool commonLock)
void connectThreadJoinEdges()
void collectLoadStoreSVFGNodes()
bool recordThreadVF
false = skip [THREAD-VF] recording
SVFGNodeSet ldnodeSet
all load SVFG nodes
SVFGNodeIDSet getSuccNodes(const StmtSVFGNode *n)
SVFGNodeSet stnodeSet
all store SVFG nodes
SVFGNodeIDSet getPrevNodes(const StmtSVFGNode *n)
Lock-span head/tail tests (non-interference lock-pair pruning).
bool isTailOfSpan(const StmtSVFGNode *n)
const SlicedICFGView * icfgSlice
Main-solve configuration (see configureForMainSolve); defaults suit VFG_pre.
Map< const StmtSVFGNode *, SVFGNodeIDSet > succset
Map< const StmtSVFGNode *, bool > headmap
Map< const StmtSVFGNode *, bool > tailmap
std::map< ThreadVFEdge, std::set< const ICFGNode * > > threadVFQueryMap
[THREAD-VF] per-edge query map (see getThreadVFQueryMap).
void addJoinRetEdge(const FormalOUTSVFGNode *formalOut, const ActualOUTSVFGNode *actualOut, CallSiteID csId)
void buildSVFG() override
Rewrite the SVFG build hook: build the stock SVFG, then add MHP edges.
bool hasCHI(const PAGEdge *inst) const
static const OptionMap< u32_t > MemPar
virtual const PointsTo & getPts(NodeID ptr)=0
Get points-to targets of a pointer. It needs to be implemented in child class.
std::unique_ptr< SVFG > svfg
NodeID getId() const
Get ID.
bool isKeptNode(const ICFGNode *node) const
Check if a node is in the sliced view.
bool intersects(const SparseBitVector< ElementSize > *RHS) const
OrderedSet< const CallICFGNode *, CallSiteIdCmp > InstSet
void getJoinSites(const CallGraphNode *routine, InstSet &csSet)
virtual const ICFGNode * getICFGNode() const
Return corresponding ICFG node.
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
llvm::IRBuilder IRBuilder