Static Value-Flow Analysis
FSMPTA.cpp
Go to the documentation of this file.
1 //===- FSMPTA.cpp -- Flow-sensitive analysis of multithreaded programs-------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * FSMPTA.cpp
25  *
26  * Created on: Jul 29, 2015
27  * Author: Yulei Sui, Peng Di
28  */
29 
30 #include "Util/Options.h"
31 #include "MTA/FSMPTA.h"
32 #include "MTA/MHP.h"
33 #include "MTA/PCG.h"
34 #include "MemoryModel/PointsTo.h"
35 
36 using namespace SVF;
37 using namespace SVFUtil;
38 
39 FSMPTA* FSMPTA::mfspta = nullptr;
43 
48 {
49  MemSSA* mssa = svfg->getMSSA();
50  svfg->buildSVFG();
51  if (ADDEDGE_NOEDGE != Options::AddModelFlag())
52  {
53  DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("FSMPTA adding edge\n"));
54  DBOUT(DMTA, outs() << SVFUtil::pasMsg("FSMPTA adding edge\n"));
55  connectMHPEdges(mssa->getPTA());
56  }
57  if (mssa->getPTA()->printStat())
58  svfg->performStat();
59 }
60 
65 {
66 
67  for (SVFG::const_iterator it = svfg->begin(), eit = svfg->end(); it != eit; ++it)
68  {
69  const SVFGNode* snode = it->second;
70  if (SVFUtil::isa<LoadSVFGNode>(snode))
71  {
72  const StmtSVFGNode* node = SVFUtil::cast<StmtSVFGNode>(snode);
73  if (node->getInst())
74  {
75  ldnodeSet.insert(node);
76  }
77  }
78  if (SVFUtil::isa<StoreSVFGNode>(snode))
79  {
80  const StmtSVFGNode* node = SVFUtil::cast<StmtSVFGNode>(snode);
81  if (node->getInst())
82  {
83  stnodeSet.insert(node);
84  }
85  }
86  }
87 }
89 {
90  NodeIDPair pair = std::make_pair(id1, id2);
91  if (recordedges.find(pair) == recordedges.end())
92  {
93  recordedges.insert(pair);
94  edge2pts[pair] = pts;
95  return true;
96  }
97  else
98  {
99  edge2pts[pair] |= pts;
100  }
101  return false;
102 }
104 {
105  return recordEdge(id1, id2, pts);
106 }
107 
109 {
110  return recordEdge(id1, id2, pts);
111 }
112 
114 {
115  MTASVFGBuilder::numOfNewSVFGEdges = recordedges.size();
116  while (!recordedges.empty())
117  {
118  std::pair<NodeID, NodeID> edgepair = *recordedges.begin();
119  PointsTo pts = edge2pts[edgepair];
120  recordedges.erase(recordedges.begin());
121  addTDEdges(edgepair.first, edgepair.second, pts);
122  }
123 }
124 
126 {
127 
128  SVFGNode* srcNode = svfg->getSVFGNode(srcId);
129  SVFGNode* dstNode = svfg->getSVFGNode(dstId);
130 
131  if(SVFGEdge* edge = svfg->hasThreadVFGEdge(srcNode,dstNode,SVFGEdge::TheadMHPIndirectVF))
132  {
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);
135  }
136  else
137  {
139  ThreadMHPIndSVFGEdge* indirectEdge = new ThreadMHPIndSVFGEdge(srcNode,dstNode);
140  indirectEdge->addPointsTo(pts.toNodeBS());
141  return (svfg->addSVFGEdge(indirectEdge) ? indirectEdge : nullptr);
142  }
143 }
144 
146 {
147  while (!recordedges.empty())
148  {
149  std::pair<NodeID, NodeID> edgepair = *recordedges.begin();
150  recordedges.erase(recordedges.begin());
151 
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));
155 
156  assert (n1&&n2 && "one node of removed pair is null");
157  assert (n1->hasOutgoingEdge() && "n1 doesn't have out edge");
158  assert (n2->hasIncomingEdge() && "n2 doesn't have in edge");
159 
160  Set<SVFGEdge*> removededges;
161  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = n1->OutEdgeBegin(); iter != n1->OutEdgeEnd(); ++iter)
162  {
163  SVFGEdge* edge = *iter;
164  if (edge->isIndirectVFGEdge() && (edge->getDstNode()==n2))
165  {
166  IndirectSVFGEdge* e = SVFUtil::cast<IndirectSVFGEdge>(edge);
167  const NodeBS& pts = e->getPointsTo();
168  for (PointsTo::iterator o = remove_pts.begin(), eo = remove_pts.end(); o != eo; ++o)
169  {
170  if (const_cast<NodeBS&>(pts).test(*o))
171  {
172  const_cast<NodeBS&>(pts).reset(*o);
174  }
175  }
176 
177  if (0 == e->getPointsTo().count())
178  {
179  removededges.insert(edge);
180  }
181  }
182  }
183 
184  while(!removededges.empty())
185  {
186  SVFGEdge* edge = *removededges.begin();
187  removededges.erase(removededges.begin());
188  svfg->removeSVFGEdge(edge);
189  DBOUT(DMTA,outs()<<"Read Precision remove: "<<edge->getSrcID()<<" -> "<<edge->getDstID()<<"\n");
191  }
192  }
193 }
194 
195 
202 {
203  SVFGNodeLockSpan pair(n,lspan);
204  if (pairheadmap.find(pair) != pairheadmap.end())
205  return pairheadmap[pair];
206 
207  SVFGNodeIDSet prev = getPrevNodes(n);
208 
209  for (SVFGNodeIDSet::iterator it = prev.begin(), eit = prev.end(); it != eit; ++it)
210  {
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));
213  const SVFInstruction* prevIns = prevNode->getInst();
214 
215  if (lockana->hasOneCxtInLockSpan(prevIns, lspan))
216  {
217  pairheadmap[pair]=false;
218  return false;
219  }
220  }
221  pairheadmap[pair]=true;
222  return true;
223 }
224 
226 {
227 
228  SVFGNodeIDSet prev = getPrevNodes(n);
229 
230  for (SVFGNodeIDSet::iterator it = prev.begin(), eit = prev.end(); it != eit; ++it)
231  {
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));
234  const SVFInstruction* prevIns = prevNode->getInst();
235  if (mergespan.find(prevIns)!=mergespan.end())
236  return false;
237  }
238  return true;
239 }
240 
244 {
245  if (headmap.find(n) != headmap.end())
246  return headmap[n];
247 
248  SVFGNodeIDSet prev = getPrevNodes(n);
249 
250  for (SVFGNodeIDSet::iterator it = prev.begin(), eit = prev.end(); it != eit; ++it)
251  {
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));
254  const SVFInstruction* prevIns = prevNode->getInst();
255 
256  if (lockana->isInSameSpan(prevIns, n->getInst()))
257  {
258  headmap[n]=false;
259  return false;
260  }
261  }
262  headmap[n]=true;
263  return true;
264 }
265 
267 {
268 
269  SVFGNodeIDSet succ = getSuccNodes(n);
270 
271  for (SVFGNodeIDSet::iterator it = succ.begin(), eit = succ.end(); it != eit; ++it)
272  {
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));
276  const SVFInstruction* succIns = succNode->getInst();
277 
278  if (mergespan.find(succIns)!=mergespan.end())
279  return false;
280  }
281  return true;
282 }
283 
286 {
287  assert(SVFUtil::isa<StoreSVFGNode>(n) && "Node is not a store node");
288 
289  SVFGNodeLockSpan pair(n,lspan);
290  if (pairtailmap.find(pair) != pairtailmap.end())
291  return pairtailmap[pair];
292 
293  SVFGNodeIDSet succ = getSuccNodes(n);
294  for (SVFGNodeIDSet::iterator it = succ.begin(), eit = succ.end(); it != eit; ++it)
295  {
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)))
299  continue;
300  const StmtSVFGNode* succNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
301  const SVFInstruction* succIns = succNode->getInst();
302 
303  if (lockana->hasOneCxtInLockSpan(succIns, lspan))
304  {
305  pairtailmap[pair]=false;
306  return false;
307  }
308  }
309  pairtailmap[pair]=true;
310  return true;
311 }
312 
313 
317 {
318  assert(SVFUtil::isa<StoreSVFGNode>(n) && "Node is not a store node");
319 
320  if (tailmap.find(n) != tailmap.end())
321  return tailmap[n];
322 
323  SVFGNodeIDSet succ = getSuccNodes(n);
324 
325  for (SVFGNodeIDSet::iterator it = succ.begin(), eit = succ.end(); it != eit; ++it)
326  {
327  assert((SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(svfg->getSVFGNode(*it))) && "succ is not a store/load node");
328  if (SVFUtil::isa<LoadSVFGNode>(svfg->getSVFGNode(*it)))
329  continue;
330 
331  const StmtSVFGNode* succNode = SVFUtil::dyn_cast<StmtSVFGNode>(svfg->getSVFGNode(*it));
332  const SVFInstruction* succIns = succNode->getInst();
333 
334  if (lockana->isInSameSpan(succIns, n->getInst()))
335  {
336  tailmap[n] = false;
337  return false;
338  }
339  }
340  tailmap[n]=true;
341  return true;
342 }
343 
345 {
346  if (prevset.find(n)!=prevset.end())
347  return prevset[n];
348 
350  SVFGNodeSet worklist;
351  SVFGNodeSet visited;
352 
353  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = n->InEdgeBegin(); iter != n->InEdgeEnd(); ++iter)
354  {
355  SVFGEdge* edge = *iter;
356  if (edge->isIndirectVFGEdge())
357  {
358  worklist.insert(edge->getSrcNode());
359  }
360  }
361 
362  while (!worklist.empty())
363  {
364  const SVFGNode* node = *worklist.begin();
365  worklist.erase(worklist.begin());
366  visited.insert(node);
367  if (SVFUtil::isa<StoreSVFGNode>(node))
368  prev.set(node->getId());
369  else
370  {
371  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = node->InEdgeBegin(); iter != node->InEdgeEnd(); ++iter)
372  {
373  SVFGEdge* edge = *iter;
374  if (edge->isIndirectVFGEdge() && visited.find(edge->getSrcNode())==visited.end())
375  worklist.insert(edge->getSrcNode());
376  }
377  }
378  }
379  prevset[n]=prev;
380  return prev;
381 }
383 {
384  if (succset.find(n)!=succset.end())
385  return succset[n];
386 
387  SVFGNodeIDSet succ;
388  SVFGNodeSet worklist;
389  SVFGNodeSet visited;
390 
391  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = n->OutEdgeBegin(); iter != n->OutEdgeEnd(); ++iter)
392  {
393  SVFGEdge* edge = *iter;
394  if (edge->isIndirectVFGEdge())
395  {
396  worklist.insert(edge->getDstNode());
397  }
398  }
399 
400  while (!worklist.empty())
401  {
402  const SVFGNode* node = *worklist.begin();
403  worklist.erase(worklist.begin());
404  visited.insert(node);
405  if (SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(node))
406  succ.set(node->getId());
407  else
408  {
409  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = node->OutEdgeBegin(); iter != node->OutEdgeEnd(); ++iter)
410  {
411  SVFGEdge* edge = *iter;
412  if (edge->isIndirectVFGEdge() && visited.find(edge->getDstNode()) == visited.end())
413  worklist.insert(edge->getDstNode());
414  }
415  }
416  }
417  succset[n]=succ;
418  return succ;
419 }
421 {
422 
423  SVFGNodeIDSet succ;
424  SVFGNodeSet worklist;
425  SVFGNodeSet visited;
426 
427  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = n->OutEdgeBegin(); iter != n->OutEdgeEnd(); ++iter)
428  {
429  SVFGEdge* edge = *iter;
430  if (edge->isIndirectVFGEdge())
431  {
432  IndirectSVFGEdge* e = SVFUtil::cast<IndirectSVFGEdge>(edge);
433  NodeBS pts = e->getPointsTo();
434  if(pts.test(o))
435  worklist.insert(edge->getDstNode());
436  }
437  }
438 
439  while (!worklist.empty())
440  {
441  const SVFGNode* node = *worklist.begin();
442  worklist.erase(worklist.begin());
443  visited.insert(node);
444  if (SVFUtil::isa<StoreSVFGNode, LoadSVFGNode>(node))
445  succ.set(node->getId());
446  else
447  {
448  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = node->OutEdgeBegin(); iter != node->OutEdgeEnd(); ++iter)
449  {
450  SVFGEdge* edge = *iter;
451  if (edge->isIndirectVFGEdge() && visited.find(edge->getDstNode()) == visited.end())
452  {
453  IndirectSVFGEdge* e = SVFUtil::cast<IndirectSVFGEdge>(edge);
454  NodeBS pts = e->getPointsTo();
455  if(pts.test(o))
456  worklist.insert(edge->getDstNode());
457  }
458  }
459  }
460  }
461 
462  return succ;
463 }
464 
466 {
467  PointsTo pts = pta->getPts(n1->getPAGDstNodeID());
468  pts &= pta->getPts(n2->getPAGSrcNodeID());
469 
470  addTDEdges(n1->getId(), n2->getId(), pts);
471 }
472 
473 
474 
476 {
477  PointsTo pts = pta->getPts(n1->getPAGDstNodeID());
478  pts &= pta->getPts(n2->getPAGDstNodeID());
479 
480  addTDEdges(n1->getId(), n2->getId(), pts);
481  addTDEdges(n2->getId(), n1->getId(), pts);
482 }
483 
485 {
486  const SVFInstruction* i1 = n1->getInst();
487  const SVFInstruction* i2 = n2->getInst();
489  if (ADDEDGE_NOMHP!=Options::AddModelFlag() && !mhp->mayHappenInParallel(i1, i2))
490  return;
492  if (ADDEDGE_NOALIAS!=Options::AddModelFlag() && !pta->alias(n1->getPAGDstNodeID(), n2->getPAGSrcNodeID()))
493  return;
494 
495 
496  PointsTo pts = pta->getPts(n1->getPAGDstNodeID());
497  pts &= pta->getPts(n2->getPAGSrcNodeID());
498 
503 
504 
505  if (ADDEDGE_NOLOCK!=Options::AddModelFlag() && lockana->isProtectedByCommonLock(i1, i2))
506  {
507  if (isTailofSpan(n1) && isHeadofSpan(n2))
508  addTDEdges(n1->getId(), n2->getId(), pts);
509  }
510  else
511  {
512  addTDEdges(n1->getId(), n2->getId(), pts);
513  }
514 }
515 
516 
517 
519 {
520  const SVFInstruction* i1 = n1->getInst();
521  const SVFInstruction* i2 = n2->getInst();
523  if (ADDEDGE_NOMHP!=Options::AddModelFlag() && !mhp->mayHappenInParallel(i1, i2))
524  return;
526  if (ADDEDGE_NOALIAS!=Options::AddModelFlag() && !pta->alias(n1->getPAGDstNodeID(), n2->getPAGDstNodeID()))
527  return;
528 
529  PointsTo pts = pta->getPts(n1->getPAGDstNodeID());
530  pts &= pta->getPts(n2->getPAGDstNodeID());
531 
533  if (ADDEDGE_NOLOCK!=Options::AddModelFlag() && lockana->isProtectedByCommonLock(i1, i2))
534  {
535  if (isTailofSpan(n1) && isHeadofSpan(n2))
536  addTDEdges(n1->getId(), n2->getId(), pts);
537  if (isTailofSpan(n2) && isHeadofSpan(n1))
538  addTDEdges(n2->getId(), n1->getId(), pts);
539  }
540  else
541  {
542  addTDEdges(n1->getId(), n2->getId(), pts);
543  addTDEdges(n2->getId(), n1->getId(), pts);
544  }
545 }
546 
548 {
549  if (!pta->alias(n1->getPAGDstNodeID(), n2->getPAGSrcNodeID()))
550  return;
551 
552 // PointsTo pts = pta->getPts(n1->getPAGDstNodeID());
553 // pts &= pta->getPts(n2->getPAGSrcNodeID());
554 //
555 // const SVFInstruction* i1 = n1->getInst();
556 // const SVFInstruction* i2 = n2->getInst();
557 //
558 // NodeBS comlocks1;
559 // NodeBS comlocks2;
560 // lockana->getCommonLocks(i1, i2, comlocks1, comlocks2);
561 //
562 // outs()<<comlocks1.count() << " "<< comlocks2.count()<<"\n";
563 
564 
565 // if(comlocks1.count() && comlocks2.count()) {
566 // bool n1istail = false;
567 // for (NodeBS::iterator it1 = comlocks1.begin(), ie1 = comlocks1.end(); it1 != ie1; ++it1) {
568 // LockAnalysis::LockSpan lspan1 = lockana->getSpanfromCxtLock(*it1);
569 // /// exist lock span, n1 is tail;
570 // if (isTailofSpan(n1, lspan1))
571 // n1istail = true;
572 // }
573 //
574 // bool n2ishead = false;
575 // for (NodeBS::iterator it2 = comlocks2.begin(), ie2 = comlocks2.end(); it2 != ie2; ++it2) {
576 // LockAnalysis::LockSpan lspan2 = lockana->getSpanfromCxtLock(*it2);
577 // /// exist lock span, n2 is head;
578 // if (isHeadofSpan(n2, lspan2))
579 // n2ishead = true;
580 // }
581 //
582 // if (n1istail && n2ishead)
583 // addTDEdges(n1->getId(), n2->getId(), pts);
584 // } else {
585 // addTDEdges(n1->getId(), n2->getId(), pts);
586 // }
587 }
589 {
590  if (!pta->alias(n1->getPAGDstNodeID(), n2->getPAGDstNodeID()))
591  return;
592 
593 // PointsTo pts = pta->getPts(n1->getPAGDstNodeID());
594 // pts &= pta->getPts(n2->getPAGDstNodeID());
595 //
596 // const SVFInstruction* i1 = n1->getInst();
597 // const SVFInstruction* i2 = n2->getInst();
598 
599 
600 // NodeBS comlocks1;
601 // NodeBS comlocks2;
602 // lockana->getCommonLocks(i1, i2, comlocks1, comlocks2);
603 // if(comlocks1.count() && comlocks2.count()) {
604 // bool n1istail = false;
605 // for (NodeBS::iterator it1 = comlocks1.begin(), ie1 = comlocks1.end(); it1 != ie1; ++it1) {
606 // LockAnalysis::LockSpan lspan1 = lockana->getSpanfromCxtLock(*it1);
607 // /// exist lock span, n1 is tail;
608 // if (isTailofSpan(n1, lspan1))
609 // n1istail = true;
610 // }
611 // bool n2ishead = false;
612 // for (NodeBS::iterator it2 = comlocks2.begin(), ie2 = comlocks2.end(); it2 != ie2; ++it2) {
613 // LockAnalysis::LockSpan lspan2 = lockana->getSpanfromCxtLock(*it2);
614 // /// exist lock span, n2 is head;
615 // if (isHeadofSpan(n2, lspan2))
616 // n2ishead = true;
617 // }
618 // if (n1istail && n2ishead)
619 // addTDEdges(n1->getId(), n2->getId(), pts);
620 //
621 //
622 //
623 // bool n2istail = false;
624 // for (NodeBS::iterator it2 = comlocks2.begin(), ie2 = comlocks2.end(); it2 != ie2; ++it2) {
625 // LockAnalysis::LockSpan lspan2 = lockana->getSpanfromCxtLock(*it2);
626 // /// exist lock span, n2 is tail;
627 // if (isTailofSpan(n2, lspan2))
628 // n2istail = true;
629 // }
630 // bool n1ishead = false;
631 // for (NodeBS::iterator it1 = comlocks1.begin(), ie1 = comlocks1.end(); it1 != ie1; ++it1) {
632 // LockAnalysis::LockSpan lspan1 = lockana->getSpanfromCxtLock(*it1);
633 // /// exist lock span, n1 is head;
634 // if (isHeadofSpan(n1, lspan1))
635 // n1ishead = true;
636 // }
637 // if (n2istail && n1ishead)
638 // addTDEdges(n2->getId(), n1->getId(), pts);
639 //
640 // } else {
641 // addTDEdges(n1->getId(), n2->getId(), pts);
642 // addTDEdges(n2->getId(), n1->getId(), pts);
643 // }
644 }
645 
646 
648 {
649 // for (NodeBS::iterator it = comlocks.begin(), ie = comlocks.end(); it != ie; ++it) {
650 // LockAnalysis::LockSpan lspan = lockana->getSpanfromCxtLock(*it);
651 // for (LockAnalysis::LockSpan::const_iterator cts = lspan.begin(), ects = lspan.end(); cts!=ects; ++cts) {
652 // res.insert((*cts).getStmt());
653 // }
654 // }
655 }
656 
659 {
660 
661  recordedges.clear();
662  edge2pts.clear();
663 
664  for (SVFGNodeSet::iterator it1 = stnodeSet.begin(), eit1 = stnodeSet.end(); it1 != eit1; ++it1)
665  {
666  const StmtSVFGNode* n1 = SVFUtil::cast<StmtSVFGNode>(*it1);
667 
668  for (SVFGEdge::SVFGEdgeSetTy::iterator iter = n1->InEdgeBegin(); iter != n1->InEdgeEnd(); ++iter)
669  {
670  SVFGEdge* edge = *iter;
671  if (edge->isIndirectVFGEdge() && SVFUtil::isa<StoreSVFGNode>(edge->getSrcNode()))
672  {
673  const StmtSVFGNode* n2 = SVFUtil::cast<StmtSVFGNode>(edge->getSrcNode());
674 
675  IndirectSVFGEdge* e = SVFUtil::cast<IndirectSVFGEdge>(edge);
676  NodeBS pts = e->getPointsTo();
677  PointsTo remove_pts;
678 
679  for (NodeBS::iterator o = pts.begin(), eo = pts.end(); o != eo; ++o)
680  {
681  SVFGNodeIDSet succ1 = getSuccNodes(n1, *o);
682  SVFGNodeIDSet succ2 = getSuccNodes(n2, *o);
683 
684  bool remove = true;
685  for (SVFGNodeIDSet::iterator sn1 = succ1.begin(), esn1 = succ1.end(); sn1 != esn1; sn1++)
686  {
687  if (!succ2.test(*sn1))
688  {
689  remove = false;
690  break;
691  }
692  }
693  if (remove)
694  remove_pts.set(*o);
695  }
696 
697  if (remove_pts.count())
698  recordRemovingEdge(n2->getId(), n1->getId(), remove_pts);
699  }
700  }
701  }
702 
703  performRemovingMHPEdges();
704 }
705 
707 {
708  PCG* pcg = new PCG(pta);
709  if ((ADDEDGE_NONSPARSE==Options::AddModelFlag()) && Options::UsePCG())
710  {
711  pcg->analyze();
712  }
713  collectLoadStoreSVFGNodes();
714  recordedges.clear();
715  edge2pts.clear();
716 
719  for (SVFGNodeSet::const_iterator it1 = stnodeSet.begin(), eit1 = stnodeSet.end(); it1!=eit1; ++it1)
720  {
721  const StmtSVFGNode* n1 = SVFUtil::cast<StmtSVFGNode>(*it1);
722  const SVFInstruction* i1 = n1->getInst();
723 
724  for (SVFGNodeSet::const_iterator it2 = ldnodeSet.begin(), eit2 = ldnodeSet.end(); it2 != eit2; ++it2)
725  {
726  const StmtSVFGNode* n2 = SVFUtil::cast<StmtSVFGNode>(*it2);
727  const SVFInstruction* i2 = n2->getInst();
728  if (ADDEDGE_NONSPARSE==Options::AddModelFlag())
729  {
730  if (Options::UsePCG())
731  {
732  if (pcg->mayHappenInParallel(i1, i2) || mhp->mayHappenInParallel(i1, i2))
733  handleStoreLoadNonSparse(n1, n2, pta);
734  }
735  else
736  {
737  handleStoreLoadNonSparse(n1, n2, pta);
738  }
739  }
740  else
741  {
742  handleStoreLoad(n1, n2, pta);
743  }
744  }
745 
746  for (SVFGNodeSet::const_iterator it2 = std::next(it1), eit2 = stnodeSet.end(); it2!=eit2; ++it2)
747  {
748  const StmtSVFGNode* n2 = SVFUtil::cast<StmtSVFGNode>(*it2);
749  const SVFInstruction* i2 = n2->getInst();
750  if (ADDEDGE_NONSPARSE == Options::AddModelFlag())
751  {
752  if (Options::UsePCG())
753  {
754  if(pcg->mayHappenInParallel(i1, i2) || mhp->mayHappenInParallel(i1, i2))
755  handleStoreStoreNonSparse(n1, n2, pta);
756  }
757  else
758  {
759  handleStoreStoreNonSparse(n1, n2, pta);
760  }
761  }
762  else
763  {
764  handleStoreStore(n1, n2, pta);
765  }
766  }
767  }
768 
769  if(Options::ReadPrecisionTDEdge() && ADDEDGE_NORP!=Options::AddModelFlag())
770  {
771  DBOUT(DGENERAL,outs()<<"Read precision edge removing \n");
772  DBOUT(DMTA,outs()<<"Read precision edge removing \n");
773  readPrecision();
774  }
775 }
776 
781 {
783 
785  MTASVFGBuilder mtaSVFGBuilder(mhp,lockana);
786  svfg = mtaSVFGBuilder.buildPTROnlySVFG(ander);
787  setGraph(svfg);
788  //AndersenWaveDiff::releaseAndersenWaveDiff();
789 
790  stat = new FlowSensitiveStat(this);
791 }
792 
unsigned u32_t
Definition: CommandLine.h:18
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition: SVFType.h:484
#define DMTA
Definition: SVFType.h:505
#define DGENERAL
Definition: SVFType.h:490
item next
Definition: cJSON.cpp:2224
newitem prev
Definition: cJSON.cpp:2285
cJSON * n
Definition: cJSON.cpp:2558
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition: Andersen.h:395
void initialize() override
Initialize analysis.
static FSMPTA * mfspta
Definition: FSMPTA.h:252
NodeType * getSrcNode() const
Definition: GenericGraph.h:97
NodeID getDstID() const
Definition: GenericGraph.h:85
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:81
NodeType * getDstNode() const
Definition: GenericGraph.h:101
IDToNodeMapTy::const_iterator const_iterator
Definition: GenericGraph.h:360
bool hasIncomingEdge() const
Has incoming/outgoing edge set.
Definition: GenericGraph.h:205
bool hasOutgoingEdge() const
Definition: GenericGraph.h:209
iterator OutEdgeEnd()
Definition: GenericGraph.h:221
iterator OutEdgeBegin()
iterators
Definition: GenericGraph.h:217
NodeID getId() const
Get ID.
Definition: GenericGraph.h:180
iterator InEdgeBegin()
Definition: GenericGraph.h:225
iterator InEdgeEnd()
Definition: GenericGraph.h:229
const NodeBS & getPointsTo() const
Definition: SVFGEdge.h:60
bool addPointsTo(const NodeBS &c)
Handle memory region.
Definition: SVFGEdge.h:56
Set< CxtStmt > LockSpan
Definition: LockAnalysis.h:68
static u32_t numOfNewSVFGEdges
Number of newly added SVFG edges.
Definition: FSMPTA.h:120
static u32_t numOfRemovedSVFGEdges
Definition: FSMPTA.h:121
static u32_t numOfRemovedPTS
Definition: FSMPTA.h:122
void performAddingMHPEdges()
perform adding/removing MHP Edges in value flow graph
Definition: FSMPTA.cpp:113
void connectMHPEdges(PointerAnalysis *pta)
Connect MHP indirect value-flow edges for two nodes that may-happen-in-parallel.
Definition: FSMPTA.cpp:706
void handleStoreStoreWithLockPrecisely(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Definition: FSMPTA.cpp:588
void handleStoreLoad(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Definition: FSMPTA.cpp:484
void performRemovingMHPEdges()
Definition: FSMPTA.cpp:145
void handleStoreStore(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Definition: FSMPTA.cpp:518
SVFGEdge * addTDEdges(NodeID srcId, NodeID dstId, PointsTo &pts)
Definition: FSMPTA.cpp:125
bool recordAddingEdge(NodeID id1, NodeID id2, PointsTo pts)
Definition: FSMPTA.cpp:103
virtual void buildSVFG()
Re-write create SVFG method.
Definition: FSMPTA.cpp:47
Set< const SVFGNode * > SVFGNodeSet
Definition: FSMPTA.h:104
void collectLoadStoreSVFGNodes()
Collect all loads/stores SVFGNodes.
Definition: FSMPTA.cpp:64
void readPrecision()
For o, n2-o->n1, n1 and n2 are write. Foreach n3:n1->n3, n2->n3; then remove n2->n1.
Definition: FSMPTA.cpp:658
bool recordEdge(NodeID id1, NodeID id2, PointsTo pts)
Record edges.
Definition: FSMPTA.cpp:88
bool isHeadofSpan(const StmtSVFGNode *n, LockAnalysis::LockSpan lspan)
whether is a first write in the lock span.
Definition: FSMPTA.cpp:201
SVFGNodeIDSet getSuccNodes(const StmtSVFGNode *n)
Definition: FSMPTA.cpp:382
SVFGNodeIDSet getPrevNodes(const StmtSVFGNode *n)
Definition: FSMPTA.cpp:344
void handleStoreLoadNonSparse(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Definition: FSMPTA.cpp:465
void handleStoreStoreNonSparse(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Definition: FSMPTA.cpp:475
bool recordRemovingEdge(NodeID id1, NodeID id2, PointsTo pts)
Definition: FSMPTA.cpp:108
void handleStoreLoadWithLockPrecisely(const StmtSVFGNode *n1, const StmtSVFGNode *n2, PointerAnalysis *pta)
Definition: FSMPTA.cpp:547
Set< const SVFInstruction * > InstSet
Definition: FSMPTA.h:107
bool isTailofSpan(const StmtSVFGNode *n, LockAnalysis::LockSpan lspan)
whether is a last write in the lock span.
Definition: FSMPTA.cpp:285
void mergeSpan(NodeBS comlocks, InstSet &res)
Definition: FSMPTA.cpp:647
std::pair< NodeID, NodeID > NodeIDPair
Definition: FSMPTA.h:108
BVDataPTAImpl * getPTA() const
Return PTA.
Definition: MemSSA.h:308
static const Option< bool > ReadPrecisionTDEdge
Definition: Options.h:157
static const Option< bool > UsePCG
Definition: Options.h:155
static const Option< u32_t > AddModelFlag
Definition: Options.h:158
Definition: PCG.h:51
virtual bool mayHappenInParallel(const SVFInstruction *i1, const SVFInstruction *i2) const
Interface to query whether two function may happen-in-parallel.
Definition: PCG.cpp:83
virtual bool analyze()
We start the pass here.
Definition: PCG.cpp:49
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
Definition: PointsTo.h:132
u32_t count() const
Returns number of elements.
Definition: PointsTo.cpp:111
void set(u32_t n)
Inserts n in the set.
Definition: PointsTo.cpp:157
NodeBS toNodeBS() const
Returns this points-to set as a NodeBS.
Definition: PointsTo.cpp:313
const_iterator begin() const
Definition: PointsTo.h:128
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
Definition: SVFGBuilder.cpp:41
bool test(unsigned Idx) const
iterator end() const
void set(unsigned Idx)
unsigned count() const
iterator begin() const
NodeID getPAGDstNodeID() const
Definition: VFGNode.h:146
const SVFInstruction * getInst() const
Definition: VFGNode.h:185
NodeID getPAGSrcNodeID() const
Definition: VFGNode.h:141
@ TheadMHPIndirectVF
Definition: VFGEdge.h:59
bool isIndirectVFGEdge() const
Definition: VFGEdge.h:80
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition: SVFUtil.cpp:99
std::ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:50
for isBitcode
Definition: BasicTypes.h:68
unsigned NodeID
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96