Static Value-Flow Analysis
Loading...
Searching...
No Matches
Andersen.cpp
Go to the documentation of this file.
1//===- Andersen.cpp -- Field-sensitive Andersen's 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 * Andersen.cpp
25 *
26 * Created on: Nov 12, 2013
27 * Author: Yulei Sui
28 */
29
30#include "Util/Options.h"
31#include "Graphs/CHG.h"
32#include "Util/SVFUtil.h"
34#include "WPA/Andersen.h"
35#include "WPA/Steensgaard.h"
36
37using namespace SVF;
38using namespace SVFUtil;
39using namespace std;
40
41
49
54
60
65{
66 delete consCG;
67 consCG = nullptr;
68}
69
74{
78 stat = new AndersenStat(this);
83 consCG->dump("consCG_initial");
84}
85
90{
93 consCG->dump("consCG_final");
94
96 consCG->print();
98}
99
101{
102 // Start solving constraints
103 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Start Solving Constraints\n"));
104
106
107 initWorklist();
108 do
109 {
112 printStat();
113
114 reanalyze = false;
115
117
119 reanalyze = true;
120
121 }
122 while (reanalyze);
123
124 // Analysis is finished, reset the alarm if we set it.
126
127 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Finish Solving Constraints\n"));
128}
129
134{
135 if(!Options::ReadAnder().empty())
136 {
138 }
139 else
140 {
141 if(Options::WriteAnder().empty())
142 {
143 initialize();
145 finalize();
146 }
147 else
148 {
150 }
151 }
152}
153
158{
159 initialize();
160 if (!filename.empty())
161 this->readFromFile(filename);
162 finalize();
163}
164
169{
171 initialize();
172 if (!filename.empty())
173 this->writeObjVarToFile(filename);
175 if (!filename.empty())
176 this->writeToFile(filename);
177 finalize();
178}
179
181{
183 for (NodeID sub: consCG->getSubs(id))
185 consCG->resetSubs(id);
186 consCG->resetRep(id);
187 assert(!consCG->hasGNode(id) && "this is either a rep nodeid or a sub nodeid should have already been merged to its field-insensitive base! ");
188}
189
191{
192
193 double cgUpdateStart = stat->getClk();
194
198 for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end();
199 it != eit; ++it)
200 {
201 for (FunctionSet::iterator cit = it->second.begin(),
202 ecit = it->second.end();
203 cit != ecit; ++cit)
204 {
206 }
207 }
208
210
211 for (NodePairSet::iterator it = cpySrcNodes.begin(),
212 eit = cpySrcNodes.end();
213 it != eit; ++it)
214 {
215 pushIntoWorklist(it->first);
216 }
217
218 double cgUpdateEnd = stat->getClk();
220
221 return ((!newEdges.empty()) || hasNewForkEdges);
222}
223
226{
229 for (CallEdgeMap::iterator it = newForkEdges.begin(), eit = newForkEdges.end(); it != eit; it++)
230 {
231 for (FunctionSet::iterator cit = it->second.begin(),
232 ecit = it->second.end();
233 cit != ecit; ++cit)
234 {
236 }
237 }
238 return !newForkEdges.empty();
239}
240
246{
247 assert(F);
248
249 DBOUT(DAndersen, outs() << "connect parameters from indirect forksite "
250 << cs->valueOnlyToString() << " to forked function "
251 << *F << "\n");
252
253 ThreadCallGraph *tdCallGraph = SVFUtil::dyn_cast<ThreadCallGraph>(callgraph);
254
255 const PAGNode *cs_arg = tdCallGraph->getThreadAPI()->getActualParmAtForkSite(cs);
256 const PAGNode *fun_arg = tdCallGraph->getThreadAPI()->getFormalParmOfForkedFun(F);
257
258 if(cs_arg->isPointer() && fun_arg->isPointer())
259 {
260 DBOUT(DAndersen, outs() << "process actual parm"
261 << cs_arg->toString() << "\n");
262 NodeID srcAA = sccRepNode(cs_arg->getId());
263 NodeID dstFA = sccRepNode(fun_arg->getId());
264 if (addCopyEdge(srcAA, dstFA))
265 {
266 cpySrcNodes.insert(std::make_pair(srcAA, dstFA));
267 }
268 }
269}
270
272// * Connect formal and actual parameters for indirect callsites
273// */
276{
277 assert(F);
278
279 DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs->valueOnlyToString() << " to callee " << *F << "\n");
280
281 const CallICFGNode* callBlockNode = cs;
283
285 {
287 }
288
290 {
292 const PAGNode* fun_return = pag->getFunRet(F);
293 if (cs_return->isPointer() && fun_return->isPointer())
294 {
295 NodeID dstrec = sccRepNode(cs_return->getId());
298 {
299 cpySrcNodes.insert(std::make_pair(srcret,dstrec));
300 }
301 }
302 else
303 {
304 DBOUT(DAndersen, outs() << "not a pointer ignored\n");
305 }
306 }
307
308 if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F))
309 {
310
311 // connect actual and formal param
312 const SVFIR::SVFVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
314 //Go through the fixed parameters.
315 DBOUT(DPAGBuild, outs() << " args:");
316 SVFIR::SVFVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
317 SVFIR::SVFVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
318 for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt)
319 {
320 //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
321 if (csArgIt == csArgEit)
322 {
323 DBOUT(DAndersen, outs() << " !! not enough args\n");
324 break;
325 }
326 const PAGNode *cs_arg = *csArgIt ;
327 const PAGNode *fun_arg = *funArgIt;
328
329 if (cs_arg->isPointer() && fun_arg->isPointer())
330 {
331 DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n");
332 NodeID srcAA = sccRepNode(cs_arg->getId());
333 NodeID dstFA = sccRepNode(fun_arg->getId());
335 {
336 cpySrcNodes.insert(std::make_pair(srcAA,dstFA));
337 }
338 }
339 }
340
341 //Any remaining actual args must be varargs.
342 if (F->isVarArg())
343 {
345 DBOUT(DPAGBuild, outs() << "\n varargs:");
346 for (; csArgIt != csArgEit; ++csArgIt)
347 {
348 const PAGNode *cs_arg = *csArgIt;
349 if (cs_arg->isPointer())
350 {
351 NodeID vnAA = sccRepNode(cs_arg->getId());
352 if (addCopyEdge(vnAA,vaF))
353 {
354 cpySrcNodes.insert(std::make_pair(vnAA,vaF));
355 }
356 }
357 }
358 }
359 if(csArgIt != csArgEit)
360 {
361 writeWrnMsg("too many args to non-vararg func.");
362 writeWrnMsg("(" + cs->getSourceLoc() + ")");
363 }
364 }
365}
366
368{
369 assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
373 CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
374 if(it != callsite2DummyValPN.end())
375 {
376 srcret = sccRepNode(it->second);
377 }
378 else
379 {
383 callsite2DummyValPN.insert(std::make_pair(cs,valNode));
386 srcret = valNode;
387 }
388
389 NodeID dstrec = sccRepNode(cs_return->getId());
391 cpySrcNodes.insert(std::make_pair(srcret,dstrec));
392}
393
395{
397 SVFIR::NodeOffsetMap &GepObjVarMap = pag->getGepObjNodeMap();
398
399 // clear GepObjVarMap/memToFieldsMap/nodeToSubsMap/nodeToRepMap
400 // for redundant gepnodes and remove those nodes from pag
402 {
403 NodeID base = pag->getBaseObjVar(n);
404 GepObjVar *gepNode = SVFUtil::dyn_cast<GepObjVar>(pag->getGNode(n));
405 assert(gepNode && "Not a gep node in redundantGepNodes set");
406 const APOffset apOffset = gepNode->getConstantFieldIdx();
407 GepObjVarMap.erase(std::make_pair(base, apOffset));
408 memToFieldsMap[base].reset(n);
409 cleanConsCG(n);
410
412 }
413}
414
419{
420 resetData();
422
424
427}
428
433{
434 // TODO: check -stat too.
435 // TODO: broken
437 {
439 const PTDataTy *ptd = getPTDataTy();
440 // TODO: should we use liveOnly?
441 // TODO: parameterise final arg.
444 }
445
448 // sanitizePts();
450}
451
456{
457 // sub nodes do not need to be processed
458 if (sccRepNode(nodeId) != nodeId)
459 return;
460
462 double insertStart = stat->getClk();
463 handleLoadStore(node);
464 double insertEnd = stat->getClk();
466
467 double propStart = stat->getClk();
468 handleCopyGep(node);
469 double propEnd = stat->getClk();
471}
472
477{
478 NodeID nodeId = node->getId();
480
481 if (!getDiffPts(nodeId).empty())
482 {
483 for (ConstraintEdge* edge : node->getCopyOutEdges())
485 for (ConstraintEdge* edge : node->getGepOutEdges())
486 {
487 if (GepCGEdge* gepEdge = SVFUtil::dyn_cast<GepCGEdge>(edge))
489 }
490 }
491}
492
497{
498 NodeID nodeId = node->getId();
499 for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter =
500 getPts(nodeId).end(); piter != epiter; ++piter)
501 {
502 NodeID ptd = *piter;
503 // handle load
505 eit = node->outgoingLoadsEnd(); it != eit; ++it)
506 {
507 if (processLoad(ptd, *it))
509 }
510
511 // handle store
513 eit = node->incomingStoresEnd(); it != eit; ++it)
514 {
515 if (processStore(ptd, *it))
516 pushIntoWorklist((*it)->getSrcID());
517 }
518 }
519}
520
525{
527 {
528 ConstraintNode * cgNode = nodeIt->second;
529 for (ConstraintNode::const_iterator it = cgNode->incomingAddrsBegin(), eit = cgNode->incomingAddrsEnd();
530 it != eit; ++it)
531 processAddr(SVFUtil::cast<AddrCGEdge>(*it));
532 }
533}
534
539{
541
542 NodeID dst = addr->getDstID();
543 NodeID src = addr->getSrcID();
544 if(addPts(dst,src))
545 pushIntoWorklist(dst);
546}
547
554{
558// if (pag->isBlkObjOrConstantObj(node))
559 if (pag->isConstantObj(node) || pag->getGNode(load->getDstID())->isPointer() == false)
560 return false;
561
563
564 NodeID dst = load->getDstID();
565 return addCopyEdge(node, dst);
566}
567
574{
578// if (pag->isBlkObjOrConstantObj(node))
579 if (pag->isConstantObj(node) || pag->getGNode(store->getSrcID())->isPointer() == false)
580 return false;
581
583
584 NodeID src = store->getSrcID();
585 return addCopyEdge(src, node);
586}
587
594{
596
597 assert((SVFUtil::isa<CopyCGEdge>(edge)) && "not copy/call/ret ??");
598 NodeID dst = edge->getDstID();
599 const PointsTo& srcPts = getDiffPts(node);
600
601 bool changed = unionPts(dst, srcPts);
602 if (changed)
603 pushIntoWorklist(dst);
604 return changed;
605}
606
614{
615 const PointsTo& srcPts = getDiffPts(edge->getSrcID());
616 return processGepPts(srcPts, edge);
617}
618
623{
625
627 if (SVFUtil::isa<VariantGepCGEdge>(edge))
628 {
629 // If a pointer is connected by a variant gep edge,
630 // then set this memory object to be field insensitive,
631 // unless the object is a black hole/constant.
632 for (NodeID o : pts)
633 {
635 {
636 tmpDstPts.set(o);
637 continue;
638 }
639
640 if (!isFieldInsensitive(o))
641 {
644 }
645
646 // Add the field-insensitive node into pts.
648 tmpDstPts.set(baseId);
649 }
650 }
651 else if (const NormalGepCGEdge* normalGepEdge = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
652 {
653 // TODO: after the node is set to field insensitive, handling invariant
654 // gep edge may lose precision because offsets here are ignored, and the
655 // base object is always returned.
656 for (NodeID o : pts)
657 {
659 {
660 tmpDstPts.set(o);
661 continue;
662 }
663
664 NodeID fieldSrcPtdNode = consCG->getGepObjVar(o, normalGepEdge->getAccessPath().getConstantStructFldIdx());
666 }
667 }
668 else
669 {
670 assert(false && "Andersen::processGepPts: New type GEP edge type?");
671 }
672
673 NodeID dstId = edge->getDstID();
675 {
677 return true;
678 }
679
680 return false;
681}
682
687{
688 // If a node is a PWC node, collapse all its points-to target.
689 // collapseNodePts() may change the points-to set of the nodes which have been processed
690 // before, in this case, we may need to re-do the analysis.
692 reanalyze = true;
693}
694
696{
698 {
700 // collapseField() may change the points-to set of the nodes which have been processed
701 // before, in this case, we may need to re-do the analysis.
702 if (collapseField(node))
703 reanalyze = true;
704 }
705}
706
707/*
708 * Merge constraint graph nodes based on SCC cycle detected.
709 */
711{
713 NodeStack & topoOrder = getSCCDetector()->topoNodeStack();
714 while (!topoOrder.empty())
715 {
716 NodeID repNodeId = topoOrder.top();
717 topoOrder.pop();
719 const NodeBS& subNodes = getSCCDetector()->subNodes(repNodeId);
720 // merge sub nodes to rep node
721 mergeSccNodes(repNodeId, subNodes);
722 }
723
724 // restore the topological order for later solving.
725 while (!revTopoOrder.empty())
726 {
727 NodeID nodeId = revTopoOrder.top();
728 revTopoOrder.pop();
729 topoOrder.push(nodeId);
730 }
731}
732
733
739{
740 for (NodeBS::iterator nodeIt = subNodes.begin(); nodeIt != subNodes.end(); nodeIt++)
741 {
743 if (subNodeId != repNodeId)
744 {
746 }
747 }
748}
749
754{
755 bool changed = false;
756 const PointsTo& nodePts = getPts(nodeId);
759 for (PointsTo::iterator ptsIt = ptsClone.begin(), ptsEit = ptsClone.end(); ptsIt != ptsEit; ptsIt++)
760 {
762 continue;
763
764 if (collapseField(*ptsIt))
765 changed = true;
766 }
767 return changed;
768}
769
774{
780 return false;
781
782 bool changed = false;
783
784 double start = stat->getClk();
785
786 // set base node field-insensitive.
788
789 // replace all occurrences of each field with the field-insensitive node
794 {
796 if (fieldId != baseId)
797 {
798 // use the reverse pts of this field node to find all pointers point to it
800 for (const NodeID o : revPts)
801 {
802 // change the points-to target from field to base node
804 addPts(o, baseId);
806
807 changed = true;
808 }
809 // merge field node into base node, including edges and pts.
812 if (fieldId != baseRepNodeId)
813 {
814 // gep node fieldId becomes redundant if it is merged to its base node who is set as field-insensitive
815 // two node IDs should be different otherwise this field is actually the base and should not be removed.
817 }
818 }
819 }
820
823 changed = true;
824
825 double end = stat->getClk();
826 timeOfCollapse += (end - start) / TIMEINTERVAL;
827
828 return changed;
829}
830
835{
837
838 double sccStart = stat->getClk();
840 double sccEnd = stat->getClk();
841
843
844 double mergeStart = stat->getClk();
845
847
848 double mergeEnd = stat->getClk();
849
851
852 return getSCCDetector()->topoNodeStack();
853}
854
859{
860
861 if(nodeId==newRepId)
862 return false;
863
867
871
876 if(node->isPWCNode())
877 pwc = true;
878
881
883
884 return pwc;
885}
886/*
887 * Merge a node to its rep node based on SCC detection
888 */
895
896/*
897 * Updates subnodes of its rep, and rep node of its subs
898 */
900{
905 // update nodeToSubsMap, union its subs with its rep Subs
907 for(NodeBS::iterator sit = nodeSubs.begin(), esit = nodeSubs.end(); sit!=esit; ++sit)
908 {
909 NodeID subId = *sit;
911 }
912 repSubs |= nodeSubs;
915}
916
917void Andersen::cluster(void) const
918{
919 assert(Options::MaxFieldLimit() == 0 && "Andersen::cluster: clustering for Andersen's is currently only supported in field-insensitive analysis");
921 std::vector<std::pair<unsigned, unsigned>> keys;
922 for (SVFIR::iterator pit = pag->begin(); pit != pag->end(); ++pit)
923 {
924 keys.push_back(std::make_pair(pit->first, 1));
925 }
926
927 std::vector<std::pair<hclust_fast_methods, std::vector<NodeID>>> candidates;
928 PointsTo::MappingPtr nodeMapping =
929 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::cluster(steens, keys, candidates, "aux-steens"));
930 PointsTo::MappingPtr reverseNodeMapping =
931 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
932
933 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
934}
935
940{
941 for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin();
942 nIter != this->getAllValidPtrs().end(); ++nIter)
943 {
944 const PAGNode* node = getPAG()->getGNode(*nIter);
945 if (getPAG()->isValidTopLevelPtr(node))
946 {
947 const PointsTo& pts = this->getPts(node->getId());
948 outs() << "\nNodeID " << node->getId() << " ";
949
950 if (pts.empty())
951 {
952 outs() << "\t\tPointsTo: {empty}\n";
953 }
954 else
955 {
956 outs() << "\t\tPointsTo: { ";
957
959 for (PointsTo::iterator it = pts.begin(), eit = pts.end();
960 it != eit; ++it)
961 {
962 line.insert(*it);
963 }
964 for (multiset<u32_t>::const_iterator it = line.begin(); it != line.end(); ++it)
965 {
967 if (auto gepNode = SVFUtil::dyn_cast<GepObjVar>(pag->getGNode(*it)))
968 outs() << gepNode->getBaseNode() << "_" << gepNode->getConstantFieldIdx() << " ";
969 else
970 outs() << *it << " ";
971 else
972 outs() << *it << " ";
973 }
974 outs() << "}\n";
975 }
976 }
977 }
978
979 outs().flush();
980}
981
unsigned u32_t
Definition CommandLine.h:18
#define F(f)
#define DBOUT(TYPE, X)
LLVM debug macros, define type of your DBUG model of each pass.
Definition SVFType.h:484
#define TIMEINTERVAL
Definition SVFType.h:512
#define DGENERAL
Definition SVFType.h:490
#define DPAGBuild
Definition SVFType.h:492
#define DAndersen
Definition SVFType.h:503
cJSON * n
Definition cJSON.cpp:2558
static double timeOfSCCMerges
Definition Andersen.h:167
static u32_t numOfProcessedCopy
Number of processed Addr edge.
Definition Andersen.h:158
static u32_t numOfSCCDetection
Definition Andersen.h:165
virtual void normalizePointsTo() override
static u32_t numOfSfrs
Number of processed Store edge.
Definition Andersen.h:162
virtual void finalize() override
Finalize analysis.
Definition Andersen.cpp:89
static double timeOfUpdateCallGraph
Definition Andersen.h:173
static u32_t numOfProcessedStore
Number of processed Load edge.
Definition Andersen.h:161
virtual void connectCaller2CalleeParams(const CallICFGNode *cs, const SVFFunction *F, NodePairSet &cpySrcNodes)
Connect formal and actual parameters for indirect callsites.
static u32_t numOfProcessedAddr
Statistics.
Definition Andersen.h:157
virtual bool updateCallGraph(const CallSiteToFunPtrMap &) override
Update call graph.
Definition Andersen.cpp:190
void printStat()
dump statistics
Definition Andersen.h:143
void heapAllocatorViaIndCall(const CallICFGNode *cs, NodePairSet &cpySrcNodes)
CallSite2DummyValPN callsite2DummyValPN
Definition Andersen.h:180
virtual void readPtsFromFile(const std::string &filename)
Definition Andersen.cpp:157
static u32_t numOfProcessedLoad
Number of processed Gep edge.
Definition Andersen.h:160
static double timeOfSCCDetection
Definition Andersen.h:166
NodeBS redundantGepNodes
Definition Andersen.h:153
virtual bool addCopyEdge(NodeID src, NodeID dst)=0
Add copy edge on constraint graph.
virtual void initialize() override
Initialize analysis.
Definition Andersen.cpp:73
~AndersenBase() override
Destructor.
Definition Andersen.cpp:64
virtual void analyze() override
Andersen analysis.
Definition Andersen.cpp:133
static u32_t numOfFieldExpand
Definition Andersen.h:163
static double timeOfProcessLoadStore
Definition Andersen.h:172
static u32_t numOfProcessedGep
Number of processed Copy edge.
Definition Andersen.h:159
static double timeOfProcessCopyGep
Definition Andersen.h:171
static u32_t MaxPointsToSetSize
Definition Andersen.h:170
virtual void solveConstraints()
Definition Andersen.cpp:100
virtual bool updateThreadCallGraph(const CallSiteToFunPtrMap &, NodePairSet &)
Update thread call graph.
Definition Andersen.cpp:224
static double timeOfCollapse
Definition Andersen.h:168
static u32_t AveragePointsToSetSize
Definition Andersen.h:169
virtual void solveAndwritePtsToFile(const std::string &filename)
Definition Andersen.cpp:168
ConstraintGraph * consCG
Constraint Graph.
Definition Andersen.h:178
void cleanConsCG(NodeID id)
remove redundant gepnodes in constraint graph
Definition Andersen.cpp:180
virtual void connectCaller2ForkedFunParams(const CallICFGNode *cs, const SVFFunction *F, NodePairSet &cpySrcNodes)
Connect formal and actual parameters for indirect forksites.
Definition Andersen.cpp:244
NodeID sccRepNode(NodeID id) const override
SCC methods.
Definition Andersen.h:129
virtual void handleLoadStore(ConstraintNode *node)
Definition Andersen.cpp:496
void mergeSccNodes(NodeID repNodeId, const NodeBS &subNodes)
Merge sub node in a SCC cycle to their rep node.
Definition Andersen.cpp:738
virtual void processNode(NodeID nodeId)
Override WPASolver function in order to use the default solver.
Definition Andersen.cpp:455
virtual void initialize()
Initialize analysis.
Definition Andersen.cpp:418
virtual NodeStack & SCCDetect()
SCC detection.
Definition Andersen.cpp:834
virtual void mergeNodeToRep(NodeID nodeId, NodeID newRepId)
Merge sub node to its rep.
Definition Andersen.cpp:889
bool collapseNodePts(NodeID nodeId)
Definition Andersen.cpp:753
void dumpTopLevelPtsTo()
Definition Andersen.cpp:939
void updatePropaPts(NodeID dstId, NodeID srcId)
Handle propagated points-to set.
Definition Andersen.h:286
virtual void computeDiffPts(NodeID id)
Handle diff points-to set.
Definition Andersen.h:268
virtual bool addCopyEdge(NodeID src, NodeID dst)
Add copy edge on constraint graph.
Definition Andersen.h:323
void resetData()
Reset data.
Definition Andersen.h:215
virtual const PointsTo & getDiffPts(NodeID id)
Definition Andersen.h:276
virtual bool processGep(NodeID node, const GepCGEdge *edge)
Definition Andersen.cpp:613
virtual void handleCopyGep(ConstraintNode *node)
Definition Andersen.cpp:476
virtual bool unionPts(NodeID id, const PointsTo &target)
Definition Andersen.h:243
virtual bool processLoad(NodeID node, const ConstraintEdge *load)
Definition Andersen.cpp:553
virtual const PointsTo & getPts(NodeID id)
Operation of points-to set.
Definition Andersen.h:239
void collapseFields()
collapse positive weight cycles of a graph
Definition Andersen.cpp:695
virtual bool processStore(NodeID node, const ConstraintEdge *load)
Definition Andersen.cpp:573
virtual bool processCopy(NodeID node, const ConstraintEdge *edge)
Definition Andersen.cpp:593
virtual bool processGepPts(const PointsTo &pts, const GepCGEdge *edge)
Definition Andersen.cpp:622
void mergeSccCycle()
Definition Andersen.cpp:710
virtual void processAddr(const AddrCGEdge *addr)
Definition Andersen.cpp:538
void updateNodeRepAndSubs(NodeID nodeId, NodeID newRepId)
Updates subnodes of its rep, and rep node of its subs.
Definition Andersen.cpp:899
virtual void finalize()
Finalize analysis.
Definition Andersen.cpp:432
void processAllAddr()
handling various constraints
Definition Andersen.cpp:524
virtual void cluster(void) const
Definition Andersen.cpp:917
virtual bool mergeSrcToTgt(NodeID srcId, NodeID tgtId)
Definition Andersen.cpp:858
virtual void collapsePWCNode(NodeID nodeId)
Collapse a field object into its base for field insensitive analysis.
Definition Andersen.cpp:686
bool collapseField(NodeID nodeId)
Definition Andersen.cpp:773
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)
const NodeSet & getRevPts(NodeID nodeId) override
virtual void clearPts(NodeID id, NodeID element)
Remove element from the points-to set of id.
void finalize() override
Finalization of pointer analysis, and normalize points-to information to Bit Vector representation.
virtual void onTheFlyThreadCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newForkEdges)
On the fly thread call graph construction respecting forksite.
virtual void onTheFlyCallGraphSolve(const CallSiteToFunPtrMap &callsites, CallEdgeMap &newEdges)
On the fly call graph construction.
PTData< NodeID, NodeSet, NodeID, PointsTo > PTDataTy
PTDataTy * getPTDataTy() const
Get points-to data structure.
virtual bool addPts(NodeID id, NodeID ptd)
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:457
const std::string getSourceLoc() const override
Definition ICFGNode.h:588
const SVFFunction * getCalledFunction() const
Definition ICFGNode.h:518
NodeID getNextCollapseNode()
Definition ConsG.h:370
void setPWCNode(NodeID nodeId)
Definition ConsG.h:354
void setSubs(NodeID node, NodeBS &subs)
Definition ConsG.h:252
void addNodeToBeCollapsed(NodeID id)
Definition ConsG.h:366
NodeID sccRepNode(NodeID id) const
SCC rep/sub nodes methods.
Definition ConsG.h:235
void addConstraintNode(ConstraintNode *node, NodeID id)
Definition ConsG.h:114
void resetSubs(NodeID node)
Definition ConsG.h:256
NodeID getGepObjVar(NodeID id, const APOffset &apOffset)
Get a field of a memory object.
Definition ConsG.h:330
NodeID getBaseObjVar(NodeID id)
Definition ConsG.h:320
NodeID getFIObjVar(NodeID id)
Get a field-insensitive node of a memory object.
Definition ConsG.h:339
NodeBS & getSubs(NodeID node)
Definition ConsG.h:260
bool isPWCNode(NodeID nodeId)
Check/Set PWC (positive weight cycle) flag.
Definition ConsG.h:350
bool isBlkObjOrConstantObj(NodeID id)
Definition ConsG.h:312
void removeConstraintNode(ConstraintNode *node)
Definition ConsG.h:123
void resetRep(NodeID node)
Definition ConsG.h:268
ConstraintNode * getConstraintNode(NodeID id) const
Get/add/remove constraint node.
Definition ConsG.h:109
bool hasNodesToBeCollapsed() const
Add/get nodes to be collapsed.
Definition ConsG.h:362
void print()
Print CG into terminal.
Definition ConsG.cpp:599
bool moveEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition ConsG.h:286
NodeBS & sccSubNodes(NodeID id)
Definition ConsG.h:243
void setRep(NodeID node, NodeID rep)
Definition ConsG.h:248
NodeID getRep(NodeID node)
Definition ConsG.h:264
NodeBS & getAllFieldsObjVars(NodeID id)
Definition ConsG.h:316
void dump(std::string name)
Dump graph into dot file.
Definition ConsG.cpp:591
bool isPWCNode() const
Whether a node involves in PWC, if so, all its points-to elements should become field-insensitive.
Definition ConsGNode.h:81
const_iterator outgoingLoadsEnd() const
Definition ConsGNode.h:194
const ConstraintEdge::ConstraintEdgeSetTy & getGepOutEdges() const
Definition ConsGNode.h:123
const_iterator incomingStoresBegin() const
Definition ConsGNode.h:215
const_iterator incomingStoresEnd() const
Definition ConsGNode.h:219
ConstraintEdge::ConstraintEdgeSetTy::const_iterator const_iterator
Definition ConsGNode.h:45
const ConstraintEdge::ConstraintEdgeSetTy & getCopyOutEdges() const
Definition ConsGNode.h:115
const_iterator outgoingLoadsBegin() const
Definition ConsGNode.h:190
NodeID getDstID() const
NodeID getSrcID() const
get methods of the components
iterator begin()
Iterators.
void removeGNode(NodeType *node)
Delete a node.
bool hasGNode(NodeID id) const
Has a node.
IDToNodeMapTy::iterator iterator
Node Iterators.
NodeType * getGNode(NodeID id) const
Get a node.
NodeID getVarargNode(const SVFFunction *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.h:157
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="")
static std::vector< NodeID > getReverseNodeMapping(const std::vector< NodeID > &nodeMapping)
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 const Option< u32_t > AnderTimeLimit
Time limit for the Andersen's analyses.
Definition Options.h:75
static const Option< bool > PrintFieldWithBasePrefix
Definition Options.h:118
static const Option< std::string > ReadAnder
Definition Options.h:214
static const Option< bool > ClusterAnder
Whether to stage Andersen's with Steensgaard and cluster based on that data.
Definition Options.h:41
static const Option< bool > PrintCGGraph
Definition Options.h:210
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:38
static const Option< std::string > WriteAnder
Definition Options.h:212
static const Option< bool > ConsCGDotGraph
Definition Options.h:208
bool isFieldInsensitive(NodeID id) const
OrderedMap< const CallICFGNode *, FunctionSet > CallEdgeMap
virtual void initialize()
Initialization of a pointer analysis, including building symbol table and SVFIR etc.
PTAStat * stat
Statistics.
SVFIR * getPAG() const
OrderedNodeSet & getAllValidPtrs()
Get all Valid Pointers for resolution.
const CallSiteToFunPtrMap & getIndirectCallsites() const
Return all indirect callsites.
void setObjFieldInsensitive(NodeID id)
PTACallGraph * callgraph
Call graph used for pointer analysis.
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
static SVFIR * pag
SVFIR.
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:42
static void setCurrentBestNodeMapping(MappingPtr newCurrentBestNodeMapping, MappingPtr newCurrentBestReverseNodeMapping)
Definition PointsTo.cpp:371
void set(u32_t n)
Inserts n in the set.
Definition PointsTo.cpp:157
static MappingPtr getCurrentBestNodeMapping()
Definition PointsTo.cpp:361
virtual const SVFType * getType() const
NodeID getId() const
Get ID.
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:746
bool isConstantObj(NodeID id) const
Definition SVFIR.h:465
std::vector< const SVFVar * > SVFVarList
Definition SVFIR.h:60
const SVFVarList & getFunArgsList(const SVFFunction *func) const
Get function arguments list.
Definition SVFIR.h:276
NodeID getBaseObjVar(NodeID id) const
Base and Offset methods for Value and Object node.
Definition SVFIR.h:477
const SVFVar * getFunRet(const SVFFunction *func) const
Get function return list.
Definition SVFIR.h:321
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:283
NodeOffsetMap & getGepObjNodeMap()
Return GepObjVarMap.
Definition SVFIR.h:135
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:311
NodeID addDummyValNode()
Definition SVFIR.h:496
Map< NodeID, NodeBS > MemObjToFieldsMap
Definition SVFIR.h:58
bool hasFunArgsList(const SVFFunction *func) const
Function has arguments list.
Definition SVFIR.h:266
const SVFVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:293
const SVFVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:305
Map< NodeOffset, NodeID > NodeOffsetMap
Definition SVFIR.h:71
NodeID addDummyObjNode(const SVFType *type)
Definition SVFIR.h:500
MemObjToFieldsMap & getMemToFieldsMap()
Return memToFieldsMap.
Definition SVFIR.h:130
bool funHasRet(const SVFFunction *func) const
Definition SVFIR.h:327
static double getClk(bool mark=false)
Definition SVFStat.cpp:48
virtual bool isPointer() const
Whether it is a pointer.
void set(unsigned Idx)
iterator begin() const
static Steensgaard * createSteensgaard(SVFIR *_pag)
Create an singleton instance.
Definition Steensgaard.h:31
SCC * getSCCDetector() const
Get SCC detector.
Definition WPASolver.h:67
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:156
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 iterationForPrintStat
print out statistics for i-th iteration
Definition WPASolver.h:173
u32_t numOfIteration
num of iterations during constraint solving
Definition WPASolver.h:200
bool reanalyze
Reanalyze if any constraint value changed.
Definition WPASolver.h:171
virtual void solveWorklist()
Definition WPASolver.h:108
void stopAnalysisLimitTimer(bool limitTimerSet)
Definition SVFUtil.cpp:311
bool isHeapAllocExtFunViaRet(const SVFFunction *fun)
Return true if the call is a heap allocator/reallocator.
Definition SVFUtil.h:296
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:100
bool startAnalysisLimitTimer(unsigned timeLimit)
Definition SVFUtil.cpp:290
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:67
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:50
for isBitcode
Definition BasicTypes.h:68
std::stack< NodeID > NodeStack
Set< NodeID > NodeSet
u32_t NodeID
Definition GeneralType.h:55
s64_t APOffset
Definition GeneralType.h:60
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:74
Set< NodePair > NodePairSet