Static Value-Flow Analysis
Loading...
Searching...
No Matches
FlowSensitive.cpp
Go to the documentation of this file.
1//===- FlowSensitive.cpp -- Sparse flow-sensitive pointer analysis------------//
2//
3// SVF: Static Value-Flow Analysis
4//
5// Copyright (C) <2013-2017> <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 * FlowSensitive.cpp
25 *
26 * Created on: Oct 28, 2013
27 * Author: Yulei Sui
28 */
29
30#include "Util/Options.h"
31#include "WPA/WPAStat.h"
32#include "WPA/FlowSensitive.h"
33#include "WPA/Andersen.h"
35
36using namespace SVF;
37using namespace SVFUtil;
38
39std::unique_ptr<FlowSensitive> FlowSensitive::fspta;
40
45{
47
48 stat = new FlowSensitiveStat(this);
49
50 // TODO: support clustered aux. Andersen's.
51 assert(!Options::ClusterAnder() && "FlowSensitive::initialize: clustering auxiliary Andersen's unsupported.");
53
54 // If cluster option is not set, it will give us a no-mapping points-to set.
56 && "FS::init: plain-mapping and cluster-fs are mutually exclusive.");
58 {
59 cluster();
60 // Reset the points-to cache although empty so the new mapping could
61 // be applied to the inserted empty set.
62 getPtCache().reset();
63 }
64 else if (Options::PlainMappingFs())
65 {
66 plainMap();
67 // As above.
68 getPtCache().reset();
69 }
70
72
74 //AndersenWaveDiff::releaseAndersenWaveDiff();
75}
77{
79 if (timeLimited)
80 {
82 }
83
84 double start = stat->getClk(true);
86 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Start Solving Constraints\n"));
87
88 do
89 {
91
93 dumpStat();
94
95 callGraphSCC->find();
96
99 }
101
102 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Finish Solving Constraints\n"));
103
104 // Reset the time-up alarm; analysis is done.
105 if (timeLimited)
106 {
108 }
109
110 double end = stat->getClk(true);
111 solveTime += (end - start) / TIMEINTERVAL;
112
113}
114
119{
121 initialize();
122 if(!filename.empty())
125 if(!filename.empty())
128 finalize();
129}
130
135{
136 if(!Options::ReadAnder().empty())
137 {
139 }
140 else
141 {
142 if(Options::WriteAnder().empty())
143 {
144 initialize();
146 finalize();
147 }
148 else
149 {
151 }
152 }
153}
154
156{
158 initialize();
160 if(!filename.empty())
161 this->readFromFile(filename);
163 finalize();
164}
165
170{
171 if(Options::DumpVFG())
172 svfg->dump("fs_solved", true);
173
175 while (nodeStack.empty() == false)
176 {
177 NodeID rep = nodeStack.top();
178 nodeStack.pop();
179 const NodeBS& subNodes = getSCCDetector()->subNodes(rep);
180 if (subNodes.count() > maxSCCSize)
181 maxSCCSize = subNodes.count();
182 if (subNodes.count() > 1)
183 {
184 numOfNodesInSCC += subNodes.count();
185 numOfSCC++;
186 }
187 }
188
189 // TODO: check -stat too.
190 if (Options::ClusterFs())
191 {
193 const PTDataTy *ptd = getPTDataTy();
194 // TODO: should we use liveOnly?
195 Map<PointsTo, unsigned> allPts = ptd->getAllPts(true);
196 // TODO: parameterise final arg.
198 if (print_stat)
199 {
201 }
202 }
203
205}
206
211{
212 double start = stat->getClk();
214 double end = stat->getClk();
215 sccTime += (end - start) / TIMEINTERVAL;
216 return nodeStack;
217}
218
223{
225 if (processSVFGNode(node))
226 propagate(&node);
227
229}
230
235{
236 double start = stat->getClk();
237 bool changed = false;
238 if (AddrSVFGNode* addr = SVFUtil::dyn_cast<AddrSVFGNode>(node))
239 {
241 if (processAddr(addr))
242 changed = true;
243 }
244 else if (CopySVFGNode* copy = SVFUtil::dyn_cast<CopySVFGNode>(node))
245 {
247 if (processCopy(copy))
248 changed = true;
249 }
250 else if (GepSVFGNode* gep = SVFUtil::dyn_cast<GepSVFGNode>(node))
251 {
253 if(processGep(gep))
254 changed = true;
255 }
256 else if (LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
257 {
259 if(processLoad(load))
260 changed = true;
261 }
262 else if (StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
263 {
265 if (processStore(store))
266 changed = true;
267 }
268 else if (PHISVFGNode* phi = SVFUtil::dyn_cast<PHISVFGNode>(node))
269 {
271 if (processPhi(phi))
272 changed = true;
273 }
276 ActualOUTSVFGNode>(node))
277 {
279 changed = true;
280 }
283 NullPtrSVFGNode>(node))
284 {
285 changed = true;
286 }
287 else if (SVFUtil::isa<CmpVFGNode, BinaryOPVFGNode>(node) ||
288 SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
289 {
290 }
291 else
292 {
293 assert(false && "unexpected kind of SVFG nodes");
294 }
295
296 double end = stat->getClk();
297 processTime += (end - start) / TIMEINTERVAL;
298
299 return changed;
300}
301
311{
312 double start = stat->getClk();
313 bool changed = false;
314
315 if (DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast<DirectSVFGEdge>(edge))
317 else if (IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(edge))
319 else
320 assert(false && "new kind of svfg edge?");
321
322 double end = stat->getClk();
323 propagationTime += (end - start) /TIMEINTERVAL;
324 return changed;
325}
326
331{
332 double start = stat->getClk();
333 bool changed = false;
334
335 SVFGNode* src = edge->getSrcNode();
336 SVFGNode* dst = edge->getDstNode();
337 // If this is an actual-param or formal-ret, top-level pointer's pts must be
338 // propagated from src to dst.
339 if (ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(src))
340 changed = propagateFromAPToFP(ap, dst);
341 else if (FormalRetSVFGNode* fp = SVFUtil::dyn_cast<FormalRetSVFGNode>(src))
343 else
344 {
345 // Direct SVFG edge links between def and use of a top-level pointer.
346 // There's no points-to information propagated along direct edge.
347 // Since the top-level pointer's value has been changed at src node,
348 // return TRUE to put dst node into the work list.
349 changed = true;
350 }
351
352 double end = stat->getClk();
353 directPropaTime += (end - start) / TIMEINTERVAL;
354 return changed;
355}
356
362{
363 const FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(dst);
364 assert(fp && "expecting a formal param node");
365
366 NodeID pagDst = fp->getParam()->getId();
367 const PointsTo &srcCPts = getPts(ap->getParam()->getId());
369
370 return changed;
371}
372
378{
379 const ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(dst);
380 assert(ar && "expecting an actual return node");
381
382 NodeID pagDst = ar->getRev()->getId();
383 const PointsTo & srcCPts = getPts(fr->getRet()->getId());
385
386 return changed;
387}
388
393{
394 double start = stat->getClk();
395
396 SVFGNode* src = edge->getSrcNode();
397 SVFGNode* dst = edge->getDstNode();
398
399 bool changed = false;
400
401 // Get points-to targets may be used by next SVFG node.
402 // Propagate points-to set for node used in dst.
403 const NodeBS& pts = edge->getPointsTo();
404 for (NodeBS::iterator ptdIt = pts.begin(), ptdEit = pts.end(); ptdIt != ptdEit; ++ptdIt)
405 {
406 NodeID ptd = *ptdIt;
407
408 if (propVarPtsFromSrcToDst(ptd, src, dst))
409 changed = true;
410
412 {
415 for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end();
417 {
418 if (propVarPtsFromSrcToDst(*fieldIt, src, dst))
419 changed = true;
420 }
421 }
422 }
423
424 double end = stat->getClk();
425 indirectPropaTime += (end - start) / TIMEINTERVAL;
426 return changed;
427}
428
433{
434 bool changed = false;
435 if (SVFUtil::isa<StoreSVFGNode>(src))
436 {
437 if (updateInFromOut(src, var, dst, var))
438 changed = true;
439 }
440 else
441 {
442 if (updateInFromIn(src, var, dst, var))
443 changed = true;
444 }
445 return changed;
446}
447
452{
453 double start = stat->getClk();
454 NodeID srcID = addr->getSrcNodeID();
459 bool changed = addPts(addr->getDstNodeID(), srcID);
460 double end = stat->getClk();
461 addrTime += (end - start) / TIMEINTERVAL;
462 return changed;
463}
464
469{
470 double start = stat->getClk();
471 bool changed = unionPts(copy->getDstNodeID(), copy->getSrcNodeID());
472 double end = stat->getClk();
473 copyTime += (end - start) / TIMEINTERVAL;
474 return changed;
475}
476
481{
482 double start = stat->getClk();
483 bool changed = false;
484 NodeID pagDst = phi->getRes()->getId();
485 for (PHISVFGNode::OPVers::const_iterator it = phi->opVerBegin(), eit = phi->opVerEnd(); it != eit; ++it)
486 {
487 NodeID src = it->second->getId();
488 const PointsTo& srcPts = getPts(src);
489 if (unionPts(pagDst, srcPts))
490 changed = true;
491 }
492
493 double end = stat->getClk();
494 phiTime += (end - start) / TIMEINTERVAL;
495 return changed;
496}
497
502{
503 double start = stat->getClk();
504 bool changed = false;
505 const PointsTo& srcPts = getPts(edge->getSrcNodeID());
506
508 const GepStmt* gepStmt = SVFUtil::cast<GepStmt>(edge->getSVFStmt());
509 if (gepStmt->isVariantFieldGep())
510 {
511 for (NodeID o : srcPts)
512 {
514 {
515 tmpDstPts.set(o);
516 continue;
517 }
518
520 tmpDstPts.set(getFIObjVar(o));
521 }
522 }
523 else
524 {
525 for (NodeID o : srcPts)
526 {
528 {
529 tmpDstPts.set(o);
530 continue;
531 }
532
533 NodeID fieldSrcPtdNode = getGepObjVar(o, gepStmt->getAccessPath().getConstantStructFldIdx());
535 }
536 }
537
538 if (unionPts(edge->getDstNodeID(), tmpDstPts))
539 changed = true;
540
541 double end = stat->getClk();
542 gepTime += (end - start) / TIMEINTERVAL;
543 return changed;
544}
545
546
554{
555 double start = stat->getClk();
556 bool changed = false;
557
558 NodeID dstVar = load->getDstNodeID();
559
560 const PointsTo& srcPts = getPts(load->getSrcNodeID());
561
562 // p = *q, the type of p must be a pointer
563 if(load->getDstNode()->isPointer())
564 {
565 for (PointsTo::iterator ptdIt = srcPts.begin(); ptdIt != srcPts.end(); ++ptdIt)
566 {
567 NodeID ptd = *ptdIt;
568
569 if (pag->isConstantObj(ptd))
570 continue;
571
572 if (unionPtsFromIn(load, ptd, dstVar))
573 changed = true;
574
576 {
580 for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end();
582 {
583 if (unionPtsFromIn(load, *fieldIt, dstVar))
584 changed = true;
585 }
586 }
587 }
588 }
589 double end = stat->getClk();
590 loadTime += (end - start) / TIMEINTERVAL;
591 return changed;
592}
593
601{
602
603 const PointsTo & dstPts = getPts(store->getDstNodeID());
604
611 if (dstPts.empty())
612 return false;
613
614 double start = stat->getClk();
615 bool changed = false;
616
617 // *p = q, the type of q must be a pointer
618 if(getPts(store->getSrcNodeID()).empty() == false && store->getSrcNode()->isPointer())
619 {
620 for (PointsTo::iterator it = dstPts.begin(), eit = dstPts.end(); it != eit; ++it)
621 {
622 NodeID ptd = *it;
623
624 if (pag->isConstantObj(ptd))
625 continue;
626
627 if (unionPtsFromTop(store, store->getSrcNodeID(), ptd))
628 changed = true;
629 }
630 }
631
632 double end = stat->getClk();
633 storeTime += (end - start) / TIMEINTERVAL;
634
635 double updateStart = stat->getClk();
636 // also merge the DFInSet to DFOutSet.
639 bool isSU = isStrongUpdate(store, singleton);
640 if (isSU)
641 {
642 svfgHasSU.set(store->getId());
644 changed = true;
645 }
646 else
647 {
648 svfgHasSU.reset(store->getId());
649 if (weakUpdateOutFromIn(store))
650 changed = true;
651 }
652 double updateEnd = stat->getClk();
654
655 return changed;
656}
657
662{
663 bool isSU = false;
664 if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
665 {
666 const PointsTo& dstCPSet = getPts(store->getDstNodeID());
667 if (dstCPSet.count() == 1)
668 {
670 PointsTo::iterator it = dstCPSet.begin();
671 singleton = *it;
672
673 // Strong update can be made if this points-to target is not heap, array or field-insensitive.
675 {
679 {
680 isSU = true;
681 }
682 }
683 }
684 }
685 return isSU;
686}
687
692{
693 double start = stat->getClk();
696
697 // Bound the new edges by the Andersen's call graph.
698 // TODO: we want this to be an assertion eventually.
700 for (typename CallEdgeMap::value_type &csfs : newEdges)
701 {
702 const CallICFGNode *potentialCallSite = csfs.first;
704
705 // Check this callsite even calls anything per Andersen's.
706 typename CallEdgeMap::const_iterator andersFunctionSetIt
709 {
710 potentialFunctionSet.clear();
711 }
712
714 for (FunctionSet::iterator potentialFunctionIt = potentialFunctionSet.begin();
716 {
719 {
720 // potentialFunction is not in the Andersen's call graph -- remove it.
722 }
723 else
724 {
725 // potentialFunction is in the Andersen's call graph -- keep it..
727 }
728 }
729 }
730
733
735
736 double end = stat->getClk();
737 updateCallGraphTime += (end - start) / TIMEINTERVAL;
738 return (!newEdges.empty());
739}
740
745{
746 CallEdgeMap::const_iterator iter = newEdges.begin();
747 CallEdgeMap::const_iterator eiter = newEdges.end();
748 for (; iter != eiter; iter++)
749 {
750 const CallICFGNode* cs = iter->first;
751 const FunctionSet & functions = iter->second;
752 for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
753 {
754 const FunObjVar* func = *func_iter;
756 }
757 }
758}
759
765{
766 for (const SVFGEdge* edge : edges)
767 {
768 SVFGNode* dstNode = edge->getDstNode();
769 if (SVFUtil::isa<PHISVFGNode>(dstNode))
770 {
773 pushIntoWorklist(dstNode->getId());
774 }
775 else if (SVFUtil::isa<FormalINSVFGNode, ActualOUTSVFGNode>(dstNode))
776 {
779 bool changed = false;
780
781 SVFGNode* srcNode = edge->getSrcNode();
782
783 const NodeBS& pts = SVFUtil::cast<IndirectSVFGEdge>(edge)->getPointsTo();
784 for (NodeBS::iterator ptdIt = pts.begin(), ptdEit = pts.end(); ptdIt != ptdEit; ++ptdIt)
785 {
786 NodeID ptd = *ptdIt;
787
789 changed = true;
790
792 {
795 for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end();
797 {
799 changed = true;
800 }
801 }
802 }
803
804 if (changed)
805 pushIntoWorklist(dstNode->getId());
806 }
807 }
808}
809
810
815{
816 if (SVFUtil::isa<StoreSVFGNode>(src))
817 {
818 if (propDFOutToIn(src, var, dst, var))
819 return true;
820 }
821 else
822 {
823 if (propDFInToIn(src, var, dst, var))
824 return true;
825 }
826 return false;
827}
828
830{
831 std::vector<std::pair<unsigned, unsigned>> keys;
832 for (const auto& pair : *pag)
833 keys.emplace_back(pair.first, 1);
834
835 PointsTo::MappingPtr nodeMapping =
836 std::make_shared<std::vector<NodeID>>(
838 );
839 PointsTo::MappingPtr reverseNodeMapping =
840 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
841
842 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
843}
844
846{
848 && "FS::cluster: plain mapping requires dense allocation strategy.");
849
850 const size_t numObjects = NodeIDAllocator::get()->getNumObjects();
851 PointsTo::MappingPtr plainMapping = std::make_shared<std::vector<NodeID>>(numObjects);
852 PointsTo::MappingPtr reversePlainMapping = std::make_shared<std::vector<NodeID>>(numObjects);
853 for (NodeID i = 0; i < plainMapping->size(); ++i)
854 {
855 plainMapping->at(i) = i;
856 reversePlainMapping->at(i) = i;
857 }
858
860}
861
862void FlowSensitive::countAliases(Set<std::pair<NodeID, NodeID>> cmp, unsigned *mayAliases, unsigned *noAliases)
863{
864 for (std::pair<NodeID, NodeID> locPA : cmp)
865 {
866 // loc doesn't make a difference for FSPTA.
867 NodeID p = locPA.second;
868 for (std::pair<NodeID, NodeID> locPB : cmp)
869 {
870 if (locPB == locPA) continue;
871
872 NodeID q = locPB.second;
873
874 switch (alias(p, q))
875 {
877 ++(*noAliases);
878 break;
880 ++(*mayAliases);
881 break;
882 default:
883 assert("Not May/NoAlias?");
884 }
885 }
886 }
887
888}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:576
#define TIMEINTERVAL
Definition SVFType.h:604
#define DGENERAL
Definition SVFType.h:582
cJSON * p
Definition cJSON.cpp:2559
copy
Definition cJSON.cpp:414
const ValVar * getParam() const
Return parameter.
Definition VFGNode.h:989
static AndersenWaveDiff * createAndersenWaveDiff(SVFIR *_pag)
Create an singleton instance directly instead of invoking llvm pass manager.
Definition Andersen.h:420
virtual void writeToFile(const std::string &filename)
Interface for analysis result storage on filesystem.
virtual bool readFromFile(const std::string &filename)
virtual void writeObjVarToFile(const std::string &filename)
AliasResult alias(const SVFVar *V1, const SVFVar *V2) override
Interface expose to users of our pointer analysis, given Value infos.
void finalize() override
Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
virtual void onTheFlyCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
On the fly call graph construction.
PersistentPointsToCache< PointsTo > & getPtCache()
PTData< NodeID, NodeSet, NodeID, PointsTo > PTDataTy
const PointsTo & getPts(NodeID id) override
virtual bool unionPts(NodeID id, const PointsTo &target)
PTDataTy * getPTDataTy() const
Get points-to data structure.
virtual bool addPts(NodeID id, NodeID ptd)
bool isFieldInsensitive() const
Return true if its field limit is 0.
void processNode(NodeID nodeId) override
Handle various constraints.
u32_t numOfProcessedLoad
Number of processed Phi node.
virtual void solveConstraints()
virtual bool unionPtsFromIn(const SVFGNode *stmt, NodeID srcVar, NodeID dstVar)
virtual void updateConnectedNodes(const SVFGEdgeSetTy &edges)
Update nodes connected during updating call graph.
u32_t numOfProcessedCopy
Number of processed Addr node.
virtual void countAliases(Set< std::pair< NodeID, NodeID > > cmp, unsigned *mayAliases, unsigned *noAliases)
Fills may/noAliases for the location/pointer pairs in cmp.
double gepTime
time of handling gep edges
static std::unique_ptr< FlowSensitive > fspta
double indirectPropaTime
time of points-to propagation of top-level pointers
virtual bool propagateFromAPToFP(const ActualParmSVFGNode *ap, const SVFGNode *dst)
double addrTime
time of handling address edges
virtual bool propagateFromFRToAR(const FormalRetSVFGNode *fr, const SVFGNode *dst)
virtual bool propDFInToIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
NodeStack & SCCDetect() override
SCC detection.
double solveTime
time of solve.
bool isStrongUpdate(const SVFGNode *node, NodeID &singleton)
Return TRUE if this is a strong update STORE statement.
virtual void readPtsFromFile(const std::string &filename)
virtual bool unionPtsFromTop(const SVFGNode *stmt, NodeID srcVar, NodeID dstVar)
virtual void plainMap(void) const
Sets the global best mapping as a plain mapping, i.e. n -> n.
AndersenWaveDiff * ander
virtual bool propDFOutToIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
u32_t numOfProcessedStore
Number of processed Load node.
SVFG::SVFGEdgeSetTy SVFGEdgeSetTy
void analyze() override
Flow sensitive analysis.
double storeTime
time of store edges
virtual bool updateInFromIn(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
double copyTime
time of handling copy edges
bool propFromSrcToDst(SVFGEdge *edge) override
Propagation.
u32_t numOfProcessedGep
Number of processed Copy node.
friend class FlowSensitiveStat
virtual void cluster(void)
virtual bool strongUpdateOutFromIn(const SVFGNode *node, NodeID singleton)
Handle strong updates.
void finalize() override
Finalize analysis.
void clearAllDFOutVarFlag(const SVFGNode *stmt)
bool processSVFGNode(SVFGNode *node)
virtual bool processLoad(const LoadSVFGNode *load)
bool propVarPtsAfterCGUpdated(NodeID var, const SVFGNode *src, const SVFGNode *dst)
virtual bool processPhi(const PHISVFGNode *phi)
virtual bool processStore(const StoreSVFGNode *store)
u32_t maxSCCSize
Number of processed mssa node.
virtual bool processCopy(const CopySVFGNode *copy)
double loadTime
time of load edges
bool updateCallGraph(const CallSiteToFunPtrMap &callsites) override
Update call graph.
virtual bool weakUpdateOutFromIn(const SVFGNode *node)
Handle weak updates.
virtual bool processAddr(const AddrSVFGNode *addr)
u32_t numOfProcessedPhi
Number of processed Gep node.
double propagationTime
time of points-to propagation.
virtual bool propAlongDirectEdge(const DirectSVFGEdge *edge)
Propagate points-to information along a DIRECT SVFG edge.
void initialize() override
Initialize analysis.
void connectCallerAndCallee(const CallEdgeMap &newEdges, SVFGEdgeSetTy &edges)
Connect nodes in SVFG.
std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > candidateMappings
Save candidate mappings for evaluation's sake.
virtual bool processGep(const GepSVFGNode *edge)
double directPropaTime
time of points-to propagation of address-taken objects
double processTime
time of processNode.
u32_t numOfProcessedAddr
Statistics.
virtual bool propVarPtsFromSrcToDst(NodeID var, const SVFGNode *src, const SVFGNode *dst)
Propagate points-to information of a certain variable from src to dst.
virtual bool propAlongIndirectEdge(const IndirectSVFGEdge *edge)
Propagate points-to information along an INDIRECT SVFG edge.
double phiTime
time of phi nodes.
double sccTime
time of SCC detection.
double updateTime
time of strong/weak updates.
virtual bool updateInFromOut(const SVFGNode *srcStmt, NodeID srcVar, const SVFGNode *dstStmt, NodeID dstVar)
u32_t numOfProcessedMSSANode
Number of processed formal ret node.
virtual void solveAndwritePtsToFile(const std::string &filename)
double updateCallGraphTime
time of updating call graph
GEdgeSetTy::const_iterator const_iterator
const ValVar * getDstNode() const
Definition VFGNode.h:217
static std::vector< NodeID > getReverseNodeMapping(const std::vector< NodeID > &nodeMapping)
static std::vector< NodeID > cluster(BVDataPTAImpl *pta, const std::vector< std::pair< NodeID, unsigned > > keys, std::vector< std::pair< hclust_fast_methods, std::vector< NodeID > > > &candidates, std::string evalSubtitle="", bool printStat=true)
static void printStats(std::string title, Map< std::string, std::string > &stats)
static void evaluate(const std::vector< NodeID > &nodeMap, const Map< PointsTo, unsigned > pointsToSets, Map< std::string, std::string > &stats, bool accountForOcc)
Fills in *NumWords statistics in stats..
static NodeIDAllocator * get(void)
Return (singleton) allocator.
NodeID getNumObjects(void) const
Returns the total number of memory objects.
static const Option< bool > PlainMappingFs
Use an explicitly plain mapping with flow-sensitive (not null).
Definition Options.h:43
static const OptionMap< SVF::NodeIDAllocator::Strategy > NodeAllocStrat
Definition Options.h:31
static const Option< std::string > ReadAnder
Definition Options.h:204
static const Option< bool > ClusterAnder
Whether to stage Andersen's with Steensgaard and cluster based on that data.
Definition Options.h:37
static const Option< u32_t > FsTimeLimit
Time limit for the main phase (i.e., the actual solving) of FS analyses.
Definition Options.h:68
static const Option< bool > ClusterFs
Whether to cluster FS or VFS with the auxiliary Andersen's.
Definition Options.h:40
static const Option< std::string > WriteAnder
Definition Options.h:202
static const Option< bool > DumpVFG
Definition Options.h:107
bool isFieldInsensitive(NodeID id) const
bool isLocalVarInRecursiveFun(NodeID id) const
Whether a local variable is in function recursions.
bool print_stat
User input flags.
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
virtual void initialize()
Initialization of a pointer analysis, including building symbol table and SVFIR etc.
virtual bool isBlkObjOrConstantObj(NodeID ptd) const
PTAStat * stat
Statistics.
NodeID getFIObjVar(NodeID id)
SVFIR * getPAG() const
Set< const FunObjVar * > FunctionSet
const CallSiteToFunPtrMap & getIndirectCallsites() const
Return all indirect callsites.
bool isArrayMemObj(NodeID id) const
NodeID getGepObjVar(NodeID id, const APOffset &ap)
void dumpStat()
Dump the statistics.
CallEdgeMap & getIndCallMap()
Get callees from an indirect callsite.
void setObjFieldInsensitive(NodeID id)
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
static SVFIR * pag
SVFIR.
CallGraphSCC * callGraphSCC
SCC for PTACallGraph.
bool isHeapMemObj(NodeID id) const
Whether this object is heap or array.
virtual const NodeBS & getAllFieldsObjVars(NodeID id)
u32_t OnTheFlyIterBudgetForStat
Flag for iteration budget for on-the-fly statistics.
bool empty() const
Returns true if set is empty.
Definition PointsTo.cpp:110
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:43
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:383
static MappingPtr getCurrentBestNodeMapping()
Definition PointsTo.cpp:373
SVFG * buildPTROnlySVFG(BVDataPTAImpl *pta)
SVFGNode * getSVFGNode(NodeID id) const
Get a SVFG node.
Definition SVFG.h:150
void dump(const std::string &file, bool simple=false)
Dump graph into dot file.
Definition SVFG.cpp:576
virtual void connectCallerAndCallee(const CallICFGNode *cs, const FunObjVar *callee, SVFGEdgeSetTy &edges)
Connect SVFG nodes between caller and callee for indirect call site.
Definition SVFG.cpp:658
bool isConstantObj(NodeID id) const
Definition SVFIR.h:542
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:498
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual bool isPointer() const
Check if this variable represents a pointer.
void set(unsigned Idx)
unsigned count() const
void reset(unsigned Idx)
NodeID getSrcNodeID() const
Definition VFGNode.h:152
NodeID getDstNodeID() const
Definition VFGNode.h:157
const ValVar * getSrcNode() const
Definition VFGNode.h:274
NodeStack nodeStack
stack used for processing nodes.
Definition WPAFSSolver.h:65
virtual NodeStack & SCCDetect()
SCC detection.
Definition WPAFSSolver.h:68
SCC * getSCCDetector() const
Get SCC detector.
Definition WPASolver.h:68
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:157
virtual void propagate(GNODE *v)
Definition WPASolver.h:128
virtual void initWorklist()
Definition WPASolver.h:98
void setGraph(GraphType g)
Definition WPASolver.h:79
virtual NodeStack & SCCDetect()
SCC detection.
Definition WPASolver.h:87
u32_t numOfIteration
num of iterations during constraint solving
Definition WPASolver.h:201
virtual void solveWorklist()
Definition WPASolver.h:109
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
LLVM_NODISCARD bool isa(const Y &Val)
Definition Casting.h:241
void stopAnalysisLimitTimer(void)
Stops analysis timer.
Definition SVFUtil.cpp:295
void startAnalysisLimitTimer(unsigned timeLimit)
Starts analysis timer. timeLimit must be non-0. Timer must not be already set.
Definition SVFUtil.cpp:281
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
std::stack< NodeID > NodeStack
Definition GeneralType.h:92
u32_t NodeID
Definition GeneralType.h:76
@ MayAlias
Definition SVFType.h:621
@ NoAlias
Definition SVFType.h:620
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition GeneralType.h:51