Static Value-Flow Analysis
Loading...
Searching...
No Matches
WPAFSSolver.h
Go to the documentation of this file.
1//===- WPAFSSolver.h -- WPA flow-sensitive solver-----------------------------//
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 * @file: WPAFSSolver.h
25 * @author: yesen
26 * @date: 14/02/2014
27 * @version: 1.0
28 *
29 * @section LICENSE
30 *
31 * @section DESCRIPTION
32 *
33 */
34
35
36#ifndef WPAFSSOLVER_H_
37#define WPAFSSOLVER_H_
38
39#include "WPA/WPASolver.h"
40#include "Util/GeneralType.h"
41
42namespace SVF
43{
44
48template<class GraphType>
49class WPAFSSolver : public WPASolver<GraphType>
50{
51public:
56 virtual ~WPAFSSolver() {}
57
59 virtual inline NodeID sccRepNode(NodeID id) const
60 {
61 return id;
62 }
63
64protected:
66
69 {
71 this->getSCCDetector()->find();
72
73 assert(nodeStack.empty() && "node stack is not empty, some nodes are not popped properly.");
74
77 FIFOWorkList<NodeID> revTopoStack = this->getSCCDetector()->revTopoNodeStack();
78 while (!revTopoStack.empty())
79 {
80 NodeID nodeId = revTopoStack.front();
81 revTopoStack.pop();
82 const NodeBS& subNodes = this->getSCCDetector()->subNodes(nodeId);
83 for (NodeBS::iterator it = subNodes.begin(), eit = subNodes.end(); it != eit; ++it)
84 {
86 nodeStack.push(*it);
87 }
88 }
89
90 return nodeStack;
91 }
92};
93
94
95
99template<class GraphType>
100class WPASCCSolver : public WPAFSSolver<GraphType>
101{
102public:
106
108
109 virtual ~WPASCCSolver() {}
110
111protected:
112 virtual void solve()
113 {
116 while (!this->isWorklistEmpty())
117 this->popFromWorklist();
118
119 NodeStack& nodeStack = this->SCCDetect();
120
121 while (!nodeStack.empty())
122 {
123 NodeID rep = nodeStack.top();
124 nodeStack.pop();
125
126 setCurrentSCC(rep);
127
128 const NodeBS& sccNodes = this->getSCCDetector()->subNodes(rep);
129 for (NodeBS::iterator it = sccNodes.begin(), eit = sccNodes.end(); it != eit; ++it)
130 this->pushIntoWorklist(*it);
131
132 while (!this->isWorklistEmpty())
133 this->processNode(this->popFromWorklist());
134 }
135 }
136
138 virtual void propagate(GNODE* v)
139 {
140 child_iterator EI = GTraits::direct_child_begin(v);
141 child_iterator EE = GTraits::direct_child_end(v);
142 for (; EI != EE; ++EI)
143 {
144 if (this->propFromSrcToDst(*(EI.getCurrent())))
146 }
147 }
148
149 virtual inline void addNodeIntoWorkList(NodeID node)
150 {
151 if (isInCurrentSCC(node))
152 this->pushIntoWorklist(node);
153 }
154
155 inline bool isInCurrentSCC(NodeID node)
156 {
157 return (const_cast<NodeBS&>(this->getSCCDetector()->subNodes(curSCCID))).test(node);
158 }
159 inline void setCurrentSCC(NodeID id)
160 {
161 curSCCID = this->getSCCDetector()->repNode(id);
162 }
163
165};
166
167
168
172template<class GraphType>
173class WPAMinimumSolver : public WPASCCSolver<GraphType>
174{
175public:
179
181
182 virtual ~WPAMinimumSolver() {}
183
184protected:
185 virtual void solve()
186 {
187 bool solveAll = true;
190 if (!this->isWorklistEmpty())
191 {
192 solveAll = false;
193 while (!this->isWorklistEmpty())
195 }
196
197 NodeStack& nodeStack = this->SCCDetect();
198
199 while (!nodeStack.empty())
200 {
201 NodeID rep = nodeStack.top();
202 nodeStack.pop();
203
204 this->setCurrentSCC(rep);
205
206 NodeBS sccNodes = this->getSCCDetector()->subNodes(rep);
207 if (solveAll == false)
209
210 for (NodeBS::iterator it = sccNodes.begin(), eit = sccNodes.end(); it != eit; ++it)
211 this->pushIntoWorklist(*it);
212
213 while (!this->isWorklistEmpty())
214 this->processNode(this->popFromWorklist());
215
216 removeCandidates(sccNodes);
217 }
218 }
219
220 virtual inline void addNodeIntoWorkList(NodeID node)
221 {
222 if (this->isInCurrentSCC(node))
223 this->pushIntoWorklist(node);
224 else
225 addNewCandidate(node);
226 }
227
228private:
229 inline void addNewCandidate(NodeID node)
230 {
231 candidates.set(node);
232 }
233 inline const NodeBS& getCandidates() const
234 {
235 return candidates;
236 }
241
243};
244
245} // End namespace SVF
246
247#endif /* WPAFSSOLVER_H_ */
bool empty() const
Definition WorkList.h:161
void set(unsigned Idx)
bool intersectWithComplement(const SparseBitVector &RHS)
iterator begin() const
virtual NodeID sccRepNode(NodeID id) const
SCC methods.
Definition WPAFSSolver.h:59
NodeStack nodeStack
stack used for processing nodes.
Definition WPAFSSolver.h:65
WPAFSSolver()
Constructor.
Definition WPAFSSolver.h:53
virtual NodeStack & SCCDetect()
SCC detection.
Definition WPAFSSolver.h:68
virtual ~WPAFSSolver()
Destructor.
Definition WPAFSSolver.h:56
const NodeBS & getCandidates() const
NodeBS candidates
nodes which need to be analyzed in current iteration.
WPASolver< GraphType >::GTraits GTraits
void addNewCandidate(NodeID node)
void removeCandidates(const NodeBS &nodes)
virtual ~WPAMinimumSolver()
WPASolver< GraphType >::child_iterator child_iterator
WPASolver< GraphType >::GNODE GNODE
virtual void addNodeIntoWorkList(NodeID node)
virtual void solve()
WPASolver< GraphType >::GTraits GTraits
NodeID curSCCID
index of current SCC.
void setCurrentSCC(NodeID id)
virtual void addNodeIntoWorkList(NodeID node)
WPASolver< GraphType >::GNODE GNODE
virtual ~WPASCCSolver()
WPASolver< GraphType >::child_iterator child_iterator
virtual void solve()
bool isInCurrentSCC(NodeID node)
virtual void propagate(GNODE *v)
Propagation for the solving, to be implemented in the child class.
NodeID Node_Index(GNODE node)
Get node ID.
Definition WPASolver.h:184
NodeID popFromWorklist()
Worklist operations.
Definition WPASolver.h:152
GTraits::NodeRef GNODE
Definition WPASolver.h:50
SCC * getSCCDetector() const
Get SCC detector.
Definition WPASolver.h:68
virtual void pushIntoWorklist(NodeID id)
Definition WPASolver.h:157
GTraits::ChildIteratorType child_iterator
Definition WPASolver.h:52
virtual bool propFromSrcToDst(GEDGE *)
Propagate information from source to destination node, to be implemented in the child class.
Definition WPASolver.h:139
bool isWorklistEmpty()
Definition WPASolver.h:161
virtual void processNode(NodeID)
Following methods are to be implemented in child class, in order to achieve a fully worked PTA.
Definition WPASolver.h:123
for isBitcode
Definition BasicTypes.h:70
std::stack< NodeID > NodeStack
Definition GeneralType.h:92
u32_t NodeID
Definition GeneralType.h:76
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
iter_range< typename GenericGraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)