Code Listener  [unstable] git snapshot
pointsto.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Pavel Raiskup <pavel@raiskup.cz>
3  *
4  * This file is part of predator.
5  *
6  * predator is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * any later version.
10  *
11  * predator is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with predator. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef H_GUARD_CL_PT_H
21 #define H_GUARD_CL_PT_H
22 
23 #include "config_cl.h"
24 
25 #include <cl/storage.hh>
26 #include <cl/cl_msg.hh>
27 #include <cl/cldebug.hh>
28 
29 extern int pt_dbg_level;
30 
31 #define PT_DEBUG(level, ...) do { \
32  if ((level) <= pt_dbg_level) \
33  CL_DEBUG("PT: " << __VA_ARGS__); \
34 } while (0)
35 
36 // this does not force invocation of gcc error
37 #define PT_ERROR(...) PT_DEBUG(0, "ERROR: " << __VA_ARGS__)
38 
39 namespace CodeStorage {
40 namespace PointsTo {
41 
42  typedef std::pair<Node*, Node*> TNodePair;
43  typedef std::vector<TNodePair> TNodeJoinTodo;
44 
45 // TODO: incorporate this in parameter parsing to allow easily turn some of the
46 // FICS phases off
47 #define FICS_PHASE_1 0x01
48 #define FICS_PHASE_2 0x02
49 #define FICS_PHASE_3 0x04
50 
51  // structure used for keeping building context among functions
52  class BuildCtx {
53  public:
57 
58  struct plot {
59  // set this variable when you want to plot all points-to graphs
60  // when some of them is changed. Content of this variable will
61  // be used as a base-name and extended by unique extension for
62  // each graph.
63  const char *progress;
64  } plot;
65 
66  // debugging-only info
67  struct debug {
68  // which phases are going to be processed (all by default)
69  int phases;
70  } debug;
71 
72  BuildCtx(Storage &stor_) :
73  stor(stor_),
74  ptg(NULL)
75  {
76  plot.progress = NULL; // disable by default
78  }
79  };
80 
81  // Methods called by name ending with 'S' character are single output
82  // methods (there is at most one output edge per node). This shape of graph
83  // is useful especially for FICS algorithm. Note that other algorithms
84  // (like Andersen's) can have more than one output edge per node.
85 
86  /**
87  * Join two nodes: nodeA = nodeA JOIN nodeB
88  *
89  * This must always KEEP nodeA on the same place as-is (it may be referenced
90  * by others) but nodeB is going to be deleted completely (there must be
91  * guaranteed that nobody is pointing it before this operation).
92  */
93  void joinNodesS(
94  BuildCtx &ctx,
95  Graph &ptg,
96  Node *nodeA,
97  Node *nodeB);
98 
99  /**
100  * Start the merging of nodes based on ctx.joinTodo information. This
101  * function uses joinNodesS() internally.
102  */
103  void joinFixPointS(
104  BuildCtx &ctx,
105  Graph &ptg);
106 
107  /**
108  * allocate and append one (empty) successor for node if it has not other
109  * output.
110  */
111  Node *preventEndingS(Node *node);
112 
113  /**
114  * Append (even existing) node to other one as a successor. Note that this
115  * just add pair to ctx.joinTodo -- this requires to call joinFixPointS to
116  * do the real joining part.
117  */
118  void appendNodeS(
119  BuildCtx &ctx,
120  Graph &ptg,
121  Node *parent,
122  Node *which);
123 
124  /**
125  * Find or create node of graph based on whole information provided by some
126  * operand. Dereferences, field accesses, etc. are taken into account.
127  *
128  * @param stor reference to the related intermediate code representation
129  * @param ptg reference to the points-to graph being built
130  * @param op an operand to take the information from
131  * @param referenced is set to true when the '&' reference operator was
132  * detected in operand.
133  */
134  Node *nodeAccessS(
135  const CodeStorage::Storage &stor,
136  Graph &ptg,
137  const cl_operand &op,
138  bool *referenced = NULL);
139 
140  /**
141  * Similar to preventEndingS() except that it would fail if the single
142  * output already existed.
143  */
144  Node *appendEmptyS(Node *root);
145 
146  /**
147  * Return non-modifiable output node pointer if the output of 'node' exists.
148  * Return NULL if the given node does not have an output.
149  */
150  const Node *hasOutputS(const Node *node);
151 
152  /**
153  * Return modifiable output node pointer if the output of 'node' exists.
154  * Return NULL if the given node does not have an output.
155  */
156  Node *getOutputS(Node *node);
157 
158  /**
159  * go 'steps'-times downwards in node's graph. Pre-allocate non-existing
160  * nodes when needed. Note that the cycles are not detected -- when you go
161  * down in a loop no node will be allocated. Return the desired node
162  * pointer.
163  */
164  Node *goDownS(Node *start, int steps);
165 
166  /**
167  * This is _blind_ function -- it does exactly what we want from it. Even
168  * if the given item 'i' already existed somewhere in the graph it will
169  * bind the item (as a referenced duplicate) into the node 'n'
170  */
171  void bindItem(Graph &ptg, Node *n, const Item *);
172 
173  /**
174  * bindVarList is more sophisticated function than 'bindVar'. Before it
175  * assigns some variable item to the node it checks whether this item does
176  * not already exist somewhere else in target graph. If yes, it performs
177  * joining (joinFixPointS()) with the concurrent node.
178  */
179  bool bindVarList(
180  BuildCtx &ctx,
181  Graph &ptg,
182  Node *target,
183  const TItemList &nl);
184 
185  /**
186  * return true if some variable (lhs) follows another one (rhs)
187  */
188  bool follows(const Graph &ptg, const Var *varA, const Var *varB);
189  bool followsGlobal(
190  const CodeStorage::Storage &stor,
191  const Var *lVar,
192  const Var *rVar);
193 
194  /**
195  * return true if given variable 'v' is pointed in given graph 'ptg'
196  */
197  bool isPointed(const Graph *ptg, const Var *v);
198 
199  /**
200  * return true if the given variable 'v' is pointed in any points-to graph
201  */
202  bool isPointedGlob(const CodeStorage::Storage &stor, const Var *v);
203 
204  /**
205  * find (or _create_ if doesn't exist!) node for given variable
206  */
207  Node *getNode(Graph &ptg, const Var *v);
208  Node *getNode(Graph &ptg, const cl_operand &op);
209  Node *getNode(Graph &ptg, const Item *i);
210 
211  /**
212  * find or create node based on item from foreign graph
213  */
214  Node *nodeFromForeign(Graph &ptg, const Item *i);
215 
216  /**
217  * allocate new node and bind i with this new node
218  */
219  Node *allocNodeForItem(Graph &, const Item *i);
220 
221  /**
222  * return the node pointer according to passed 'uid' of variable or
223  * function.
224  */
225  const Node *existsUid(const Graph &graph, int uid);
226 
227  /**
228  * return pointer to node with given variable 'v'
229  */
230  const Node *existsVar(const Graph &graph, const Var *v);
231 
232  const Node *existsItem(const Graph &graph, const Item *i);
233 
234 
235  /**
236  * return pointer to (modifiable) node object according to given variable or
237  * node item pointer. Return NULL when the node doesn't exist.
238  */
239  Node *findNode(Graph &, int);
240  Node *findNode(Graph &, const Var *);
241  Node *findNode(Graph &, const Item *);
242 
243  /**
244  * Setup the given node to be black-hole -- self-pointed node that eats each
245  * other note that is set as its successor.
246  */
247  void setBlackHole(Graph &, Node *);
248 
249  /**
250  * Interconnect two given nodes with edge
251  */
252  void addEdge(Node *from, Node *to);
253 
254  /**
255  * return true when some problem occurs
256  */
257  bool existsError(const Storage &stor);
258 } /* namespace PointsTo */
259 
260 void pointsToAnalyse(Storage &stor, const std::string &conf);
261 
262 } /* namespace CodeStorage */
263 
264 #endif /* H_GUARD_CL_PT_H */