37 using namespace SVFUtil;
49 MemSSA* mssa = svfg->getMSSA();
55 connectMHPEdges(mssa->
getPTA());
70 if (SVFUtil::isa<LoadSVFGNode>(snode))
72 const StmtSVFGNode* node = SVFUtil::cast<StmtSVFGNode>(snode);
75 ldnodeSet.insert(node);
78 if (SVFUtil::isa<StoreSVFGNode>(snode))
80 const StmtSVFGNode* node = SVFUtil::cast<StmtSVFGNode>(snode);
83 stnodeSet.insert(node);
91 if (recordedges.find(pair) == recordedges.end())
93 recordedges.insert(pair);
99 edge2pts[pair] |= pts;
105 return recordEdge(id1, id2, pts);
110 return recordEdge(id1, id2, pts);
116 while (!recordedges.empty())
118 std::pair<NodeID, NodeID> edgepair = *recordedges.begin();
120 recordedges.erase(recordedges.begin());
121 addTDEdges(edgepair.first, edgepair.second, pts);
128 SVFGNode* srcNode = svfg->getSVFGNode(srcId);
129 SVFGNode* dstNode = svfg->getSVFGNode(dstId);
133 assert(SVFUtil::isa<IndirectSVFGEdge>(edge) &&
"this should be a indirect value flow edge!");
134 return (SVFUtil::cast<IndirectSVFGEdge>(edge)->addPointsTo(pts.
toNodeBS()) ? edge :
nullptr);
141 return (svfg->addSVFGEdge(indirectEdge) ? indirectEdge :
nullptr);
147 while (!recordedges.empty())
149 std::pair<NodeID, NodeID> edgepair = *recordedges.begin();
150 recordedges.erase(recordedges.begin());
152 PointsTo remove_pts = edge2pts[edgepair];
153 const StmtSVFGNode* n1 = SVFUtil::cast<StmtSVFGNode>(svfg->getSVFGNode(edgepair.first));
154 const StmtSVFGNode* n2 = SVFUtil::cast<StmtSVFGNode>(svfg->getSVFGNode(edgepair.second));
156 assert (n1&&n2 &&
"one node of removed pair is null");
170 if (
const_cast<NodeBS&
>(pts).test(*o))
172 const_cast<NodeBS&
>(pts).reset(*o);
179 removededges.insert(edge);
184 while(!removededges.empty())
186 SVFGEdge* edge = *removededges.begin();
187 removededges.erase(removededges.begin());
188 svfg->removeSVFGEdge(edge);
204 if (pairheadmap.find(pair) != pairheadmap.end())
205 return pairheadmap[pair];
211 assert (SVFUtil::isa<StoreSVFGNode>(svfg->getSVFGNode(*it)) &&
"prev is not a store node");
212 const StmtSVFGNode* prevNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
215 if (lockana->hasOneCxtInLockSpan(prevIns, lspan))
217 pairheadmap[pair]=
false;
221 pairheadmap[pair]=
true;
232 assert (SVFUtil::isa<StoreSVFGNode>(svfg->getSVFGNode(*it)) &&
"prev is not a store node");
233 const StmtSVFGNode* prevNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
235 if (mergespan.find(prevIns)!=mergespan.end())
245 if (headmap.find(
n) != headmap.end())
252 assert(SVFUtil::isa<StoreSVFGNode>(svfg->getSVFGNode(*it)) &&
"prev is not a store node");
253 const StmtSVFGNode* prevNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
256 if (lockana->isInSameSpan(prevIns,
n->getInst()))
273 assert((SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(svfg->getSVFGNode(*it))) &&
274 "succ is not a store/load node");
275 const StmtSVFGNode* succNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
278 if (mergespan.find(succIns)!=mergespan.end())
287 assert(SVFUtil::isa<StoreSVFGNode>(
n) &&
"Node is not a store node");
290 if (pairtailmap.find(pair) != pairtailmap.end())
291 return pairtailmap[pair];
296 assert((SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(svfg->getSVFGNode(*it))) &&
297 "succ is not a store/load node");
298 if (SVFUtil::isa<LoadSVFGNode>(svfg->getSVFGNode(*it)))
300 const StmtSVFGNode* succNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
303 if (lockana->hasOneCxtInLockSpan(succIns, lspan))
305 pairtailmap[pair]=
false;
309 pairtailmap[pair]=
true;
318 assert(SVFUtil::isa<StoreSVFGNode>(
n) &&
"Node is not a store node");
320 if (tailmap.find(
n) != tailmap.end())
327 assert((SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(svfg->getSVFGNode(*it))) &&
"succ is not a store/load node");
328 if (SVFUtil::isa<LoadSVFGNode>(svfg->getSVFGNode(*it)))
331 const StmtSVFGNode* succNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
334 if (lockana->isInSameSpan(succIns,
n->getInst()))
346 if (prevset.find(
n)!=prevset.end())
353 for (SVFGEdge::SVFGEdgeSetTy::iterator iter =
n->InEdgeBegin(); iter !=
n->InEdgeEnd(); ++iter)
362 while (!worklist.empty())
364 const SVFGNode* node = *worklist.begin();
365 worklist.erase(worklist.begin());
366 visited.insert(node);
367 if (SVFUtil::isa<StoreSVFGNode>(node))
371 for (SVFGEdge::SVFGEdgeSetTy::iterator iter = node->
InEdgeBegin(); iter != node->
InEdgeEnd(); ++iter)
384 if (succset.find(
n)!=succset.end())
391 for (SVFGEdge::SVFGEdgeSetTy::iterator iter =
n->OutEdgeBegin(); iter !=
n->OutEdgeEnd(); ++iter)
400 while (!worklist.empty())
402 const SVFGNode* node = *worklist.begin();
403 worklist.erase(worklist.begin());
404 visited.insert(node);
405 if (SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(node))
427 for (SVFGEdge::SVFGEdgeSetTy::iterator iter =
n->OutEdgeBegin(); iter !=
n->OutEdgeEnd(); ++iter)
439 while (!worklist.empty())
441 const SVFGNode* node = *worklist.begin();
442 worklist.erase(worklist.begin());
443 visited.insert(node);
444 if (SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(node))
507 if (isTailofSpan(n1) && isHeadofSpan(n2))
535 if (isTailofSpan(n1) && isHeadofSpan(n2))
537 if (isTailofSpan(n2) && isHeadofSpan(n1))
664 for (SVFGNodeSet::iterator it1 = stnodeSet.begin(), eit1 = stnodeSet.end(); it1 != eit1; ++it1)
666 const StmtSVFGNode* n1 = SVFUtil::cast<StmtSVFGNode>(*it1);
668 for (SVFGEdge::SVFGEdgeSetTy::iterator iter = n1->
InEdgeBegin(); iter != n1->
InEdgeEnd(); ++iter)
687 if (!succ2.
test(*sn1))
697 if (remove_pts.
count())
698 recordRemovingEdge(n2->
getId(), n1->
getId(), remove_pts);
703 performRemovingMHPEdges();
713 collectLoadStoreSVFGNodes();
719 for (SVFGNodeSet::const_iterator it1 = stnodeSet.begin(), eit1 = stnodeSet.end(); it1!=eit1; ++it1)
721 const StmtSVFGNode* n1 = SVFUtil::cast<StmtSVFGNode>(*it1);
724 for (SVFGNodeSet::const_iterator it2 = ldnodeSet.begin(), eit2 = ldnodeSet.end(); it2 != eit2; ++it2)
726 const StmtSVFGNode* n2 = SVFUtil::cast<StmtSVFGNode>(*it2);
733 handleStoreLoadNonSparse(n1, n2, pta);
737 handleStoreLoadNonSparse(n1, n2, pta);
742 handleStoreLoad(n1, n2, pta);
746 for (SVFGNodeSet::const_iterator it2 =
std::next(it1), eit2 = stnodeSet.end(); it2!=eit2; ++it2)
748 const StmtSVFGNode* n2 = SVFUtil::cast<StmtSVFGNode>(*it2);
755 handleStoreStoreNonSparse(n1, n2, pta);
759 handleStoreStoreNonSparse(n1, n2, pta);
764 handleStoreStore(n1, n2, pta);
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
void initialize() override
Initialize analysis.
NodeType * getSrcNode() const
NodeID getSrcID() const
get methods of the components
NodeType * getDstNode() const
IDToNodeMapTy::const_iterator const_iterator
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
bool hasOutgoingEdge() const
iterator OutEdgeBegin()
iterators
NodeID getId() const
Get ID.
const NodeBS & getPointsTo() const
bool addPointsTo(const NodeBS &c)
Handle memory region.
static u32_t numOfNewSVFGEdges
Number of newly added SVFG edges.
static u32_t numOfRemovedSVFGEdges
static u32_t numOfRemovedPTS
void performAddingMHPEdges()
perform adding/removing MHP Edges in value flow graph
void connectMHPEdges(PointerAnalysis *pta)
Connect MHP indirect value-flow edges for two nodes that may-happen-in-parallel.
void handleStoreStoreWithLockPrecisely(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
void handleStoreLoad(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
void performRemovingMHPEdges()
void handleStoreStore(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
SVFGEdge * addTDEdges(NodeID srcId, NodeID dstId, PointsTo &pts)
bool recordAddingEdge(NodeID id1, NodeID id2, PointsTo pts)
virtual void buildSVFG()
Re-write create SVFG method.
Set< const SVFGNode * > SVFGNodeSet
void collectLoadStoreSVFGNodes()
Collect all loads/stores SVFGNodes.
void readPrecision()
For o, n2-o->n1, n1 and n2 are write. Foreach n3:n1->n3, n2->n3; then remove n2->n1.
bool recordEdge(NodeID id1, NodeID id2, PointsTo pts)
Record edges.
bool isHeadofSpan(const StmtSVFGNode *n, LockAnalysis::LockSpan lspan)
whether is a first write in the lock span.
SVFGNodeIDSet getSuccNodes(const StmtSVFGNode *n)
SVFGNodeIDSet getPrevNodes(const StmtSVFGNode *n)
void handleStoreLoadNonSparse(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
void handleStoreStoreNonSparse(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
bool recordRemovingEdge(NodeID id1, NodeID id2, PointsTo pts)
void handleStoreLoadWithLockPrecisely(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Set< const SVFInstruction * > InstSet
bool isTailofSpan(const StmtSVFGNode *n, LockAnalysis::LockSpan lspan)
whether is a last write in the lock span.
void mergeSpan(NodeBS comlocks, InstSet &res)
std::pair< NodeID, NodeID > NodeIDPair
BVDataPTAImpl * getPTA() const
Return PTA.
static const Option< bool > ReadPrecisionTDEdge
static const Option< bool > UsePCG
static const Option< u32_t > AddModelFlag
virtual bool mayHappenInParallel(const SVFInstruction *i1, const SVFInstruction *i2) const
Interface to query whether two function may happen-in-parallel.
virtual bool analyze()
We start the pass here.
virtual void initialize()
Initialization of a pointer analysis, including building symbol table and SVFIR etc.
bool printStat()
Whether print statistics.
virtual const PointsTo & getPts(NodeID ptr)=0
Get points-to targets of a pointer. It needs to be implemented in child class.
virtual AliasResult alias(const SVFValue *V1, const SVFValue *V2)=0
Interface exposed to users of our pointer analysis, given Value infos.
const_iterator end() const
u32_t count() const
Returns number of elements.
void set(u32_t n)
Inserts n in the set.
NodeBS toNodeBS() const
Returns this points-to set as a NodeBS.
const_iterator begin() const
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
bool test(unsigned Idx) const
NodeID getPAGDstNodeID() const
const SVFInstruction * getInst() const
NodeID getPAGSrcNodeID() const
bool isIndirectVFGEdge() const
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
std::ostream & outs()
Overwrite llvm::outs()
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set