Otawa  0.10
ai.h
Go to the documentation of this file.
1 /*
2  * ai module interface
3  *
4  * This file is part of OTAWA
5  * Copyright (c) 2014, IRIT UPS.
6  *
7  * OTAWA is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * OTAWA is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with OTAWA; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  */
22 #ifndef OTAWA_DFA_AI_H_
23 #define OTAWA_DFA_AI_H_
24 
25 #include <elm/genstruct/Vector.h>
26 #include <elm/util/Pair.h>
27 #include <elm/util/BitVector.h>
28 #include <elm/PreIterator.h>
29 #include <otawa/cfg.h>
30 
31 namespace otawa { namespace ai {
32 
33 using namespace elm;
34 using namespace elm::genstruct;
35 
42 template <class D, class G, class S>
43 class WorkListDriver: public PreIterator<WorkListDriver<D, G, S>, typename G::vertex_t > {
44 public:
45  typedef typename G::vertex_t vertex_t;
46 
53  WorkListDriver(D& dom, const G& graph, S& store)
54  : _dom(dom), _graph(graph), _store(store), wl_set(graph.count()), end(false) {
55  store.set(_graph.entry(), dom.init());
56  for(typename G::Successor succ(graph, _graph.entry()); succ; succ++)
57  push(graph.sinkOf(*succ));
58  next();
59  }
60 
65  inline bool ended(void) {
66  return end;
67  }
68 
72  inline void next(void) {
73  while(!wl_vertices.isEmpty()) {
74  cur = pop();
75  if(cur != _graph.exit())
76  return;
77  }
78  end = true;
79  }
80 
85  inline typename G::vertex_t item(void) {
86  return cur;
87  }
88 
93  inline void change(void) {
94  for(typename G::Successor succ(_graph, cur); succ; succ++)
95  push(*succ);
96  }
97 
101  inline void change(typename D::t s) {
102  _store.set(cur, s);
103  change();
104  }
105 
110  inline void change(typename G::edge_t edge) {
111  push(_graph.sinkOf(edge));
112  }
113 
117  inline void change(typename G::edge_t edge, typename D::t s) {
118  _store.set(edge, s);
119  change(edge);
120  }
121 
125  inline void changeAll(void) {
126 
127  // collect vertices
128  wl_vertices.clear();
130  todo.push(_graph.entry());
131  while(todo) {
132  vertex_t v = todo.pop();
133  for(typename G::Successor s(_graph, v); s; s++)
134  if(!contains(_graph.sinkOf(s))) {
135  push(_graph.sinkOf(s));
136  todo.push(_graph.sinkOf(s));
137  }
138  }
139 
140  // reverse the order
141  for(int i = 0, j = wl_vertices.length() - 1; i < j; i++, j--) {
142  vertex_t tmp = wl_vertices[i];
143  wl_vertices[i] = wl_vertices[j];
144  wl_vertices[j] = tmp;
145  }
146 
147  // and start...
148  next();
149  }
150 
154  inline void check(typename G::edge_t edge, typename D::t s) {
155  typename D::t ps = _store.get(edge);
156  if(!_dom.equals(s, ps))
157  change(edge, s);
158  }
159 
163  inline typename D::t input(void) {
164  return input(cur);
165  }
166 
172  inline typename D::t input(vertex_t vertex) {
173  typename D::t s = _dom.bot();
174  for(typename G::Predecessor pred(_graph, vertex); pred; pred++) {
175  s = _dom.join(s, _store.get(*pred));
176  }
177  return s;
178  }
179 
180 private:
181 
182  inline void push(typename G::vertex_t v) {
183  if(!wl_set.bit(_graph.index(v))) {
184  wl_vertices.push(v);
185  wl_set.set(_graph.index(v));
186  }
187  }
188 
189  inline typename G::vertex_t pop(void) {
190  typename G::vertex_t v = wl_vertices.pop();
191  wl_set.clear(_graph.index(v));
192  return v;
193  }
194 
195  inline bool contains(vertex_t v) {
196  return wl_set.bit(_graph.index(v));
197  }
198 
199  D& _dom;
200  const G& _graph;
201  S& _store;
204  typename G::vertex_t cur;
205  bool end;
206 };
207 
208 
212 class CFGGraph {
213 public:
214  inline CFGGraph(CFG *cfg): _cfg(cfg) { }
215 
216  // BiDiGraph concept
218  typedef Edge *edge_t;
219 
220  inline vertex_t entry(void) const { return _cfg->entry(); }
221  inline vertex_t exit(void) const { return _cfg->exit(); }
222  inline vertex_t sinkOf(edge_t e) const { return e->target(); }
223  inline vertex_t sourceOf(edge_t e) const { return e->source(); }
224 
226  public:
227  inline Predecessor(const CFGGraph& graph, vertex_t v): BasicBlock::InIterator(v) { }
228  inline Predecessor(const Predecessor& p): BasicBlock::InIterator(p) { }
229  };
230 
232  public:
233  inline Successor(const CFGGraph& graph, vertex_t v): BasicBlock::OutIterator(v) { }
234  inline Successor(const Successor& p): BasicBlock::OutIterator(p) { }
235  };
236 
237  class Iterator: public CFG::BBIterator {
238  public:
239  inline Iterator(const CFGGraph& g): CFG::BBIterator(g._cfg) { }
240  inline Iterator(const Iterator& i): CFG::BBIterator(i) { }
241  };
242 
243  // Indexed concept
244  inline int index(vertex_t v) const { return v->number(); }
245  inline int count(void) const { return _cfg->countBB(); }
246 
247 private:
249 };
250 
251 
257 template <class D, class G>
258 class ArrayStore {
259 public:
260  typedef typename D::t t;
261  typedef typename G::vertex_t vertex_t;
262  typedef typename G::edge_t edge_t;
263 
264  ArrayStore(D& dom, G& graph): _dom(dom), _graph(graph), map(new typename D::t[_graph.count()]) {
265  for(int i = 0; i < graph.count(); i++)
266  map[i] = dom.bot();
267  }
268 
269  inline void set(vertex_t v, t s) { map[_graph.index(v)] = s; }
270 
271  void set(edge_t e, t s) {
272  int i = _graph.index(_graph.sourceOf(e));
273  map[i] = _dom.join(map[i], s);
274  }
275 
276  inline t get(vertex_t v) const { return map[_graph.index(v)]; }
277 
278  inline t get(edge_t e) const { return map[_graph.index(_graph.sourceOf(e))]; }
279 
280 private:
281  D& _dom;
282  G& _graph;
283  typename D::t *map;
284 };
285 
286 
290 template <class D, class G>
291 class EdgeStore {
292 public:
293  typedef typename D::t t;
294  typedef typename G::vertex_t vertex_t;
295  typedef typename G::edge_t edge_t;
296 
297  EdgeStore(D& dom, G& graph): _dom(dom), _graph(graph) {
298  for(typename G::Successor e(_graph, _graph.entry()); e; e++)
299  map.put(*e, _dom.init());
300  }
301 
302  void set(vertex_t v, t s) {
303  for(typename G::Successor e(_graph, v); e; e++)
304  map.put(*e, s);
305  }
306 
307  inline void set(edge_t e, t s) { map.put(e, s); }
308 
309  t get(vertex_t v) const {
310  t s = _dom.bot();
311  for(typename G::Successor e(_graph, v); e; e++)
312  s = _dom.join(s, map.get(e, _dom.bot()));
313  return s;
314  }
315 
316  inline t get(edge_t e) { return map.get(e, _dom.bot()); }
317 
318 private:
319  D& _dom;
320  G& _graph;
322 };
323 
324 } } // ai
325 
326 #endif /* OTAWA_DFA_AI_H_ */
HashTable< edge_t, t > map
Definition: ai.h:321
Definition: CFG.h:48
D & _dom
Definition: ai.h:319
dtd::Element edge(dtd::make("edge", _EDGE).attr(source).attr(target).attr(called))
void change(typename G::edge_t edge, typename D::t s)
Change the output value of the current vertex for the given edge.
Definition: ai.h:117
BasicBlock * source(void) const
Definition: Edge.h:52
D::t input(void)
Compute the input state.
Definition: ai.h:163
G & _graph
Definition: ai.h:282
ArrayStore(D &dom, G &graph)
Definition: ai.h:264
Iterator(const CFGGraph &g)
Definition: ai.h:239
G::vertex_t vertex_t
Definition: ai.h:45
const int end
Definition: Registration.h:42
Edge * edge_t
Definition: ai.h:218
S & _store
Definition: ai.h:201
Predecessor(const Predecessor &p)
Definition: ai.h:228
G::vertex_t cur
Definition: ai.h:204
Definition: ai.h:237
D::t t
Definition: ai.h:260
G::vertex_t vertex_t
Definition: ai.h:294
G::edge_t edge_t
Definition: ai.h:295
G::vertex_t item(void)
Get the current vertex.
Definition: ai.h:85
BiDiGraph implementation for CFG.
Definition: ai.h:212
D::t input(vertex_t vertex)
Compute the input state for the given vertex.
Definition: ai.h:172
Successor(const CFGGraph &graph, vertex_t v)
Definition: ai.h:233
D::t t
Definition: ai.h:293
Vector< typename G::vertex_t > wl_vertices
Definition: ai.h:202
Control Flow Graph representation.
Definition: CFG.h:42
bool end
Definition: ai.h:205
Predecessor(const CFGGraph &graph, vertex_t v)
Definition: ai.h:227
CFGGraph(CFG *cfg)
Definition: ai.h:214
vertex_t sourceOf(edge_t e) const
Definition: ai.h:223
Driver of abstract interpretation with a simple to-do list.
Definition: ai.h:43
void set(vertex_t v, t s)
Definition: ai.h:302
Successor(const Successor &p)
Definition: ai.h:234
CFG * _cfg
Definition: ai.h:248
void set(edge_t e, t s)
Definition: ai.h:271
BasicBlock * vertex_t
Definition: ai.h:217
G & _graph
Definition: ai.h:320
G::vertex_t vertex_t
Definition: ai.h:261
void changeAll(void)
Consider that all has been changed causing a re-computation of all.
Definition: ai.h:125
Definition: BasicBlock.h:165
int number(void) const
Get the number hooked on this basic block, that is, value of ID_Index property.
Definition: BasicBlock.h:146
vertex_t exit(void) const
Definition: ai.h:221
int index(vertex_t v) const
Definition: ai.h:244
Definition: ai.h:231
Definition: BasicBlock.h:160
void set(edge_t e, t s)
Definition: ai.h:307
vertex_t sinkOf(edge_t e) const
Definition: ai.h:222
This class represents edges in the CFG representation.
Definition: Edge.h:33
dtd::Element cfg(dtd::make("cfg", _CFG).attr(id).content((entry,*bb, exit,*edge)))
void push(typename G::vertex_t v)
Definition: ai.h:182
void push(const T &value)
BasicBlock * target(void) const
Definition: Edge.h:53
BitVector wl_set
Definition: ai.h:203
State storage on the edges.
Definition: ai.h:291
void set(vertex_t v, t s)
Definition: ai.h:269
int count(void) const
Definition: ai.h:245
This is the minimal definition of a basic block.
Definition: BasicBlock.h:43
bool contains(vertex_t v)
Definition: ai.h:195
bool ended(void)
Test if the traversal is ended.
Definition: ai.h:65
void change(void)
Called when the output state of the current vertex is changed (and successors must be updated)...
Definition: ai.h:93
WorkListDriver(D &dom, const G &graph, S &store)
Initialize the driver.
Definition: ai.h:53
G::vertex_t pop(void)
Definition: ai.h:189
G::edge_t edge_t
Definition: ai.h:262
Iterator(const Iterator &i)
Definition: ai.h:240
void change(typename D::t s)
Set the new output state of the current vertex.
Definition: ai.h:101
void check(typename G::edge_t edge, typename D::t s)
If there is a state change for the given edge.
Definition: ai.h:154
D::t * map
Definition: ai.h:283
D & _dom
Definition: ai.h:281
void change(typename G::edge_t edge)
Called when the output state of the current vertex for the given edge is changed (and successors must...
Definition: ai.h:110
D & _dom
Definition: ai.h:199
Stockage of output values as an array.
Definition: ai.h:258
vertex_t entry(void) const
Definition: ai.h:220
EdgeStore(D &dom, G &graph)
Definition: ai.h:297
void next(void)
Go to the next vertex to process.
Definition: ai.h:72
const G & _graph
Definition: ai.h:200
inst store(int d, int a, int t)
Definition: inst.h:155