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 "DDA/DDAStat.h"
34#include "Graphs/SCC.h"
35#include "MSSA/SVFGBuilder.h"
37#include "WPA/Andersen.h"
38#include <algorithm>
39
40namespace SVF
41{
42
46template<class CVar, class CPtSet, class DPIm>
48{
49 friend class DDAStat;
50public:
63
69 virtual ~DDAVFSolver()
70 {
71 if(_ander != nullptr)
72 {
73 // AndersenWaveDiff::releaseAndersenWaveDiff();
74 _ander = nullptr;
75 }
76
77 if (_svfg != nullptr)
78 {
79 // DDASVFGBuilder::releaseDDASVFG();
80 _svfg = nullptr;
81 }
82
83 if (_svfgSCC != nullptr)
84 delete _svfgSCC;
85 _svfgSCC = nullptr;
86
87 _callGraph = nullptr;
88 _callGraphSCC = nullptr;
89 }
92 {
93 return candidateQueries;
94 }
96 virtual inline DPIm getDPIm(const CVar& var, const SVFGNode* loc) const
97 {
98 DPIm dpm(var,loc);
99 return dpm;
100 }
102 virtual bool unionDDAPts(CPtSet& pts, const CPtSet& targetPts)
103 {
104 return (pts |= targetPts);
105 }
107 virtual bool unionDDAPts(DPIm dpm, const CPtSet& targetPts)
108 {
110 return pts |= targetPts;
111 }
113 virtual void addDDAPts(CPtSet& pts, const CVar& var)
114 {
115 pts.set(var);
116 }
118 inline SVFG* getSVFG() const
119 {
120 return _svfg;
121 }
123 inline SVFGSCC* getSVFGSCC() const
124 {
125 return _svfgSCC;
126 }
127 // Dump cptsSet
128 inline void dumpCPtSet(const CPtSet& cpts) const
129 {
130 SVFUtil::outs() << "{";
131 for(typename CPtSet::iterator it = cpts.begin(), eit = cpts.end(); it!=eit; ++it)
132 {
133 SVFUtil::outs() << (*it) << " ";
134 }
135 SVFUtil::outs() << "}\n";
136 }
138 virtual const CPtSet& findPT(const DPIm& dpm)
139 {
140
141 if(isbkVisited(dpm))
142 {
143 const CPtSet& cpts = getCachedPointsTo(dpm);
144 DBOUT(DDDA, SVFUtil::outs() << "\t already backward visited dpm: ");
145 DBOUT(DDDA, dpm.dump());
146 DBOUT(DDDA, SVFUtil::outs() << "\t return points-to: ");
147 DBOUT(DDDA, dumpCPtSet(cpts));
148 return cpts;
149 }
150
151 DBOUT(DDDA, SVFUtil::outs() << "\t backward visit dpm: ");
152 DBOUT(DDDA, dpm.dump());
155
156 if(testOutOfBudget(dpm) == false)
157 {
158
159 CPtSet pts;
161
164 }
165 return getCachedPointsTo(dpm);
166 }
167
168protected:
170 virtual void handleSingleStatement(const DPIm& dpm, CPtSet& pts)
171 {
174
175 const SVFGNode* node = dpm.getLoc();
176 if(SVFUtil::isa<AddrSVFGNode>(node))
177 {
178 handleAddr(pts,dpm,SVFUtil::cast<AddrSVFGNode>(node));
179 }
183 {
185 }
186 else if(SVFUtil::isa<GepSVFGNode>(node))
187 {
188 CPtSet gepPts;
190 unionDDAPts(pts, processGepPts(SVFUtil::cast<GepSVFGNode>(node),gepPts));
191 }
192 else if(const LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
193 {
194 if(load->getPAGDstNode()->isPointer() == false)
195 return;
196
197 CPtSet loadpts;
199 for(typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it)
200 {
202 }
203 }
204 else if(const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
205 {
206 if(store->getPAGSrcNode()->isPointer() == false)
207 return;
208
210 {
211 DBOUT(DDDA, SVFUtil::outs() << "+++must alias for load and store:");
213 DBOUT(DDDA, dpm.dump());
214 DBOUT(DDDA, SVFUtil::outs() << "+++\n");
217 }
218 else
219 {
220 CPtSet storepts;
222 for(typename CPtSet::iterator it = storepts.begin(), eit = storepts.end(); it!=eit; ++it)
223 {
225 {
227
228 if(isStrongUpdate(storepts,store))
229 {
230 DBOUT(DDDA, SVFUtil::outs() << "backward strong update for obj " << dpm.getCurNodeID() << "\n");
231 DOSTAT(addSUStat(dpm,store);)
232 }
233 else
234 {
235 DOSTAT(rmSUStat(dpm,store);)
237 }
238 }
239 else
240 {
242 }
243 }
244 }
245 }
246 else if(SVFUtil::isa<MRSVFGNode>(node))
247 {
249 }
250 else
251 assert(false && "unexpected kind of SVFG nodes");
252 }
253
255 void reCompute(const DPIm& dpm)
256 {
259 if(_pag->isFunPtr(dpm.getCurNodeID()))
260 {
261 const CallSiteSet& csSet = _pag->getIndCallSites(dpm.getCurNodeID());
262 for(CallSiteSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
264 }
266 if(!newIndirectEdges.empty())
267 _callGraphSCC->find();
269
271 SVFGEdgeSet edgeSet(dpm.getLoc()->getOutEdges());
273 }
274
276 void reComputeForEdges(const DPIm& dpm, const SVFGEdgeSet& edgeSet, bool indirectCall = false)
277 {
278 for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
279 {
280 const SVFGEdge* edge = *it;
281 const SVFGNode* dst = edge->getDstNode();
282 typename LocToDPMVecMap::const_iterator locIt = getLocToDPMVecMap().find(dst->getId());
284 if (locIt == getLocToDPMVecMap().end())
285 continue;
286 DPTItemSet dpmSet(locIt->second.begin(), locIt->second.end());
287 for(typename DPTItemSet::const_iterator it = dpmSet.begin(),eit = dpmSet.end(); it!=eit; ++it)
288 {
289 const DPIm& dstDpm = *it;
290 if(!indirectCall && SVFUtil::isa<IndirectSVFGEdge>(edge) && !SVFUtil::isa<LoadSVFGNode>(edge->getDstNode()))
291 {
292 if(dstDpm.getCurNodeID() == dpm.getCurNodeID())
293 {
294 DBOUT(DDDA,SVFUtil::outs() << "\t Recompute, forward from :");
295 DBOUT(DDDA, dpm.dump());
298 findPT(dstDpm);
299 }
300 }
301 else
302 {
303 if(indirectCall)
304 DBOUT(DDDA,SVFUtil::outs() << "\t Recompute for indirect call from :");
305 else
306 DBOUT(DDDA,SVFUtil::outs() << "\t Recompute forward from :");
307 DBOUT(DDDA, dpm.dump());
310 findPT(dstDpm);
311 }
312 }
313 }
314 }
315
317 virtual inline void buildSVFG(SVFIR* pag)
318 {
321 _pag = _svfg->getPAG();
322 }
324 virtual inline void resetQuery()
325 {
328
329 locToDpmSetMap.clear();
330 dpmToloadDpmMap.clear();
331 loadToPTCVarMap.clear();
332 outOfBudgetQuery = false;
333 ddaStat->_NumOfStep = 0;
334 }
336 inline void OOBResetVisited()
337 {
338 for(typename LocToDPMVecMap::const_iterator it = locToDpmSetMap.begin(),eit = locToDpmSetMap.end(); it!=eit; ++it)
339 {
340 DPTItemSet dpmSet(it->second.begin(), it->second.end());
341 for(typename DPTItemSet::const_iterator dit = dpmSet.begin(),deit=dpmSet.end(); dit!=deit; ++dit)
342 if(isOutOfBudgetDpm(*dit)==false)
344 }
345 }
347 inline const SVFGNode* getDefSVFGNode(const PAGNode* pagNode) const
348 {
349 return getSVFG()->getDefSVFGNode(pagNode);
350 }
352 void backtraceAlongIndirectVF(CPtSet& pts, const DPIm& oldDpm)
353 {
354 const SVFGNode* node = oldDpm.getLoc();
355 NodeID obj = oldDpm.getCurNodeID();
356 if (_pag->isConstantObj(obj))
357 return;
358 const SVFGEdgeSet edgeSet(node->getInEdges());
359 for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
360 {
361 if(const IndirectSVFGEdge* indirEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(*it))
362 {
363 const NodeBS& guard = indirEdge->getPointsTo();
364 if(guard.test(obj))
365 {
366 DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace indirectVF svfgNode " <<
367 indirEdge->getDstID() << " --> " << indirEdge->getSrcID() << "\n");
368 backwardPropDpm(pts,oldDpm.getCurNodeID(),oldDpm,indirEdge);
369 }
370 }
371 }
372 }
374 void backtraceAlongDirectVF(CPtSet& pts, const DPIm& oldDpm)
375 {
376 const SVFGNode* node = oldDpm.getLoc();
377 const SVFGEdgeSet edgeSet(node->getInEdges());
378 for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
379 {
380 if(const DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast<DirectSVFGEdge>(*it))
381 {
382 DBOUT(DDDA, SVFUtil::outs() << "\t\t==backtrace directVF svfgNode " <<
383 dirEdge->getDstID() << " --> " << dirEdge->getSrcID() << "\n");
384 const SVFGNode* srcNode = dirEdge->getSrcNode();
385 backwardPropDpm(pts,getSVFG()->getLHSTopLevPtr(srcNode)->getId(),oldDpm,dirEdge);
386 }
387 }
388 }
389
392 inline void startNewPTCompFromLoadSrc(CPtSet& pts, const DPIm& oldDpm)
393 {
394 const LoadSVFGNode* load = SVFUtil::cast<LoadSVFGNode>(oldDpm.getLoc());
396 DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from loadSrc svfgNode " <<
397 load->getId() << " --> " << loadSrc->getId() << "\n");
399 assert(edge && "Edge not found!!");
401
402 }
403 inline void startNewPTCompFromStoreDst(CPtSet& pts, const DPIm& oldDpm)
404 {
405 const StoreSVFGNode* store = SVFUtil::cast<StoreSVFGNode>(oldDpm.getLoc());
407 DBOUT(DDDA, SVFUtil::outs() << "!##start new computation from storeDst svfgNode " <<
408 store->getId() << " --> " << storeDst->getId() << "\n");
410 assert(edge && "Edge not found!!");
412 }
413 inline void backtraceToStoreSrc(CPtSet& pts, const DPIm& oldDpm)
414 {
415 const StoreSVFGNode* store = SVFUtil::cast<StoreSVFGNode>(oldDpm.getLoc());
417 DBOUT(DDDA, SVFUtil::outs() << "++backtrace to storeSrc from svfgNode " << getLoadDpm(oldDpm).getLoc()->getId() << " to "<<
418 store->getId() << " to " << storeSrc->getId() <<"\n");
420 assert(edge && "Edge not found!!");
422 }
424
426 virtual void backwardPropDpm(CPtSet& pts, NodeID ptr,const DPIm& oldDpm,const SVFGEdge* edge)
427 {
428 DPIm dpm(oldDpm);
429 dpm.setLocVar(edge->getSrcNode(),ptr);
430 DOTIMESTAT(double start = DDAStat::getClk(true));
432 if(handleBKCondition(dpm,edge)==false)
433 {
435 DBOUT(DDDA, SVFUtil::outs() << "\t!!! infeasible path svfgNode: " << edge->getDstID() << " --| " << edge->getSrcID() << "\n");
437 return;
438 }
439
441 if(SVFUtil::isa<IndirectSVFGEdge>(edge))
443
447 }
449 virtual bool isMustAlias(const DPIm&, const DPIm&)
450 {
451 return false;
452 }
454 virtual bool isStrongUpdate(const CPtSet& dstCPSet, const StoreSVFGNode* store)
455 {
456 if (dstCPSet.count() == 1)
457 {
459 typename CPtSet::iterator it = dstCPSet.begin();
460 const CVar& var = *it;
461 // Strong update can be made if this points-to target is not heap, array or field-insensitive.
464 {
465 return true;
466 }
467 }
468 return false;
469 }
471 virtual inline bool isLocalCVarInRecursion(const CVar& var) const
472 {
473 NodeID id = getPtrNodeID(var);
474 const BaseObjVar* baseObj = _pag->getBaseObject(id);
475 assert(baseObj && "base object is null??");
476 const MemObj* obj = _pag->getObject(id);
477 assert(obj && "object not found!!");
478 if(SVFUtil::isa<StackObjVar>(baseObj))
479 {
480 if(const SVFFunction* svffun = _pag->getGNode(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 SVFFunction* fun = getSVFG()->isFunEntrySVFGNode(dpm.getLoc()))
507 {
511 for(CallInstSet::const_iterator it = csSet.begin(), eit = csSet.end(); it!=eit; ++it)
512 {
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 }
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 {
648 const MemObj* mem = _pag->getObject(getPtrNodeID(var));
649 assert(mem && "memory object is null??");
650 return mem->isArray();
651 }
652 inline bool isFieldInsenCondMemObj(const CVar& var) const
653 {
654 const MemObj* mem = _pag->getBaseObj(getPtrNodeID(var));
655 return mem->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:484
#define DDDA
Definition SVFType.h:496
#define DOSTAT(X)
Definition SVFType.h:485
#define DOTIMESTAT(X)
Definition SVFType.h:486
#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
u32_t _NumOfMustAliases
Definition DDAStat.h:56
u32_t _NumOfDPM
Definition DDAStat.h:54
u32_t _NumOfStrongUpdates
Definition DDAStat.h:55
u32_t _NumOfInfeasiblePath
Definition DDAStat.h:57
u64_t _NumOfStep
Definition DDAStat.h:59
double _TotalTimeOfBKCondition
Definition DDAStat.h:64
u64_t _NumOfStepInCycle
Definition DDAStat.h:60
double _AnaTimeCyclePerQuery
Definition DDAStat.h:62
NodeBS _StrongUpdateStores
Definition DDAStat.h:66
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:55
virtual const CPtSet & getCachedADPointsTo(const DPIm &dpm)
bool isOutOfBudgetDpm(const DPIm &dpm) const
SVFIR::CallSiteSet CallSiteSet
Definition DDAVFSolver.h:54
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:69
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:58
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.
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:51
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:61
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:65
NodeBS & getCandidateQueries()
Return candidate pointers for DDA.
Definition DDAVFSolver.h:91
OrderedMap< DPIm, CPtSet > DPImToCPtSetMap
Definition DDAVFSolver.h:56
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
AndersenWaveDiff * _ander
Andersen's analysis.
void dumpCPtSet(const CPtSet &cpts) const
LocToDPMVecMap locToDpmSetMap
map location to its dpms
void clearbkVisited(const DPIm &dpm)
const SVFGNode * getDefSVFGNode(const PAGNode *pagNode) const
GetDefinition SVFG.
OrderedMap< NodeID, DPTItemSet > LocToDPMVecMap
Definition DDAVFSolver.h:59
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.
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.
PTACallGraph * _callGraph
PTACallGraph.
SVFG * getSVFG() const
Return SVFG.
const DPTItemSet & getDpmSetAtLoc(const SVFGNode *loc)
PTACallGraphEdge::CallInstSet CallInstSet
Definition DDAVFSolver.h:53
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:62
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:96
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:60
OrderedMap< DPIm, CVar > DPMToCVarMap
Definition DDAVFSolver.h:57
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
SCCDetection< PTACallGraph * > CallGraphSCC
Definition DDAVFSolver.h:52
void addDpmToLoc(const DPIm &dpm)
DDAStat * setDDAStat(DDAStat *s)
Set DDAStat.
void setCallGraph(PTACallGraph *cg)
Set callgraph.
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)
NodeType * getGNode(NodeID id) const
Get a node.
const GEdgeSetTy & getInEdges() const
bool isFieldInsensitive() const
Return true if its field limit is 0.
bool isArray() const
Set< const CallICFGNode * > CallInstSet
void getIndCallSitesInvokingCallee(const SVFFunction *callee, PTACallGraphEdge::CallInstSet &csSet)
PTACallGraphNode * getCallGraphNode(NodeID id) const
Get call graph node.
PTACallGraph * getCallGraph() const
Return call graph.
NodeID getId() const
Get ID.
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
const SVFGNode * getDefSVFGNode(const PAGNode *pagNode) const
Given a pagNode, return its definition site.
Definition SVFG.h:171
NodeID getFunPtr(const CallICFGNode *cs) const
Definition SVFIR.h:355
Set< const CallICFGNode * > CallSiteSet
Definition SVFIR.h:55
bool isIndirectCallSites(const CallICFGNode *cs) const
Definition SVFIR.h:367
bool isConstantObj(NodeID id) const
Definition SVFIR.h:465
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:405
const MemObj * getBaseObj(NodeID id) const
Definition SVFIR.h:481
bool isFunPtr(NodeID id) const
Definition SVFIR.h:371
const MemObj * getObject(NodeID id) const
Definition SVFIR.h:396
const CallSiteSet & getIndCallSites(NodeID funPtr) const
Definition SVFIR.h:361
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
virtual const SVFFunction * getFunction() const
void set(unsigned Idx)
void reset(unsigned Idx)
NodeID getPAGDstNodeID() const
Definition VFGNode.h:157
PAGNode * getPAGSrcNode() const
Definition VFGNode.h:162
PAGNode * getPAGDstNode() const
Definition VFGNode.h:167
NodeID getPAGSrcNodeID() const
Definition VFGNode.h:152
@ 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:928
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
u32_t NodeID
Definition GeneralType.h:55
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
void dump(const SparseBitVector< ElementSize > &LHS, std::ostream &out)