Static Value-Flow Analysis
Loading...
Searching...
No Matches
DDAVFSolver.h
Go to the documentation of this file.
1//===- DDAVFSolver.h -- Demand-driven analysis value-flow solver------------//
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 * DDAVFSolver.h
25 *
26 * Created on: Jul 3, 2014
27 * Author: Yulei Sui
28 */
29
30#ifndef VALUEFLOWDDA_H_
31#define VALUEFLOWDDA_H_
32
33#include <algorithm>
34
35#include "DDA/DDAStat.h"
36#include "Graphs/SCC.h"
37#include "MSSA/SVFGBuilder.h"
39#include "WPA/Andersen.h"
40#include "Util/GeneralType.h"
41
42namespace SVF
43{
44
48template<class CVar, class CPtSet, class DPIm>
50{
51 friend class DDAStat;
52public:
65
71 virtual ~DDAVFSolver()
72 {
73 if(_ander != nullptr)
74 {
75 // AndersenWaveDiff::releaseAndersenWaveDiff();
76 _ander = nullptr;
77 }
78
79 if (_svfg != nullptr)
80 {
81 // DDASVFGBuilder::releaseDDASVFG();
82 _svfg = nullptr;
83 }
84
85 if (_svfgSCC != nullptr)
86 delete _svfgSCC;
87 _svfgSCC = nullptr;
88
89 _callGraph = nullptr;
90 _callGraphSCC = nullptr;
91 }
94 {
95 return candidateQueries;
96 }
98 virtual inline DPIm getDPIm(const CVar& var, const SVFGNode* loc) const
99 {
100 DPIm dpm(var,loc);
101 return dpm;
102 }
104 virtual bool unionDDAPts(CPtSet& pts, const CPtSet& targetPts)
105 {
106 return (pts |= targetPts);
107 }
109 virtual bool unionDDAPts(DPIm dpm, const CPtSet& targetPts)
110 {
112 return pts |= targetPts;
113 }
115 virtual void addDDAPts(CPtSet& pts, const CVar& var)
116 {
117 pts.set(var);
118 }
120 inline SVFG* getSVFG() const
121 {
122 return _svfg;
123 }
125 inline SVFGSCC* getSVFGSCC() const
126 {
127 return _svfgSCC;
128 }
129 // Dump cptsSet
130 inline void dumpCPtSet(const CPtSet& cpts) const
131 {
132 SVFUtil::outs() << "{";
133 for(typename CPtSet::iterator it = cpts.begin(), eit = cpts.end(); it!=eit; ++it)
134 {
135 SVFUtil::outs() << (*it) << " ";
136 }
137 SVFUtil::outs() << "}\n";
138 }
140 virtual const CPtSet& findPT(const DPIm& dpm)
141 {
142
143 if(isbkVisited(dpm))
144 {
145 const CPtSet& cpts = getCachedPointsTo(dpm);
146 DBOUT(DDDA, SVFUtil::outs() << "\t already backward visited dpm: ");
147 DBOUT(DDDA, dpm.dump());
148 DBOUT(DDDA, SVFUtil::outs() << "\t return points-to: ");
149 DBOUT(DDDA, dumpCPtSet(cpts));
150 return cpts;
151 }
152
153 DBOUT(DDDA, SVFUtil::outs() << "\t backward visit dpm: ");
154 DBOUT(DDDA, dpm.dump());
157
158 if(testOutOfBudget(dpm) == false)
159 {
160
161 CPtSet pts;
163
166 }
167 return getCachedPointsTo(dpm);
168 }
169
170protected:
172 virtual void handleSingleStatement(const DPIm& dpm, CPtSet& pts)
173 {
176
177 const SVFGNode* node = dpm.getLoc();
178 if(SVFUtil::isa<AddrSVFGNode>(node))
179 {
180 handleAddr(pts,dpm,SVFUtil::cast<AddrSVFGNode>(node));
181 }
185 {
187 }
188 else if(SVFUtil::isa<GepSVFGNode>(node))
189 {
190 CPtSet gepPts;
192 unionDDAPts(pts, processGepPts(SVFUtil::cast<GepSVFGNode>(node),gepPts));
193 }
194 else if(const LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
195 {
196 if(load->getDstNode()->isPointer() == false)
197 return;
198
199 CPtSet loadpts;
201 for(typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it)
202 {
204 }
205 }
206 else if(const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
207 {
208 if(store->getSrcNode()->isPointer() == false)
209 return;
210
212 {
213 DBOUT(DDDA, SVFUtil::outs() << "+++must alias for load and store:");
215 DBOUT(DDDA, dpm.dump());
216 DBOUT(DDDA, SVFUtil::outs() << "+++\n");
219 }
220 else
221 {
222 CPtSet storepts;
224 for(typename CPtSet::iterator it = storepts.begin(), eit = storepts.end(); it!=eit; ++it)
225 {
227 {
229
230 if(isStrongUpdate(storepts,store))
231 {
232 DBOUT(DDDA, SVFUtil::outs() << "backward strong update for obj " << dpm.getCurNodeID() << "\n");
233 DOSTAT(addSUStat(dpm,store);)
234 }
235 else
236 {
237 DOSTAT(rmSUStat(dpm,store);)
239 }
240 }
241 else
242 {
244 }
245 }
246 }
247 }
248 else if(SVFUtil::isa<MRSVFGNode>(node))
249 {
251 }
252 else
253 assert(false && "unexpected kind of SVFG nodes");
254 }
255
257 void reCompute(const DPIm& dpm)
258 {
261 if(_pag->isFunPtr(dpm.getCurNodeID()))
262 {
263 const CallSiteSet& csSet = _pag->getIndCallSites(dpm.getCurNodeID());
264 for(CallSiteSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
266 }
268 if(!newIndirectEdges.empty())
269 _callGraphSCC->find();
271
273 SVFGEdgeSet edgeSet(dpm.getLoc()->getOutEdges());
275 }
276
278 void reComputeForEdges(const DPIm& dpm, const SVFGEdgeSet& edgeSet, bool indirectCall = false)
279 {
280 for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
281 {
282 const SVFGEdge* edge = *it;
283 const SVFGNode* dst = edge->getDstNode();
284 typename LocToDPMVecMap::const_iterator locIt = getLocToDPMVecMap().find(dst->getId());
286 if (locIt == getLocToDPMVecMap().end())
287 continue;
288 DPTItemSet dpmSet(locIt->second.begin(), locIt->second.end());
289 for(typename DPTItemSet::const_iterator it = dpmSet.begin(),eit = dpmSet.end(); it!=eit; ++it)
290 {
291 const DPIm& dstDpm = *it;
292 if(!indirectCall && SVFUtil::isa<IndirectSVFGEdge>(edge) && !SVFUtil::isa<LoadSVFGNode>(edge->getDstNode()))
293 {
294 if(dstDpm.getCurNodeID() == dpm.getCurNodeID())
295 {
296 DBOUT(DDDA,SVFUtil::outs() << "\t Recompute, forward from :");
297 DBOUT(DDDA, dpm.dump());
300 findPT(dstDpm);
301 }
302 }
303 else
304 {
305 if(indirectCall)
306 DBOUT(DDDA,SVFUtil::outs() << "\t Recompute for indirect call from :");
307 else
308 DBOUT(DDDA,SVFUtil::outs() << "\t Recompute forward from :");
309 DBOUT(DDDA, dpm.dump());
312 findPT(dstDpm);
313 }
314 }
315 }
316 }
317
319 virtual inline void buildSVFG(SVFIR* pag)
320 {
323 _pag = _svfg->getPAG();
324 }
326 virtual inline void resetQuery()
327 {
330
331 locToDpmSetMap.clear();
332 dpmToloadDpmMap.clear();
333 loadToPTCVarMap.clear();
334 outOfBudgetQuery = false;
335 ddaStat->_NumOfStep = 0;
336 }
338 inline void OOBResetVisited()
339 {
340 for(typename LocToDPMVecMap::const_iterator it = locToDpmSetMap.begin(),eit = locToDpmSetMap.end(); it!=eit; ++it)
341 {
342 DPTItemSet dpmSet(it->second.begin(), it->second.end());
343 for(typename DPTItemSet::const_iterator dit = dpmSet.begin(),deit=dpmSet.end(); dit!=deit; ++dit)
344 if(isOutOfBudgetDpm(*dit)==false)
346 }
347 }
349 inline const SVFGNode* getDefSVFGNode(const ValVar* valVar) const
350 {
351 return getSVFG()->getDefSVFGNode(valVar);
352 }
354 void backtraceAlongIndirectVF(CPtSet& pts, const DPIm& oldDpm)
355 {
356 const SVFGNode* node = oldDpm.getLoc();
357 NodeID obj = oldDpm.getCurNodeID();
358 if (_pag->isConstantObj(obj))
359 return;
360 const SVFGEdgeSet edgeSet(node->getInEdges());
361 for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
362 {
363 if(const IndirectSVFGEdge* indirEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
364 {
365 const NodeBS& guard = indirEdge->getPointsTo();
366 if(guard.test(obj))
367 {
368 DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace indirectVF svfgNode " <<
369 indirEdge->getDstID() << " --> " << indirEdge->getSrcID() << "\n");
370 backwardPropDpm(pts,oldDpm.getCurNodeID(),oldDpm,indirEdge);
371 }
372 }
373 }
374 }
376 void backtraceAlongDirectVF(CPtSet& pts, const DPIm& oldDpm)
377 {
378 const SVFGNode* node = oldDpm.getLoc();
379 const SVFGEdgeSet edgeSet(node->getInEdges());
380 for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
381 {
382 if(const DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast<DirectSVFGEdge>(*it))
383 {
384 DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace directVF svfgNode " <<
385 dirEdge->getDstID() << " --> " << dirEdge->getSrcID() << "\n");
386 const SVFGNode* srcNode = dirEdge->getSrcNode();
387 backwardPropDpm(pts,getSVFG()->getLHSTopLevPtr(srcNode)->getId(),oldDpm,dirEdge);
388 }
389 }
390 }
391
394 inline void startNewPTCompFromLoadSrc(CPtSet& pts, const DPIm& oldDpm)
395 {
396 const LoadSVFGNode* load = SVFUtil::cast<LoadSVFGNode>(oldDpm.getLoc());
397 const SVFGNode* loadSrc = getDefSVFGNode(load->getSrcNode());
398 DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from loadSrc svfgNode " <<
399 load->getId() << " --> " << loadSrc->getId() << "\n");
401 assert(edge && "Edge not found!!");
403
404 }
405 inline void startNewPTCompFromStoreDst(CPtSet& pts, const DPIm& oldDpm)
406 {
407 const StoreSVFGNode* store = SVFUtil::cast<StoreSVFGNode>(oldDpm.getLoc());
408 const SVFGNode* storeDst = getDefSVFGNode(store->getDstNode());
409 DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from storeDst svfgNode " <<
410 store->getId() << " --> " << storeDst->getId() << "\n");
412 assert(edge && "Edge not found!!");
414 }
415 inline void backtraceToStoreSrc(CPtSet& pts, const DPIm& oldDpm)
416 {
417 const StoreSVFGNode* store = SVFUtil::cast<StoreSVFGNode>(oldDpm.getLoc());
418 const SVFGNode* storeSrc = getDefSVFGNode(store->getSrcNode());
419 DBOUT(DDDA, SVFUtil::outs() << "++backtrace to storeSrc from svfgNode " << getLoadDpm(oldDpm).getLoc()->getId() << " to "<<
420 store->getId() << " to " << storeSrc->getId() <<"\n");
422 assert(edge && "Edge not found!!");
424 }
426
428 virtual void backwardPropDpm(CPtSet& pts, NodeID ptr,const DPIm& oldDpm,const SVFGEdge* edge)
429 {
430 DPIm dpm(oldDpm);
431 dpm.setLocVar(edge->getSrcNode(),ptr);
432 DOTIMESTAT(double start = DDAStat::getClk(true));
434 if(handleBKCondition(dpm,edge)==false)
435 {
437 DBOUT(DDDA, SVFUtil::outs() << "\t!!! infeasible path svfgNode: " << edge->getDstID() << " --| " << edge->getSrcID() << "\n");
439 return;
440 }
441
443 if(SVFUtil::isa<IndirectSVFGEdge>(edge))
445
449 }
451 virtual bool isMustAlias(const DPIm&, const DPIm&)
452 {
453 return false;
454 }
456 virtual bool isStrongUpdate(const CPtSet& dstCPSet, const StoreSVFGNode* store)
457 {
458 if (dstCPSet.count() == 1)
459 {
461 typename CPtSet::iterator it = dstCPSet.begin();
462 const CVar& var = *it;
463 // Strong update can be made if this points-to target is not heap, array or field-insensitive.
466 {
467 return true;
468 }
469 }
470 return false;
471 }
473 virtual inline bool isLocalCVarInRecursion(const CVar& var) const
474 {
475 NodeID id = getPtrNodeID(var);
476 const BaseObjVar* baseObj = _pag->getBaseObject(id);
477 assert(baseObj && "base object is null??");
478 if(SVFUtil::isa<StackObjVar>(baseObj))
479 {
480 if(const FunObjVar* svffun = _pag->getSVFVar(id)->getFunction())
481 {
482 return _callGraphSCC->isInCycle(_callGraph->getCallGraphNode(svffun)->getId());
483 }
484 }
485 return false;
486 }
487
489 virtual inline bool propagateViaObj(const CVar& storeObj, const CVar& loadObj)
490 {
492 }
494 void resolveFunPtr(const DPIm& dpm)
495 {
496 if(const CallICFGNode* cbn= getSVFG()->isCallSiteRetSVFGNode(dpm.getLoc()))
497 {
499 {
501 DPIm funPtrDpm(dpm);
504 }
505 }
506 else if(const FunObjVar* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc()))
507 {
511 for(CallInstSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
512 {
513 NodeID funPtr = _pag->getFunPtr(*it);
514 DPIm funPtrDpm(dpm);
517 }
518 }
519 }
521
522
523 virtual NodeID getPtrNodeID(const CVar& var) const = 0;
525 virtual CPtSet processGepPts(const GepSVFGNode* gep, const CPtSet& srcPts) = 0;
527 virtual void handleAddr(CPtSet& pts,const DPIm& dpm,const AddrSVFGNode* addr) = 0;
529 virtual CPtSet getConservativeCPts(const DPIm& dpm) = 0;
531 virtual inline bool handleBKCondition(DPIm&, const SVFGEdge*)
532 {
533 return true;
534 }
536 virtual inline void updateCallGraphAndSVFG(const DPIm&, const CallICFGNode*, SVFGEdgeSet&) {}
538
540
541 inline void markbkVisited(const DPIm& dpm)
542 {
543 backwardVisited.insert(dpm);
544 }
545 inline bool isbkVisited(const DPIm& dpm)
546 {
547 return backwardVisited.find(dpm)!=backwardVisited.end();
548 }
549 inline void clearbkVisited(const DPIm& dpm)
550 {
551 assert(backwardVisited.find(dpm)!=backwardVisited.end() && "dpm not found!");
552 backwardVisited.erase(dpm);
553 }
555
557
558 virtual inline const CPtSet& getCachedPointsTo(const DPIm& dpm)
559 {
560 if (isTopLevelPtrStmt(dpm.getLoc()))
561 return getCachedTLPointsTo(dpm);
562 else
563 return getCachedADPointsTo(dpm);
564 }
565 virtual inline void updateCachedPointsTo(const DPIm& dpm, const CPtSet& pts)
566 {
567 if (unionDDAPts(dpm, pts))
568 {
569 DOSTAT(double start = DDAStat::getClk(true));
570 reCompute(dpm);
572 }
573 }
574 virtual inline const CPtSet& getCachedTLPointsTo(const DPIm& dpm)
575 {
576 return dpmToTLCPtSetMap[dpm];
577 }
578 virtual inline const CPtSet& getCachedADPointsTo(const DPIm& dpm)
579 {
580 return dpmToADCPtSetMap[dpm];
581 }
583
585 inline bool isTopLevelPtrStmt(const SVFGNode* stmt)
586 {
587 return !SVFUtil::isa<StoreSVFGNode, MRSVFGNode>(stmt);
588 }
590 virtual inline DPIm getDPImWithOldCond(const DPIm& oldDpm,const CVar& var, const SVFGNode* loc)
591 {
592 DPIm dpm(oldDpm);
593 dpm.setLocVar(loc,getPtrNodeID(var));
594
595 if(SVFUtil::isa<StoreSVFGNode>(loc))
597
598 if(SVFUtil::isa<LoadSVFGNode>(loc))
600
602 return dpm;
603 }
605 inline void SVFGSCCDetection()
606 {
607 if(_svfgSCC==nullptr)
608 {
609 _svfgSCC = new SVFGSCC(getSVFG());
610 }
611 _svfgSCC->find();
612 }
615 {
616 return _svfgSCC->repNode(id);
617 }
619 inline bool isSVFGNodeInCycle(const SVFGNode* node)
620 {
621 return _svfgSCC->isInCycle(node->getId());
622 }
624 inline bool edgeInSVFGSCC(const SVFGEdge* edge)
625 {
626 return (getSVFGSCCRepNode(edge->getSrcID()) == getSVFGSCCRepNode(edge->getDstID()));
627 }
629 inline void setCallGraph (CallGraph* cg)
630 {
631 _callGraph = cg;
632 }
634 inline void setCallGraphSCC (CallGraphSCC* scc)
635 {
636 _callGraphSCC = scc;
637 }
639
640 virtual inline bool isHeapCondMemObj(const CVar& var, const StoreSVFGNode*)
641 {
643 return pVar && SVFUtil::isa<HeapObjVar, DummyObjVar>(pVar);
644 }
645
646 inline bool isArrayCondMemObj(const CVar& var) const
647 {
649 assert(obj && "base object is null??");
650 return obj->isArray();
651 }
652 inline bool isFieldInsenCondMemObj(const CVar& var) const
653 {
655 return baseObj->isFieldInsensitive();
656 }
658private:
660
661 inline const LocToDPMVecMap& getLocToDPMVecMap() const
662 {
663 return locToDpmSetMap;
664 }
665 inline const DPTItemSet& getDpmSetAtLoc(const SVFGNode* loc)
666 {
667 return locToDpmSetMap[loc->getId()];
668 }
669 inline void addDpmToLoc(const DPIm& dpm)
670 {
671 locToDpmSetMap[dpm.getLoc()->getId()].insert(dpm);
672 }
673 inline void removeDpmFromLoc(const DPIm& dpm)
674 {
675 assert(dpm == locToDpmSetMap[dpm.getLoc()].back() && "dpm not match with the end of vector");
676 locToDpmSetMap[dpm.getLoc()->getId()].erase(dpm);
677 }
679protected:
681
682 inline void addLoadDpmAndCVar(const DPIm& dpm,const DPIm& loadDpm,const CVar& loadVar)
683 {
686 }
688 inline void addLoadDpm(const DPIm& dpm,const DPIm& loadDpm)
689 {
690 typename DPMToDPMMap::iterator it = dpmToloadDpmMap.find(dpm);
691 if(it!=dpmToloadDpmMap.end())
692 it->second = loadDpm;
693 else
694 dpmToloadDpmMap.insert(std::make_pair(dpm,loadDpm));
695 }
696 inline const DPIm& getLoadDpm(const DPIm& dpm) const
697 {
698 typename DPMToDPMMap::const_iterator it = dpmToloadDpmMap.find(dpm);
699 assert(it!=dpmToloadDpmMap.end() && "not found??");
700 return it->second;
701 }
702 inline void addLoadCVar(const DPIm& dpm, const CVar& loadVar)
703 {
704 typename DPMToCVarMap::iterator it = loadToPTCVarMap.find(dpm);
705 if(it!=loadToPTCVarMap.end())
706 it->second = loadVar;
707 else
708 loadToPTCVarMap.insert(std::make_pair(dpm,loadVar));
709 }
710 inline const CVar& getLoadCVar(const DPIm& dpm) const
711 {
712 typename DPMToCVarMap::const_iterator it = loadToPTCVarMap.find(dpm);
713 assert(it!=loadToPTCVarMap.end() && "not found??");
714 return it->second;
715 }
717
719 {
720 return _ander;
721 }
723
724
725 inline void handleOutOfBudgetDpm(const DPIm& dpm) {}
726 inline bool testOutOfBudget(const DPIm& dpm)
727 {
728 if(outOfBudgetQuery) return true;
729 if(++ddaStat->_NumOfStep > DPIm::getMaxBudget())
730 outOfBudgetQuery = true;
732 }
733 inline bool isOutOfBudgetQuery() const
734 {
735 return outOfBudgetQuery;
736 }
737 inline void addOutOfBudgetDpm(const DPIm& dpm)
738 {
739 outOfBudgetDpms.insert(dpm);
740 }
741 inline bool isOutOfBudgetDpm(const DPIm& dpm) const
742 {
743 return outOfBudgetDpms.find(dpm) != outOfBudgetDpms.end();
744 }
746
749 {
750 ddaStat = s;
751 return ddaStat;
752 }
754 inline void addSUStat(const DPIm& dpm, const SVFGNode* node)
755 {
756 if (storeToDPMs[node].insert(dpm).second)
757 {
760 }
761 }
763 inline void rmSUStat(const DPIm& dpm, const SVFGNode* node)
764 {
766 if (dpmSet.erase(dpm))
767 {
769 if(dpmSet.empty())
771 }
772 }
773
792};
793
794} // End namespace SVF
795
796#endif /* VALUEFLOWDDA_H_ */
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define DDDA
Definition SVFType.h:588
#define DOSTAT(X)
Definition SVFType.h:577
#define DOTIMESTAT(X)
Definition SVFType.h:578
#define false
Definition cJSON.cpp:70
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:408
bool isFieldInsensitive() const
Return true if its field limit is 0.
Set< const CallICFGNode * > CallInstSet
Definition CallGraph.h:55
void getIndCallSitesInvokingCallee(const FunObjVar *callee, CallGraphEdge::CallInstSet &csSet)
const CallGraphNode * getCallGraphNode(const std::string &name) const
Get call graph node.
u32_t _NumOfMustAliases
Definition DDAStat.h:57
u32_t _NumOfDPM
Definition DDAStat.h:55
u32_t _NumOfStrongUpdates
Definition DDAStat.h:56
u32_t _NumOfInfeasiblePath
Definition DDAStat.h:58
u64_t _NumOfStep
Definition DDAStat.h:60
double _TotalTimeOfBKCondition
Definition DDAStat.h:65
u64_t _NumOfStepInCycle
Definition DDAStat.h:61
double _AnaTimeCyclePerQuery
Definition DDAStat.h:63
NodeBS _StrongUpdateStores
Definition DDAStat.h:67
void removeDpmFromLoc(const DPIm &dpm)
bool edgeInSVFGSCC(const SVFGEdge *edge)
Return TRUE if this edge is inside a SVFG SCC, i.e., src node and dst node are in the same SCC on the...
void backtraceAlongIndirectVF(CPtSet &pts, const DPIm &oldDpm)
Backward traverse along indirect value flows.
OrderedSet< DPIm > DPTItemSet
Definition DDAVFSolver.h:57
virtual const CPtSet & getCachedADPointsTo(const DPIm &dpm)
bool isOutOfBudgetDpm(const DPIm &dpm) const
SVFIR::CallSiteSet CallSiteSet
Definition DDAVFSolver.h:56
SVFGBuilder svfgBuilder
SVFG Builder.
NodeID getSVFGSCCRepNode(NodeID id)
Get SCC rep node of a SVFG node.
void addLoadDpmAndCVar(const DPIm &dpm, const DPIm &loadDpm, const CVar &loadVar)
LoadDpm for must-alias analysis.
const CVar & getLoadCVar(const DPIm &dpm) const
virtual bool isLocalCVarInRecursion(const CVar &var) const
Whether a local variable is in function recursions.
virtual ~DDAVFSolver()
Destructor.
Definition DDAVFSolver.h:71
virtual void updateCachedPointsTo(const DPIm &dpm, const CPtSet &pts)
DPImToCPtSetMap dpmToADCPtSetMap
points-to caching map for address-taken vars
OrderedMap< DPIm, DPIm > DPMToDPMMap
Definition DDAVFSolver.h:60
DPImToCPtSetMap dpmToTLCPtSetMap
points-to caching map for top-level vars
virtual bool isMustAlias(const DPIm &, const DPIm &)
whether load and store are aliased
bool isFieldInsenCondMemObj(const CVar &var) const
virtual CPtSet getConservativeCPts(const DPIm &dpm)=0
Get conservative points-to results when the query is out of budget.
SCCDetection< CallGraph * > CallGraphSCC
Definition DDAVFSolver.h:54
virtual NodeID getPtrNodeID(const CVar &var) const =0
Methods to be implemented in child class.
bool testOutOfBudget(const DPIm &dpm)
void addLoadDpm(const DPIm &dpm, const DPIm &loadDpm)
Note that simply use "dpmToloadDpmMap[dpm]=loadDpm", requires DPIm have a default constructor.
AndersenWaveDiff * getAndersenAnalysis() const
Return Andersen's analysis.
CallGraphSCC * _callGraphSCC
SCC for PTACallGraph.
SCCDetection< SVFG * > SVFGSCC
Definition DDAVFSolver.h:53
const LocToDPMVecMap & getLocToDPMVecMap() const
Map a SVFGNode to its dpms for handling value-flow cycles.
SVFGSCC * _svfgSCC
SCC for SVFG.
SVFIR * _pag
SVFIR.
virtual void addDDAPts(CPtSet &pts, const CVar &var)
Add pts.
virtual bool handleBKCondition(DPIm &, const SVFGEdge *)
Handle condition for context or path analysis (backward analysis)
virtual void updateCallGraphAndSVFG(const DPIm &, const CallICFGNode *, SVFGEdgeSet &)
Update call graph.
DPTItemSet backwardVisited
visited map during backward traversing
virtual bool isHeapCondMemObj(const CVar &var, const StoreSVFGNode *)
Check heap and array object.
SVFGEdge::SVFGEdgeSetTy SVFGEdgeSet
Definition DDAVFSolver.h:63
DPMToCVarMap loadToPTCVarMap
map a load dpm to its cvar pointed by its pointer operand
void markbkVisited(const DPIm &dpm)
Visited flags to avoid cycles.
SVFG * _svfg
SVFG.
void addLoadCVar(const DPIm &dpm, const CVar &loadVar)
bool isOutOfBudgetQuery() const
void backtraceAlongDirectVF(CPtSet &pts, const DPIm &oldDpm)
Backward traverse along direct value flows.
bool isTopLevelPtrStmt(const SVFGNode *stmt)
Whether this is a top-level pointer statement.
void rmSUStat(const DPIm &dpm, const SVFGNode *node)
remove strong updates num if the dpm goes to weak updates branch
DDAVFSolver()
Constructor.
Definition DDAVFSolver.h:67
NodeBS & getCandidateQueries()
Return candidate pointers for DDA.
Definition DDAVFSolver.h:93
OrderedMap< DPIm, CPtSet > DPImToCPtSetMap
Definition DDAVFSolver.h:58
void reCompute(const DPIm &dpm)
recompute points-to for value-flow cycles and indirect calls
void handleOutOfBudgetDpm(const DPIm &dpm)
handle out-of-budget queries
virtual bool isStrongUpdate(const CPtSet &dstCPSet, const StoreSVFGNode *store)
Return TRUE if this is a strong update STORE statement.
virtual bool unionDDAPts(CPtSet &pts, const CPtSet &targetPts)
Union pts.
virtual void handleSingleStatement(const DPIm &dpm, CPtSet &pts)
Handle single statement.
bool isbkVisited(const DPIm &dpm)
bool isArrayCondMemObj(const CVar &var) const
DPMToDPMMap dpmToloadDpmMap
dpms at loads for may/must-alias analysis with stores
void setCallGraph(CallGraph *cg)
Set callgraph.
AndersenWaveDiff * _ander
Andersen's analysis.
void dumpCPtSet(const CPtSet &cpts) const
LocToDPMVecMap locToDpmSetMap
map location to its dpms
void clearbkVisited(const DPIm &dpm)
OrderedMap< NodeID, DPTItemSet > LocToDPMVecMap
Definition DDAVFSolver.h:61
DPTItemSet outOfBudgetDpms
out of budget dpm set
virtual CPtSet processGepPts(const GepSVFGNode *gep, const CPtSet &srcPts)=0
ProcessGep node to generate field object nodes of a struct.
CallGraph * _callGraph
PTACallGraph.
void OOBResetVisited()
Reset visited map if the current query is out-of-budget.
void SVFGSCCDetection()
SVFG SCC detection.
virtual const CPtSet & findPT(const DPIm &dpm)
Compute points-to.
void setCallGraphSCC(CallGraphSCC *scc)
Set callgraphSCC.
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
GetDefinition SVFG.
SVFG * getSVFG() const
Return SVFG.
const DPTItemSet & getDpmSetAtLoc(const SVFGNode *loc)
virtual DPIm getDPImWithOldCond(const DPIm &oldDpm, const CVar &var, const SVFGNode *loc)
Return dpm with old context and path conditions.
OrderedMap< const SVFGNode *, DPTItemSet > StoreToPMSetMap
Definition DDAVFSolver.h:64
void startNewPTCompFromLoadSrc(CPtSet &pts, const DPIm &oldDpm)
void reComputeForEdges(const DPIm &dpm, const SVFGEdgeSet &edgeSet, bool indirectCall=false)
Traverse along out edges to find all nodes which may be affected by locDPM.
virtual bool propagateViaObj(const CVar &storeObj, const CVar &loadObj)
If the points-to contain the object obj, we could move forward along indirect value-flow edge.
virtual void handleAddr(CPtSet &pts, const DPIm &dpm, const AddrSVFGNode *addr)=0
Handle AddrSVFGNode to add proper points-to.
virtual DPIm getDPIm(const CVar &var, const SVFGNode *loc) const
Given CVar and location (SVFGNode) return a new DPItem.
Definition DDAVFSolver.h:98
void backtraceToStoreSrc(CPtSet &pts, const DPIm &oldDpm)
bool isSVFGNodeInCycle(const SVFGNode *node)
Return whether this SVFGNode is in cycle.
SVFGSCC * getSVFGSCC() const
Return SVFGSCC.
NodeBS candidateQueries
candidate pointers;
void addOutOfBudgetDpm(const DPIm &dpm)
DDAStat * ddaStat
DDA stat.
virtual bool unionDDAPts(DPIm dpm, const CPtSet &targetPts)
Union pts.
void addSUStat(const DPIm &dpm, const SVFGNode *node)
stat strong updates num
virtual const CPtSet & getCachedPointsTo(const DPIm &dpm)
Points-to Caching for top-level pointers and address-taken objects.
OrderedSet< const SVFGEdge * > ConstSVFGEdgeSet
Definition DDAVFSolver.h:62
OrderedMap< DPIm, CVar > DPMToCVarMap
Definition DDAVFSolver.h:59
virtual void buildSVFG(SVFIR *pag)
Build SVFG.
const DPIm & getLoadDpm(const DPIm &dpm) const
virtual const CPtSet & getCachedTLPointsTo(const DPIm &dpm)
StoreToPMSetMap storeToDPMs
map store to set of DPM which have been stong updated there
virtual void backwardPropDpm(CPtSet &pts, NodeID ptr, const DPIm &oldDpm, const SVFGEdge *edge)
dpm transit during backward tracing
void addDpmToLoc(const DPIm &dpm)
DDAStat * setDDAStat(DDAStat *s)
Set DDAStat.
CallGraphEdge::CallInstSet CallInstSet
Definition DDAVFSolver.h:55
void resolveFunPtr(const DPIm &dpm)
resolve function pointer
bool outOfBudgetQuery
Whether the current query is out of step limits.
virtual void resetQuery()
Reset visited map for next points-to query.
void startNewPTCompFromStoreDst(CPtSet &pts, const DPIm &oldDpm)
const GEdgeSetTy & getInEdges() const
const ValVar * getSrcNode() const
Definition VFGNode.h:213
CallGraph * getCallGraph() const
Return call graph.
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
const SVFGNode * getDefSVFGNode(const ValVar *valVar) const
Given a valVar, return its definition site.
Definition SVFG.h:171
NodeID getFunPtr(const CallICFGNode *cs) const
Definition SVFIR.h:457
Set< const CallICFGNode * > CallSiteSet
Definition SVFIR.h:55
bool isIndirectCallSites(const CallICFGNode *cs) const
Definition SVFIR.h:469
bool isConstantObj(NodeID id) const
Definition SVFIR.h:542
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:498
bool isFunPtr(NodeID id) const
Definition SVFIR.h:473
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:135
const CallSiteSet & getIndCallSites(NodeID funPtr) const
Definition SVFIR.h:463
const ValVar * getValVar(NodeID id) const
Definition SVFIR.h:139
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual const FunObjVar * getFunction() const
Get containing function, or null for globals/constants.
void set(unsigned Idx)
void reset(unsigned Idx)
NodeID getSrcNodeID() const
Definition VFGNode.h:152
NodeID getDstNodeID() const
Definition VFGNode.h:157
const ValVar * getDstNode() const
Definition VFGNode.h:278
const ValVar * getSrcNode() const
Definition VFGNode.h:274
@ IntraDirectVF
Definition VFGEdge.h:53
VFGEdgeSetTy SVFGEdgeSetTy
Definition VFGEdge.h:118
VFGEdge::VFGEdgeSetTy::const_iterator const_iterator
Definition VFGNode.h:55
SVFIR * getPAG() const
Return SVFIR.
Definition VFG.h:133
VFGEdge * getIntraVFGEdge(const VFGNode *src, const VFGNode *dst, VFGEdge::VFGEdgeK kind)
Get a SVFG edge according to src and dst.
Definition VFG.cpp:908
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
u32_t NodeID
Definition GeneralType.h:76
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
void dump(const SparseBitVector< ElementSize > &LHS, std::ostream &out)