SVF
OfflineConsG.cpp
Go to the documentation of this file.
1 //===- OfflineConsG.cpp -- Offline constraint graph -----------------------------//
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 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 General Public License for more details.
17 
18 // You should have received a copy of the GNU General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * OfflineConsG.cpp
25  *
26  * Created on: Oct 28, 2018
27  * Author: Yuxiang Lei
28  */
29 
30 #include "Util/Options.h"
31 #include "Graphs/OfflineConsG.h"
32 
33 using namespace SVF;
34 using namespace SVFUtil;
35 
40 {
41  LoadEdges loads;
42  StoreEdges stores;
43 
44  // Add a copy edge between the ref node of src node and dst node
45  for (ConstraintEdge::ConstraintEdgeSetTy::iterator it = LoadCGEdgeSet.begin(), eit =
46  LoadCGEdgeSet.end(); it != eit; ++it)
47  {
49  loads.insert(load);
50  NodeID src = load->getSrcID();
51  NodeID dst = load->getDstID();
52  addRefLoadEdge(src, dst);
53  }
54  // Add a copy edge between src node and the ref node of dst node
55  for (ConstraintEdge::ConstraintEdgeSetTy::iterator it = StoreCGEdgeSet.begin(), eit =
56  StoreCGEdgeSet.end(); it != eit; ++it)
57  {
59  stores.insert(store);
60  NodeID src = store->getSrcID();
61  NodeID dst = store->getDstID();
62  addRefStoreEdge(src, dst);
63  }
64 
65  // Dump offline graph with all edges
66  dump("oCG_initial");
67 
68  // Remove load and store edges in offline constraint graph
69  for (LoadEdges::iterator it = loads.begin(), eit = loads.end(); it != eit; ++it)
70  {
71  removeLoadEdge(*it);
72  }
73  for (StoreEdges::iterator it = stores.begin(), eit = stores.end(); it != eit; ++it)
74  {
75  removeStoreEdge(*it);
76  }
77 
78  // Dump offline graph with removed load and store edges
79  dump("oCG_final");
80 }
81 
87 {
88  createRefNode(src);
89  NodeID ref = nodeToRefMap[src];
90  return addCopyCGEdge(ref, dst);
91 }
92 
98 {
99  createRefNode(dst);
100  NodeID ref = nodeToRefMap[dst];
101  return addCopyCGEdge(src, ref);
102 }
103 
108 {
109  if (hasRef(nodeId))
110  return false;
111 
112  NodeID refId = pag->addDummyValNode();
113  ConstraintNode* node = new ConstraintNode(refId);
114  addConstraintNode(node, refId);
115  refNodes.insert(refId);
116  nodeToRefMap[nodeId] = refId;
117  return true;
118 }
119 
125 {
126  // Build offline nodeToRepMap
127  buildOfflineMap(oscc);
128 }
129 
134 {
135  for (NodeToRepMap::const_iterator it = nodeToRefMap.begin(); it != nodeToRefMap.end(); ++it)
136  {
137  NodeID node = it->first;
138  NodeID ref = getRef(node);
139  NodeID rep = solveRep(oscc,oscc->repNode(ref));
140  if (!isaRef(rep) && !isaRef(node))
141  setNorRep(node, rep);
142  }
143 }
144 
150 {
151  if (isaRef(rep))
152  {
153  NodeBS subNodes = oscc->subNodes(rep);
154  for (NodeBS::iterator subIt = subNodes.begin(), subEit = subNodes.end(); subIt != subEit; ++subIt)
155  {
156  if (isaRef(*subIt))
157  {
158  rep = *subIt;
159  break;
160  }
161  }
162  }
163  return rep;
164 }
165 
169 void OfflineConsG::dump(std::string name)
170 {
172  GraphPrinter::WriteGraphToFile(outs(), name, this);
173 }
174 
175 
176 
177 // --- GraphTraits specialization for offline constraint graph ---
178 
179 namespace llvm
180 {
181 template<>
182 struct DOTGraphTraits<OfflineConsG*> : public DOTGraphTraits<PAG*>
183 {
184 
186  DOTGraphTraits(bool isSimple = false) :
187  DOTGraphTraits<PAG*>(isSimple)
188  {
189  }
190 
192  static std::string getGraphName(OfflineConsG*)
193  {
194  return "Offline Constraint Graph";
195  }
196 
199  static std::string getNodeLabel(NodeType *n, OfflineConsG*)
200  {
201  std::string str;
202  raw_string_ostream rawstr(str);
203  if (PAG::getPAG()->findPAGNode(n->getId()))
204  {
205  PAGNode *node = PAG::getPAG()->getPAGNode(n->getId());
206  bool briefDisplay = true;
207  bool nameDisplay = true;
208 
209 
210  if (briefDisplay)
211  {
212  if (SVFUtil::isa<ValPN>(node))
213  {
214  if (nameDisplay)
215  rawstr << node->getId() << ":" << node->getValueName();
216  else
217  rawstr << node->getId();
218  }
219  else
220  rawstr << node->getId();
221  }
222  else
223  {
224  // print the whole value
225  if (!SVFUtil::isa<DummyValPN>(node) && !SVFUtil::isa<DummyObjPN>(node))
226  rawstr << *node->getValue();
227  else
228  rawstr << "";
229 
230  }
231 
232  return rawstr.str();
233  }
234  else
235  {
236  rawstr<< n->getId();
237  return rawstr.str();
238  }
239  }
240 
241  static std::string getNodeAttributes(NodeType *n, OfflineConsG*)
242  {
243  if (PAG::getPAG()->findPAGNode(n->getId()))
244  {
245  PAGNode *node = PAG::getPAG()->getPAGNode(n->getId());
246  return node->getNodeAttrForDotDisplay();
247  }
248  else
249  {
250  return "shape=folder";
251  }
252  }
253 
254  template<class EdgeIter>
255  static std::string getEdgeAttributes(NodeType*, EdgeIter EI, OfflineConsG*)
256  {
257  ConstraintEdge* edge = *(EI.getCurrent());
258  assert(edge && "No edge found!!");
259  if (edge->getEdgeKind() == ConstraintEdge::Addr)
260  {
261  return "color=green";
262  }
263  else if (edge->getEdgeKind() == ConstraintEdge::Copy)
264  {
265  return "color=black";
266  }
267  else if (edge->getEdgeKind() == ConstraintEdge::NormalGep
269  {
270  return "color=purple";
271  }
272  else if (edge->getEdgeKind() == ConstraintEdge::Store)
273  {
274  return "color=blue";
275  }
276  else if (edge->getEdgeKind() == ConstraintEdge::Load)
277  {
278  return "color=red";
279  }
280  else
281  {
282  assert(0 && "No such kind edge!!");
283  }
284  return "";
285  }
286 
287  template<class EdgeIter>
288  static std::string getEdgeSourceLabel(NodeType*, EdgeIter)
289  {
290  return "";
291  }
292 };
293 } // End namespace llvm
GEdgeKind getEdgeKind() const
Definition: GenericGraph.h:81
Definition: ConsG.h:385
const NodeBS & subNodes(NodeID n) const
get all subnodes in one scc, if size is empty insert itself into the set
Definition: SCC.h:173
NodeID getDstID() const
Definition: GenericGraph.h:77
u32_t NodeID
Definition: SVFBasicTypes.h:80
#define assert(ex)
Definition: util.h:141
bool addRefLoadEdge(NodeID src, NodeID dst)
NodeID getSrcID() const
get methods of the components
Definition: GenericGraph.h:73
static const llvm::cl::opt< bool > OCGDotGraph
Definition: Options.h:63
void solveOfflineSCC(OSCC *oscc)
static std::string getEdgeAttributes(NodeType *, EdgeIter EI, OfflineConsG *)
Definition: PAG.h:47
const Value * getValue() const
Get/has methods of the components.
Definition: PAGNode.h:93
virtual const std::string getValueName() const =0
Get name of the LLVM value.
static std::string getNodeLabel(NodeType *n, OfflineConsG *)
static PAG * getPAG(bool buildFromFile=false)
Singleton design here to make sure we only have one instance during any analysis. ...
Definition: PAG.h:160
Set< StoreCGEdge * > StoreEdges
Definition: OfflineConsG.h:50
NodeID repNode(NodeID n) const
get the rep node if not found return itself
Definition: SCC.h:139
PAGNode * getPAGNode(NodeID id) const
Get PAGNode ID.
Definition: PAG.h:513
llvm::raw_string_ostream raw_string_ostream
Definition: BasicTypes.h:100
bool addRefStoreEdge(NodeID src, NodeID dst)
bool createRefNode(NodeID nodeId)
raw_ostream & outs()
Overwrite llvm::outs()
Definition: SVFUtil.h:47
Set< LoadCGEdge * > LoadEdges
Definition: OfflineConsG.h:49
void buildOfflineMap(OSCC *oscc)
static std::string getNodeAttributes(NodeType *n, OfflineConsG *)
NodeID solveRep(OSCC *oscc, NodeID rep)
void dump(std::string name)
static std::string getEdgeSourceLabel(NodeType *, EdgeIter)
for isBitcode
Definition: ContextDDA.h:15
NodeID getId() const
Get ID.
Definition: GenericGraph.h:164
llvm::SparseBitVector NodeBS
Definition: SVFBasicTypes.h:87
static std::string getGraphName(OfflineConsG *)
Return name of the graph.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:343
virtual const std::string getNodeAttrForDotDisplay() const
Get shape and/or color of node for .dot display.
Definition: PAG.cpp:54
static void WriteGraphToFile(llvm::raw_ostream &O, const std::string &GraphName, const GraphType &GT, bool simple=false)
Definition: GraphPrinter.h:56