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
32#include "WPA/Andersen.h"
33#include "WPA/Steensgaard.h"
34#include "WPA/WPAStat.h"
35#include "Util/GeneralType.h"
36#include "Util/Options.h"
37#include "Util/SVFUtil.h"
38
39using namespace SVF;
40using namespace SVFUtil;
41using namespace std;
42
43
51
56
62
67{
68 delete consCG;
69 consCG = nullptr;
70}
71
76{
80 stat = new AndersenStat(this);
85 consCG->dump("consCG_initial");
86}
87
92{
95 consCG->dump("consCG_final");
96
98 consCG->print();
100}
101
103{
104 // Start solving constraints
105 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Start Solving Constraints\n"));
106
108
109 initWorklist();
110 do
111 {
114 printStat();
115
116 reanalyze = false;
117
119
121 reanalyze = true;
122
123 }
124 while (reanalyze);
125
126 // Analysis is finished, reset the alarm if we set it.
128
129 DBOUT(DGENERAL, outs() << SVFUtil::pasMsg("Finish Solving Constraints\n"));
130}
131
136{
137 if(!Options::ReadAnder().empty())
138 {
140 }
141 else
142 {
143 if(Options::WriteAnder().empty())
144 {
145 initialize();
147 finalize();
148 }
149 else
150 {
152 }
153 }
154}
155
160{
161 initialize();
162 if (!filename.empty())
163 this->readFromFile(filename);
164 finalize();
165}
166
171{
173 initialize();
174 if (!filename.empty())
175 this->writeObjVarToFile(filename);
177 if (!filename.empty())
178 this->writeToFile(filename);
179 finalize();
180}
181
183{
185 for (NodeID sub: consCG->getSubs(id))
187 consCG->resetSubs(id);
188 consCG->resetRep(id);
189 assert(!consCG->hasGNode(id) && "this is either a rep nodeid or a sub nodeid should have already been merged to its field-insensitive base! ");
190}
191
193{
194
195 double cgUpdateStart = stat->getClk();
196
200 for (CallEdgeMap::iterator it = newEdges.begin(), eit = newEdges.end();
201 it != eit; ++it)
202 {
203 for (FunctionSet::iterator cit = it->second.begin(),
204 ecit = it->second.end();
205 cit != ecit; ++cit)
206 {
208 }
209 }
210
212
213 for (NodePairSet::iterator it = cpySrcNodes.begin(),
214 eit = cpySrcNodes.end();
215 it != eit; ++it)
216 {
217 pushIntoWorklist(it->first);
218 }
219
220 double cgUpdateEnd = stat->getClk();
222
223 return ((!newEdges.empty()) || hasNewForkEdges);
224}
225
228{
231 for (CallEdgeMap::iterator it = newForkEdges.begin(), eit = newForkEdges.end(); it != eit; it++)
232 {
233 for (FunctionSet::iterator cit = it->second.begin(),
234 ecit = it->second.end();
235 cit != ecit; ++cit)
236 {
238 }
239 }
240 return !newForkEdges.empty();
241}
242
248{
249 assert(F);
250
251 DBOUT(DAndersen, outs() << "connect parameters from indirect forksite "
252 << cs->valueOnlyToString() << " to forked function "
253 << *F << "\n");
254
255 ThreadCallGraph *tdCallGraph = SVFUtil::dyn_cast<ThreadCallGraph>(callgraph);
256
257 const PAGNode *cs_arg = tdCallGraph->getThreadAPI()->getActualParmAtForkSite(cs);
258 const PAGNode *fun_arg = tdCallGraph->getThreadAPI()->getFormalParmOfForkedFun(F);
259
260 if(cs_arg->isPointer() && fun_arg->isPointer())
261 {
262 DBOUT(DAndersen, outs() << "process actual parm"
263 << cs_arg->toString() << "\n");
264 NodeID srcAA = sccRepNode(cs_arg->getId());
265 NodeID dstFA = sccRepNode(fun_arg->getId());
266 if (addCopyEdge(srcAA, dstFA))
267 {
268 cpySrcNodes.insert(std::make_pair(srcAA, dstFA));
269 }
270 }
271}
272
274// * Connect formal and actual parameters for indirect callsites
275// */
278{
279 assert(F);
280
281 DBOUT(DAndersen, outs() << "connect parameters from indirect callsite " << cs->valueOnlyToString() << " to callee " << *F << "\n");
282
283 const CallICFGNode* callBlockNode = cs;
285
287 {
289 }
290
292 {
294 const PAGNode* fun_return = pag->getFunRet(F);
295 if (cs_return->isPointer() && fun_return->isPointer())
296 {
297 NodeID dstrec = sccRepNode(cs_return->getId());
300 {
301 cpySrcNodes.insert(std::make_pair(srcret,dstrec));
302 }
303 }
304 else
305 {
306 DBOUT(DAndersen, outs() << "not a pointer ignored\n");
307 }
308 }
309
310 if (pag->hasCallSiteArgsMap(callBlockNode) && pag->hasFunArgsList(F))
311 {
312
313 // connect actual and formal param
314 const SVFIR::ValVarList& csArgList = pag->getCallSiteArgsList(callBlockNode);
316 //Go through the fixed parameters.
317 DBOUT(DPAGBuild, outs() << " args:");
318 SVFIR::ValVarList::const_iterator funArgIt = funArgList.begin(), funArgEit = funArgList.end();
319 SVFIR::ValVarList::const_iterator csArgIt = csArgList.begin(), csArgEit = csArgList.end();
320 for (; funArgIt != funArgEit; ++csArgIt, ++funArgIt)
321 {
322 //Some programs (e.g. Linux kernel) leave unneeded parameters empty.
323 if (csArgIt == csArgEit)
324 {
325 DBOUT(DAndersen, outs() << " !! not enough args\n");
326 break;
327 }
328 const PAGNode *cs_arg = *csArgIt ;
329 const PAGNode *fun_arg = *funArgIt;
330
331 if (cs_arg->isPointer() && fun_arg->isPointer())
332 {
333 DBOUT(DAndersen, outs() << "process actual parm " << cs_arg->toString() << " \n");
334 NodeID srcAA = sccRepNode(cs_arg->getId());
335 NodeID dstFA = sccRepNode(fun_arg->getId());
337 {
338 cpySrcNodes.insert(std::make_pair(srcAA,dstFA));
339 }
340 }
341 }
342
343 //Any remaining actual args must be varargs.
344 if (F->isVarArg())
345 {
347 DBOUT(DPAGBuild, outs() << "\n varargs:");
348 for (; csArgIt != csArgEit; ++csArgIt)
349 {
350 const PAGNode *cs_arg = *csArgIt;
351 if (cs_arg->isPointer())
352 {
353 NodeID vnAA = sccRepNode(cs_arg->getId());
354 if (addCopyEdge(vnAA,vaF))
355 {
356 cpySrcNodes.insert(std::make_pair(vnAA,vaF));
357 }
358 }
359 }
360 }
361 if(csArgIt != csArgEit)
362 {
363 writeWrnMsg("too many args to non-vararg func.");
364 writeWrnMsg("(" + cs->getSourceLoc() + ")");
365 }
366 }
367}
368
370{
371 assert(cs->getCalledFunction() == nullptr && "not an indirect callsite?");
375 CallSite2DummyValPN::const_iterator it = callsite2DummyValPN.find(cs);
376 if(it != callsite2DummyValPN.end())
377 {
378 srcret = sccRepNode(it->second);
379 }
380 else
381 {
385 callsite2DummyValPN.insert(std::make_pair(cs,valNode));
388 srcret = valNode;
389 }
390
391 NodeID dstrec = sccRepNode(cs_return->getId());
393 cpySrcNodes.insert(std::make_pair(srcret,dstrec));
394}
395
397{
400
401 // clear GepObjVarMap/memToFieldsMap/nodeToSubsMap/nodeToRepMap
402 // for redundant gepnodes and remove those nodes from pag
404 {
405 NodeID base = pag->getBaseObjVarID(n);
407 assert(gepNode && "Not a gep node in redundantGepNodes set");
408 const APOffset apOffset = gepNode->getConstantFieldIdx();
409 GepObjVarMap.erase(std::make_pair(base, apOffset));
410 memToFieldsMap[base].reset(n);
411 cleanConsCG(n);
412
413 pag->removeGNode(const_cast<GepObjVar*>(gepNode));
414 }
415}
416
421{
422 resetData();
424
426
429}
430
435{
436 // TODO: broken
438 {
440 const PTDataTy *ptd = getPTDataTy();
441 // TODO: should we use liveOnly?
442 // TODO: parameterise final arg.
444 if (print_stat)
445 {
447 }
448 }
449
452 // sanitizePts();
454}
455
460{
461 // sub nodes do not need to be processed
462 if (sccRepNode(nodeId) != nodeId)
463 return;
464
466 double insertStart = stat->getClk();
467 handleLoadStore(node);
468 double insertEnd = stat->getClk();
470
471 double propStart = stat->getClk();
472 handleCopyGep(node);
473 double propEnd = stat->getClk();
475}
476
481{
482 NodeID nodeId = node->getId();
484
485 if (!getDiffPts(nodeId).empty())
486 {
487 for (ConstraintEdge* edge : node->getCopyOutEdges())
489 for (ConstraintEdge* edge : node->getGepOutEdges())
490 {
491 if (GepCGEdge* gepEdge = SVFUtil::dyn_cast<GepCGEdge>(edge))
493 }
494 }
495}
496
501{
502 NodeID nodeId = node->getId();
503 for (PointsTo::iterator piter = getPts(nodeId).begin(), epiter =
504 getPts(nodeId).end(); piter != epiter; ++piter)
505 {
506 NodeID ptd = *piter;
507 // handle load
509 eit = node->outgoingLoadsEnd(); it != eit; ++it)
510 {
511 if (processLoad(ptd, *it))
513 }
514
515 // handle store
517 eit = node->incomingStoresEnd(); it != eit; ++it)
518 {
519 if (processStore(ptd, *it))
520 pushIntoWorklist((*it)->getSrcID());
521 }
522 }
523}
524
529{
531 {
532 ConstraintNode * cgNode = nodeIt->second;
534 it != eit; ++it)
535 processAddr(SVFUtil::cast<AddrCGEdge>(*it));
536 }
537}
538
543{
545
546 NodeID dst = addr->getDstID();
547 NodeID src = addr->getSrcID();
548 if(addPts(dst,src))
549 pushIntoWorklist(dst);
550}
551
558{
562// if (pag->isBlkObjOrConstantObj(node))
563 if (pag->isConstantObj(node) || pag->getSVFVar(load->getDstID())->isPointer() == false)
564 return false;
565
567
568 NodeID dst = load->getDstID();
569 return addCopyEdge(node, dst);
570}
571
578{
582// if (pag->isBlkObjOrConstantObj(node))
583 if (pag->isConstantObj(node) || pag->getSVFVar(store->getSrcID())->isPointer() == false)
584 return false;
585
587
588 NodeID src = store->getSrcID();
589 return addCopyEdge(src, node);
590}
591
598{
600
601 assert((SVFUtil::isa<CopyCGEdge>(edge)) && "not copy/call/ret ??");
602 NodeID dst = edge->getDstID();
603 const PointsTo& srcPts = getDiffPts(node);
604
605 bool changed = unionPts(dst, srcPts);
606 if (changed)
607 pushIntoWorklist(dst);
608 return changed;
609}
610
618{
619 const PointsTo& srcPts = getDiffPts(edge->getSrcID());
620 return processGepPts(srcPts, edge);
621}
622
627{
629
631 if (SVFUtil::isa<VariantGepCGEdge>(edge))
632 {
633 // If a pointer is connected by a variant gep edge,
634 // then set this memory object to be field insensitive,
635 // unless the object is a black hole/constant.
636 for (NodeID o : pts)
637 {
639 {
640 tmpDstPts.set(o);
641 continue;
642 }
643
644 if (!isFieldInsensitive(o))
645 {
648 }
649
650 // Add the field-insensitive node into pts.
652 tmpDstPts.set(baseId);
653 }
654 }
655 else if (const NormalGepCGEdge* normalGepEdge = SVFUtil::dyn_cast<NormalGepCGEdge>(edge))
656 {
657 // TODO: after the node is set to field insensitive, handling invariant
658 // gep edge may lose precision because offsets here are ignored, and the
659 // base object is always returned.
660 for (NodeID o : pts)
661 {
663 {
664 tmpDstPts.set(o);
665 continue;
666 }
667
668 NodeID fieldSrcPtdNode = consCG->getGepObjVar(o, normalGepEdge->getAccessPath().getConstantStructFldIdx());
670 }
671 }
672 else
673 {
674 assert(false && "Andersen::processGepPts: New type GEP edge type?");
675 }
676
677 NodeID dstId = edge->getDstID();
679 {
681 return true;
682 }
683
684 return false;
685}
686
691{
692 // If a node is a PWC node, collapse all its points-to target.
693 // collapseNodePts() may change the points-to set of the nodes which have been processed
694 // before, in this case, we may need to re-do the analysis.
696 reanalyze = true;
697}
698
700{
702 {
704 // collapseField() may change the points-to set of the nodes which have been processed
705 // before, in this case, we may need to re-do the analysis.
706 if (collapseField(node))
707 reanalyze = true;
708 }
709}
710
711/*
712 * Merge constraint graph nodes based on SCC cycle detected.
713 */
715{
716 NodeStack topoOrder = getSCCDetector()->topoNodeStack();
717
718 while (!topoOrder.empty())
719 {
720 NodeID repNodeId = topoOrder.top();
721 topoOrder.pop();
722 const NodeBS& subNodes = getSCCDetector()->subNodes(repNodeId);
723 // merge sub nodes to rep node
724 mergeSccNodes(repNodeId, subNodes);
725 if (subNodes.count() > 1)
726 {
728 reanalyze = true;
729 }
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>>(
930 NodeIDAllocator::Clusterer::cluster(steens, keys, candidates, "aux-steens", print_stat)
931 );
932 PointsTo::MappingPtr reverseNodeMapping =
933 std::make_shared<std::vector<NodeID>>(NodeIDAllocator::Clusterer::getReverseNodeMapping(*nodeMapping));
934
935 PointsTo::setCurrentBestNodeMapping(nodeMapping, reverseNodeMapping);
936}
937
942{
943 for (OrderedNodeSet::iterator nIter = this->getAllValidPtrs().begin();
944 nIter != this->getAllValidPtrs().end(); ++nIter)
945 {
946 const SVFVar* node = getPAG()->getSVFVar(*nIter);
947 if (getPAG()->isValidTopLevelPtr(node))
948 {
949 const PointsTo& pts = this->getPts(node->getId());
950 outs() << "\nNodeID " << node->getId() << " ";
951
952 if (pts.empty())
953 {
954 outs() << "\t\tPointsTo: {empty}\n";
955 }
956 else
957 {
958 outs() << "\t\tPointsTo: { ";
959
961 for (PointsTo::iterator it = pts.begin(), eit = pts.end();
962 it != eit; ++it)
963 {
964 line.insert(*it);
965 }
966 for (multiset<u32_t>::const_iterator it = line.begin(); it != line.end(); ++it)
967 {
969 if (auto gepNode = pag->getGepObjVar(*it))
970 outs() << gepNode->getBaseNode() << "_" << gepNode->getConstantFieldIdx() << " ";
971 else
972 outs() << *it << " ";
973 else
974 outs() << *it << " ";
975 }
976 outs() << "}\n";
977 }
978 }
979 }
980
981 outs().flush();
982}
983
unsigned u32_t
Definition CommandLine.h:18
#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
#define DPAGBuild
Definition SVFType.h:584
#define DAndersen
Definition SVFType.h:595
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:91
static double timeOfUpdateCallGraph
Definition Andersen.h:173
static u32_t numOfProcessedStore
Number of processed Load edge.
Definition Andersen.h:161
virtual void connectCaller2ForkedFunParams(const CallICFGNode *cs, const FunObjVar *F, NodePairSet &cpySrcNodes)
Connect formal and actual parameters for indirect forksites.
Definition Andersen.cpp:246
static u32_t numOfProcessedAddr
Statistics.
Definition Andersen.h:157
virtual bool updateCallGraph(const CallSiteToFunPtrMap &) override
Update call graph.
Definition Andersen.cpp:192
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:159
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:75
~AndersenBase() override
Destructor.
Definition Andersen.cpp:66
virtual void analyze() override
Andersen analysis.
Definition Andersen.cpp:135
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:102
virtual bool updateThreadCallGraph(const CallSiteToFunPtrMap &, NodePairSet &)
Update thread call graph.
Definition Andersen.cpp:226
virtual void connectCaller2CalleeParams(const CallICFGNode *cs, const FunObjVar *F, NodePairSet &cpySrcNodes)
Connect formal and actual parameters for indirect callsites.
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:170
ConstraintGraph * consCG
Constraint Graph.
Definition Andersen.h:178
void cleanConsCG(NodeID id)
remove redundant gepnodes in constraint graph
Definition Andersen.cpp:182
NodeID sccRepNode(NodeID id) const override
SCC methods.
Definition Andersen.h:129
virtual void handleLoadStore(ConstraintNode *node)
Definition Andersen.cpp:500
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:459
virtual void initialize()
Initialize analysis.
Definition Andersen.cpp:420
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:941
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:617
virtual void handleCopyGep(ConstraintNode *node)
Definition Andersen.cpp:480
virtual bool unionPts(NodeID id, const PointsTo &target)
Definition Andersen.h:243
virtual bool processLoad(NodeID node, const ConstraintEdge *load)
Definition Andersen.cpp:557
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:699
virtual bool processStore(NodeID node, const ConstraintEdge *load)
Definition Andersen.cpp:577
virtual bool processCopy(NodeID node, const ConstraintEdge *edge)
Definition Andersen.cpp:597
virtual bool processGepPts(const PointsTo &pts, const GepCGEdge *edge)
Definition Andersen.cpp:626
void mergeSccCycle()
Definition Andersen.cpp:714
virtual void processAddr(const AddrCGEdge *addr)
Definition Andersen.cpp:542
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:434
void processAllAddr()
handling various constraints
Definition Andersen.cpp:528
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:690
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 FunObjVar * getCalledFunction() const
Definition ICFGNode.h:501
const RetICFGNode * getRetICFGNode() const
Return callsite.
Definition ICFGNode.h:440
const std::string getSourceLoc() const override
Definition ICFGNode.h:571
NodeID getNextCollapseNode()
Definition ConsG.h:365
void setPWCNode(NodeID nodeId)
Definition ConsG.h:349
void setSubs(NodeID node, NodeBS &subs)
Definition ConsG.h:247
void addNodeToBeCollapsed(NodeID id)
Definition ConsG.h:361
NodeID getBaseObjVarID(NodeID id)
Definition ConsG.h:315
NodeID sccRepNode(NodeID id) const
SCC rep/sub nodes methods.
Definition ConsG.h:230
void addConstraintNode(ConstraintNode *node, NodeID id)
Definition ConsG.h:109
void resetSubs(NodeID node)
Definition ConsG.h:251
NodeID getGepObjVar(NodeID id, const APOffset &apOffset)
Get a field of a memory object.
Definition ConsG.h:325
NodeID getFIObjVar(NodeID id)
Get a field-insensitive node of a memory object.
Definition ConsG.h:334
NodeBS & getSubs(NodeID node)
Definition ConsG.h:255
bool isPWCNode(NodeID nodeId)
Check/Set PWC (positive weight cycle) flag.
Definition ConsG.h:345
bool isBlkObjOrConstantObj(NodeID id)
Definition ConsG.h:307
void removeConstraintNode(ConstraintNode *node)
Definition ConsG.h:118
void resetRep(NodeID node)
Definition ConsG.h:263
ConstraintNode * getConstraintNode(NodeID id) const
Get/add/remove constraint node.
Definition ConsG.h:104
bool hasNodesToBeCollapsed() const
Add/get nodes to be collapsed.
Definition ConsG.h:357
void print()
Print CG into terminal.
Definition ConsG.cpp:603
bool moveEdgesToRepNode(ConstraintNode *node, ConstraintNode *rep)
Definition ConsG.h:281
NodeBS & sccSubNodes(NodeID id)
Definition ConsG.h:238
void setRep(NodeID node, NodeID rep)
Definition ConsG.h:243
NodeID getRep(NodeID node)
Definition ConsG.h:259
NodeBS & getAllFieldsObjVars(NodeID id)
Definition ConsG.h:311
void dump(std::string name)
Dump graph into dot file.
Definition ConsG.cpp:595
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_iterator incomingAddrsBegin() const
Definition ConsGNode.h:181
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 incomingAddrsEnd() const
Definition ConsGNode.h:185
const_iterator outgoingLoadsBegin() const
Definition ConsGNode.h:190
bool isVarArg() const
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.
NodeID getVarargNode(const FunObjVar *func) const
getVarargNode - Return the unique node representing the variadic argument of a variadic function.
Definition IRGraph.cpp:71
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 const Option< u32_t > AnderTimeLimit
Time limit for the Andersen's analyses.
Definition Options.h:71
static const Option< bool > PrintFieldWithBasePrefix
Definition Options.h:114
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< bool > PrintCGGraph
Definition Options.h:200
static const Option< u32_t > MaxFieldLimit
Maximum number of field derivations for an object.
Definition Options.h:34
static const Option< std::string > WriteAnder
Definition Options.h:202
static const Option< bool > ConsCGDotGraph
Definition Options.h:198
bool isFieldInsensitive(NodeID id) const
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.
PTAStat * stat
Statistics.
SVFIR * getPAG() const
OrderedNodeSet & getAllValidPtrs()
Get all Valid Pointers for resolution.
const CallSiteToFunPtrMap & getIndirectCallsites() const
Return all indirect callsites.
CallGraph * callgraph
Call graph used for pointer analysis.
void setObjFieldInsensitive(NodeID id)
SVFIR::CallSiteToFunPtrMap CallSiteToFunPtrMap
static SVFIR * pag
SVFIR.
std::shared_ptr< std::vector< NodeID > > MappingPtr
Definition PointsTo.h:43
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
bool funHasRet(const FunObjVar *func) const
Definition SVFIR.h:429
bool hasFunArgsList(const FunObjVar *func) const
Function has arguments list.
Definition SVFIR.h:368
NodeID getBaseObjVarID(NodeID id) const
Base and Offset methods for Value and Object node.
Definition SVFIR.h:554
const ValVar * getCallSiteRet(const RetICFGNode *cs) const
Get callsite return.
Definition SVFIR.h:407
const ValVarList & getFunArgsList(const FunObjVar *func) const
Get function arguments list.
Definition SVFIR.h:378
std::vector< const ValVar * > ValVarList
Definition SVFIR.h:60
bool isConstantObj(NodeID id) const
Definition SVFIR.h:542
bool hasCallSiteArgsMap(const CallICFGNode *cs) const
Callsite has argument list.
Definition SVFIR.h:385
const SVFVar * getSVFVar(NodeID id) const
ObjVar/GepObjVar/BaseObjVar.
Definition SVFIR.h:135
bool callsiteHasRet(const RetICFGNode *cs) const
Definition SVFIR.h:413
NodeID addDummyValNode()
Definition SVFIR.h:566
OffsetToGepVarMap & getGepObjNodeMap()
Return GepObjVarMap.
Definition SVFIR.h:203
Map< NodeID, NodeBS > MemObjToFieldsMap
Definition SVFIR.h:58
Map< GepOffset, NodeID > OffsetToGepVarMap
Definition SVFIR.h:72
const ValVar * getFunRet(const FunObjVar *func) const
Get function return list.
Definition SVFIR.h:423
const ValVarList & getCallSiteArgsList(const CallICFGNode *cs) const
Get callsite argument list.
Definition SVFIR.h:395
const GepObjVar * getGepObjVar(NodeID id) const
Definition SVFIR.h:169
NodeID addDummyObjNode(const SVFType *type)
Definition SVFIR.h:570
MemObjToFieldsMap & getMemToFieldsMap()
Return memToFieldsMap.
Definition SVFIR.h:198
static double getClk(bool mark=false)
Definition SVFStat.cpp:51
NodeID getId() const
Get ID.
Definition SVFValue.h:158
virtual const SVFType * getType() const
Definition SVFValue.h:169
const std::string valueOnlyToString() const
Definition LLVMUtil.cpp:741
virtual bool isPointer() const
Check if this variable represents a pointer.
void set(unsigned Idx)
unsigned count() const
iterator begin() const
static Steensgaard * createSteensgaard(SVFIR *_pag)
Create an singleton instance.
Definition Steensgaard.h:36
SCC * getSCCDetector() const
Get SCC detector.
Definition WPASolver.h:68
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:157
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 iterationForPrintStat
print out statistics for i-th iteration
Definition WPASolver.h:174
u32_t numOfIteration
num of iterations during constraint solving
Definition WPASolver.h:201
bool reanalyze
Reanalyze if any constraint value changed.
Definition WPASolver.h:172
virtual void solveWorklist()
Definition WPASolver.h:109
void stopAnalysisLimitTimer(bool limitTimerSet)
Definition SVFUtil.cpp:302
bool isHeapAllocExtFunViaRet(const FunObjVar *fun)
Return true if the call is a heap allocator/reallocator.
Definition SVFUtil.h:279
std::string pasMsg(const std::string &msg)
Print each pass/phase message by converting a string into blue string output.
Definition SVFUtil.cpp:105
bool startAnalysisLimitTimer(unsigned timeLimit)
Definition SVFUtil.cpp:281
void writeWrnMsg(const std::string &msg)
Writes a message run through wrnMsg.
Definition SVFUtil.cpp:72
std::ostream & outs()
Overwrite llvm::outs()
Definition SVFUtil.h:52
for isBitcode
Definition BasicTypes.h:70
std::stack< NodeID > NodeStack
Definition GeneralType.h:92
Set< NodeID > NodeSet
Definition GeneralType.h:87
u32_t NodeID
Definition GeneralType.h:76
s64_t APOffset
Definition GeneralType.h:80
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
Set< NodePair > NodePairSet
Definition GeneralType.h:88