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
80 double start = stat->getClk(true);
82 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Start Solving Constraints\n"));
83
84 do
85 {
87
89 dumpStat();
90
91 callGraphSCC->find();
92
95 }
97
98 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Finish Solving Constraints\n"));
99
100 // Reset the time-up alarm; analysis is done.
102
103 double end = stat->getClk(true);
104 solveTime += (end - start) / TIMEINTERVAL;
105
106}
107
112{
114 initialize();
115 if(!filename.empty())
118 if(!filename.empty())
121 finalize();
122}
123
128{
129 if(!Options::ReadAnder().empty())
130 {
132 }
133 else
134 {
135 if(Options::WriteAnder().empty())
136 {
137 initialize();
139 finalize();
140 }
141 else
142 {
144 }
145 }
146}
147
149{
151 initialize();
153 if(!filename.empty())
154 this->readFromFile(filename);
156 finalize();
157}
158
163{
164 if(Options::DumpVFG())
165 svfg->dump("fs_solved", true);
166
168 while (nodeStack.empty() == false)
169 {
170 NodeID rep = nodeStack.top();
171 nodeStack.pop();
172 const NodeBS& subNodes = getSCCDetector()->subNodes(rep);
173 if (subNodes.count() > maxSCCSize)
174 maxSCCSize = subNodes.count();
175 if (subNodes.count() > 1)
176 {
177 numOfNodesInSCC += subNodes.count();
178 numOfSCC++;
179 }
180 }
181
182 // TODO: check -stat too.
183 if (Options::ClusterFs())
184 {
186 const PTDataTy *ptd = getPTDataTy();
187 // TODO: should we use liveOnly?
188 Map<PointsTo, unsigned> allPts = ptd->getAllPts(true);
189 // TODO: parameterise final arg.
191 if (print_stat)
192 {
194 }
195 }
196
198}
199
204{
205 double start = stat->getClk();
207 double end = stat->getClk();
208 sccTime += (end - start) / TIMEINTERVAL;
209 return nodeStack;
210}
211
216{
218 if (processSVFGNode(node))
219 propagate(&node);
220
222}
223
228{
229 double start = stat->getClk();
230 bool changed = false;
231 if (AddrSVFGNode* addr = SVFUtil::dyn_cast<AddrSVFGNode>(node))
232 {
234 if (processAddr(addr))
235 changed = true;
236 }
237 else if (CopySVFGNode* copy = SVFUtil::dyn_cast<CopySVFGNode>(node))
238 {
240 if (processCopy(copy))
241 changed = true;
242 }
243 else if (GepSVFGNode* gep = SVFUtil::dyn_cast<GepSVFGNode>(node))
244 {
246 if(processGep(gep))
247 changed = true;
248 }
249 else if (LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
250 {
252 if(processLoad(load))
253 changed = true;
254 }
255 else if (StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
256 {
258 if (processStore(store))
259 changed = true;
260 }
261 else if (PHISVFGNode* phi = SVFUtil::dyn_cast<PHISVFGNode>(node))
262 {
264 if (processPhi(phi))
265 changed = true;
266 }
269 ActualOUTSVFGNode>(node))
270 {
272 changed = true;
273 }
276 NullPtrSVFGNode>(node))
277 {
278 changed = true;
279 }
280 else if (SVFUtil::isa<CmpVFGNode, BinaryOPVFGNode>(node) ||
281 SVFUtil::dyn_cast<UnaryOPVFGNode>(node))
282 {
283 }
284 else
285 {
286 assert(false && "unexpected kind of SVFG nodes");
287 }
288
289 double end = stat->getClk();
290 processTime += (end - start) / TIMEINTERVAL;
291
292 return changed;
293}
294
304{
305 double start = stat->getClk();
306 bool changed = false;
307
308 if (DirectSVFGEdge* dirEdge = SVFUtil::dyn_cast<DirectSVFGEdge>(edge))
310 else if (IndirectSVFGEdge* indEdge = SVFUtil::dyn_cast<IndirectSVFGEdge>(edge))
312 else
313 assert(false && "new kind of svfg edge?");
314
315 double end = stat->getClk();
317 return changed;
318}
319
324{
325 double start = stat->getClk();
326 bool changed = false;
327
328 SVFGNode* src = edge->getSrcNode();
329 SVFGNode* dst = edge->getDstNode();
330 // If this is an actual-param or formal-ret, top-level pointer's pts must be
331 // propagated from src to dst.
332 if (ActualParmSVFGNode* ap = SVFUtil::dyn_cast<ActualParmSVFGNode>(src))
333 changed = propagateFromAPToFP(ap, dst);
334 else if (FormalRetSVFGNode* fp = SVFUtil::dyn_cast<FormalRetSVFGNode>(src))
336 else
337 {
338 // Direct SVFG edge links between def and use of a top-level pointer.
339 // There's no points-to information propagated along direct edge.
340 // Since the top-level pointer's value has been changed at src node,
341 // return TRUE to put dst node into the work list.
342 changed = true;
343 }
344
345 double end = stat->getClk();
347 return changed;
348}
349
355{
356 const FormalParmSVFGNode* fp = SVFUtil::dyn_cast<FormalParmSVFGNode>(dst);
357 assert(fp && "expecting a formal param node");
358
359 NodeID pagDst = fp->getParam()->getId();
360 const PointsTo &srcCPts = getPts(ap->getParam()->getId());
362
363 return changed;
364}
365
371{
372 const ActualRetSVFGNode* ar = SVFUtil::dyn_cast<ActualRetSVFGNode>(dst);
373 assert(ar && "expecting an actual return node");
374
375 NodeID pagDst = ar->getRev()->getId();
376 const PointsTo & srcCPts = getPts(fr->getRet()->getId());
378
379 return changed;
380}
381
386{
387 double start = stat->getClk();
388
389 SVFGNode* src = edge->getSrcNode();
390 SVFGNode* dst = edge->getDstNode();
391
392 bool changed = false;
393
394 // Get points-to targets may be used by next SVFG node.
395 // Propagate points-to set for node used in dst.
396 const NodeBS& pts = edge->getPointsTo();
397 for (NodeBS::iterator ptdIt = pts.begin(), ptdEit = pts.end(); ptdIt != ptdEit; ++ptdIt)
398 {
399 NodeID ptd = *ptdIt;
400
401 if (propVarPtsFromSrcToDst(ptd, src, dst))
402 changed = true;
403
405 {
408 for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end();
410 {
411 if (propVarPtsFromSrcToDst(*fieldIt, src, dst))
412 changed = true;
413 }
414 }
415 }
416
417 double end = stat->getClk();
419 return changed;
420}
421
426{
427 bool changed = false;
428 if (SVFUtil::isa<StoreSVFGNode>(src))
429 {
430 if (updateInFromOut(src, var, dst, var))
431 changed = true;
432 }
433 else
434 {
435 if (updateInFromIn(src, var, dst, var))
436 changed = true;
437 }
438 return changed;
439}
440
445{
446 double start = stat->getClk();
447 NodeID srcID = addr->getSrcNodeID();
452 bool changed = addPts(addr->getDstNodeID(), srcID);
453 double end = stat->getClk();
454 addrTime += (end - start) / TIMEINTERVAL;
455 return changed;
456}
457
462{
463 double start = stat->getClk();
464 bool changed = unionPts(copy->getDstNodeID(), copy->getSrcNodeID());
465 double end = stat->getClk();
466 copyTime += (end - start) / TIMEINTERVAL;
467 return changed;
468}
469
474{
475 double start = stat->getClk();
476 bool changed = false;
477 NodeID pagDst = phi->getRes()->getId();
478 for (PHISVFGNode::OPVers::const_iterator it = phi->opVerBegin(), eit = phi->opVerEnd(); it != eit; ++it)
479 {
480 NodeID src = it->second->getId();
481 const PointsTo& srcPts = getPts(src);
482 if (unionPts(pagDst, srcPts))
483 changed = true;
484 }
485
486 double end = stat->getClk();
487 phiTime += (end - start) / TIMEINTERVAL;
488 return changed;
489}
490
495{
496 double start = stat->getClk();
497 bool changed = false;
498 const PointsTo& srcPts = getPts(edge->getSrcNodeID());
499
501 const GepStmt* gepStmt = SVFUtil::cast<GepStmt>(edge->getSVFStmt());
502 if (gepStmt->isVariantFieldGep())
503 {
504 for (NodeID o : srcPts)
505 {
507 {
508 tmpDstPts.set(o);
509 continue;
510 }
511
513 tmpDstPts.set(getFIObjVar(o));
514 }
515 }
516 else
517 {
518 for (NodeID o : srcPts)
519 {
521 {
522 tmpDstPts.set(o);
523 continue;
524 }
525
526 NodeID fieldSrcPtdNode = getGepObjVar(o, gepStmt->getAccessPath().getConstantStructFldIdx());
528 }
529 }
530
531 if (unionPts(edge->getDstNodeID(), tmpDstPts))
532 changed = true;
533
534 double end = stat->getClk();
535 gepTime += (end - start) / TIMEINTERVAL;
536 return changed;
537}
538
539
547{
548 double start = stat->getClk();
549 bool changed = false;
550
551 NodeID dstVar = load->getDstNodeID();
552
553 const PointsTo& srcPts = getPts(load->getSrcNodeID());
554
555 // p = *q, the type of p must be a pointer
556 if(load->getDstNode()->isPointer())
557 {
558 for (PointsTo::iterator ptdIt = srcPts.begin(); ptdIt != srcPts.end(); ++ptdIt)
559 {
560 NodeID ptd = *ptdIt;
561
562 if (pag->isConstantObj(ptd))
563 continue;
564
565 if (unionPtsFromIn(load, ptd, dstVar))
566 changed = true;
567
569 {
573 for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end();
575 {
576 if (unionPtsFromIn(load, *fieldIt, dstVar))
577 changed = true;
578 }
579 }
580 }
581 }
582 double end = stat->getClk();
583 loadTime += (end - start) / TIMEINTERVAL;
584 return changed;
585}
586
594{
595
596 const PointsTo & dstPts = getPts(store->getDstNodeID());
597
604 if (dstPts.empty())
605 return false;
606
607 double start = stat->getClk();
608 bool changed = false;
609
610 // *p = q, the type of q must be a pointer
611 if(getPts(store->getSrcNodeID()).empty() == false && store->getSrcNode()->isPointer())
612 {
613 for (PointsTo::iterator it = dstPts.begin(), eit = dstPts.end(); it != eit; ++it)
614 {
615 NodeID ptd = *it;
616
617 if (pag->isConstantObj(ptd))
618 continue;
619
620 if (unionPtsFromTop(store, store->getSrcNodeID(), ptd))
621 changed = true;
622 }
623 }
624
625 double end = stat->getClk();
626 storeTime += (end - start) / TIMEINTERVAL;
627
628 double updateStart = stat->getClk();
629 // also merge the DFInSet to DFOutSet.
632 bool isSU = isStrongUpdate(store, singleton);
633 if (isSU)
634 {
635 svfgHasSU.set(store->getId());
637 changed = true;
638 }
639 else
640 {
641 svfgHasSU.reset(store->getId());
642 if (weakUpdateOutFromIn(store))
643 changed = true;
644 }
645 double updateEnd = stat->getClk();
647
648 return changed;
649}
650
655{
656 bool isSU = false;
657 if (const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
658 {
659 const PointsTo& dstCPSet = getPts(store->getDstNodeID());
660 if (dstCPSet.count() == 1)
661 {
664 singleton = *it;
665
666 // Strong update can be made if this points-to target is not heap, array or field-insensitive.
668 {
672 {
673 isSU = true;
674 }
675 }
676 }
677 }
678 return isSU;
679}
680
685{
686 double start = stat->getClk();
689
690 // Bound the new edges by the Andersen's call graph.
691 // TODO: we want this to be an assertion eventually.
693 for (typename CallEdgeMap::value_type &csfs : newEdges)
694 {
695 const CallICFGNode *potentialCallSite = csfs.first;
697
698 // Check this callsite even calls anything per Andersen's.
699 typename CallEdgeMap::const_iterator andersFunctionSetIt
702 {
703 potentialFunctionSet.clear();
704 }
705
707 for (FunctionSet::iterator potentialFunctionIt = potentialFunctionSet.begin();
709 {
712 {
713 // potentialFunction is not in the Andersen's call graph -- remove it.
715 }
716 else
717 {
718 // potentialFunction is in the Andersen's call graph -- keep it..
720 }
721 }
722 }
723
726
728
729 double end = stat->getClk();
731 return (!newEdges.empty());
732}
733
738{
739 CallEdgeMap::const_iterator iter = newEdges.begin();
740 CallEdgeMap::const_iterator eiter = newEdges.end();
741 for (; iter != eiter; iter++)
742 {
743 const CallICFGNode* cs = iter->first;
744 const FunctionSet & functions = iter->second;
745 for (FunctionSet::const_iterator func_iter = functions.begin(); func_iter != functions.end(); func_iter++)
746 {
747 const FunObjVar* func = *func_iter;
749 }
750 }
751}
752
758{
759 for (const SVFGEdge* edge : edges)
760 {
761 SVFGNode* dstNode = edge->getDstNode();
762 if (SVFUtil::isa<PHISVFGNode>(dstNode))
763 {
766 pushIntoWorklist(dstNode->getId());
767 }
768 else if (SVFUtil::isa<FormalINSVFGNode, ActualOUTSVFGNode>(dstNode))
769 {
772 bool changed = false;
773
774 SVFGNode* srcNode = edge->getSrcNode();
775
776 const NodeBS& pts = SVFUtil::cast<IndirectSVFGEdge>(edge)->getPointsTo();
777 for (NodeBS::iterator ptdIt = pts.begin(), ptdEit = pts.end(); ptdIt != ptdEit; ++ptdIt)
778 {
779 NodeID ptd = *ptdIt;
780
782 changed = true;
783
785 {
788 for (NodeBS::iterator fieldIt = allFields.begin(), fieldEit = allFields.end();
790 {
792 changed = true;
793 }
794 }
795 }
796
797 if (changed)
798 pushIntoWorklist(dstNode->getId());
799 }
800 }
801}
802
803
808{
809 if (SVFUtil::isa<StoreSVFGNode>(src))
810 {
811 if (propDFOutToIn(src, var, dst, var))
812 return true;
813 }
814 else
815 {
816 if (propDFInToIn(src, var, dst, var))
817 return true;
818 }
819 return false;
820}
821
823{
824 std::vector<std::pair<unsigned, unsigned>> keys;
825 for (const auto& pair : *pag)
826 keys.emplace_back(pair.first, 1);
827
828 PointsTo::MappingPtr nodeMapping =
829 std::make_shared<std::vector<NodeID>>(
831 );
832 PointsTo::MappingPtr reverseNodeMapping =
833 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
834
835 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
836}
837
839{
841 && "FS::cluster: plain mapping requires dense allocation strategy.");
842
843 const size_t numObjects = NodeIDAllocator::get()->getNumObjects();
844 PointsTo::MappingPtr plainMapping = std::make_shared<std::vector<NodeID>>(numObjects);
845 PointsTo::MappingPtr reversePlainMapping = std::make_shared<std::vector<NodeID>>(numObjects);
846 for (NodeID i = 0; i < plainMapping->size(); ++i)
847 {
848 plainMapping->at(i) = i;
849 reversePlainMapping->at(i) = i;
850 }
851
853}
854
855void FlowSensitive::countAliases(Set<std::pair<NodeID, NodeID>> cmp, unsigned *mayAliases, unsigned *noAliases)
856{
857 for (std::pair<NodeID, NodeID> locPA : cmp)
858 {
859 // loc doesn't make a difference for FSPTA.
860 NodeID p = locPA.second;
861 for (std::pair<NodeID, NodeID> locPB : cmp)
862 {
863 if (locPB == locPA) continue;
864
865 NodeID q = locPB.second;
866
867 switch (alias(p, q))
868 {
870 ++(*noAliases);
871 break;
873 ++(*mayAliases);
874 break;
875 default:
876 assert("Not May/NoAlias?");
877 }
878 }
879 }
880
881}
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:593
#define TIMEINTERVAL
Definition SVFType.h:621
#define DGENERAL
Definition SVFType.h:599
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:408
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:44
static const OptionMap< SVF::NodeIDAllocator::Strategy > NodeAllocStrat
Definition Options.h:32
static const Option< std::string > ReadAnder
Definition Options.h:208
static const Option< bool > ClusterAnder
Whether to stage Andersen's with Steensgaard and cluster based on that data.
Definition Options.h:38
static const Option< u32_t > FsTimeLimit
Time limit for the main phase (i.e., the actual solving) of FS analyses.
Definition Options.h:69
static const Option< bool > ClusterFs
Whether to cluster FS or VFS with the auxiliary Andersen's.
Definition Options.h:41
static const Option< std::string > WriteAnder
Definition Options.h:206
static const Option< bool > DumpVFG
Definition Options.h:108
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:98
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:42
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:371
static MappingPtr getCurrentBestNodeMapping()
Definition PointsTo.cpp:361
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:540
const BaseObjVar * getBaseObject(NodeID id) const
Definition SVFIR.h:496
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
NodeID getId() const
Get ID.
Definition SVFValue.h:161
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:64
virtual NodeStack & SCCDetect()
SCC detection.
Definition WPAFSSolver.h:67
SCC * getSCCDetector() const
Get SCC detector.
Definition WPASolver.h:67
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:156
virtual void propagate(GNODE *v)
Definition WPASolver.h:127
virtual void initWorklist()
Definition WPASolver.h:97
void setGraph(GraphType g)
Definition WPASolver.h:78
virtual NodeStack & SCCDetect()
SCC detection.
Definition WPASolver.h:86
u32_t numOfIteration
num of iterations during constraint solving
Definition WPASolver.h:200
virtual void solveWorklist()
Definition WPASolver.h:108
void stopAnalysisLimitTimer(bool limitTimerSet)
Definition SVFUtil.cpp:302
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
bool startAnalysisLimitTimer(unsigned timeLimit)
Definition SVFUtil.cpp:281
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
std::stack< NodeID > NodeStack
u32_t NodeID
Definition GeneralType.h:56
@ MayAlias
Definition SVFType.h:638
@ NoAlias
Definition SVFType.h:637
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition GeneralType.h:96