Otawa  0.10
AbsIntLite.h
Go to the documentation of this file.
1 /*
2  * $Id$
3  * AbsIntLite class interface
4  *
5  * This file is part of OTAWA
6  * Copyright (c) 2010, IRIT UPS.
7  *
8  * OTAWA 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 2 of the License, or
11  * (at your option) any later version.
12  *
13  * OTAWA 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 OTAWA; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 #ifndef OTAWA_DFA_ABSINTLITE_H_
23 #define OTAWA_DFA_ABSINTLITE_H_
24 
25 #include <elm/genstruct/VectorQueue.h>
26 #include <elm/util/BitVector.h>
27 
28 namespace otawa { namespace dfa {
29 
30 #ifdef OTAWA_AIL_DEBUG
31 # define OTAWA_AILD(x) x
32 #else
33 # define OTAWA_AILD(x)
34 #endif
35 
36 // AbsIntLiteEx class
37 template <class G, class T>
38 class AbsIntLiteEx {
39 public:
40 
41  inline AbsIntLiteEx(const G& graph, T& domain): g(graph), d(domain), set(g.count()) {
42  vals = new typename T::t[g.count()];
43  }
44 
45  inline void push(typename G::Vertex v) {
46  if(!set.bit(g.index(v))) {
47  set.set(g.index(v));
48  todo.put(v);
49  }
50  }
51 
52  inline typename G::Vertex pop(void) {
53  typename G::Vertex v = todo.get();
54  set.clear(g.index(v));
55  return v;
56  }
57 
58  inline void process(void) {
59 
60  // set all values to bottom
61  for(int i = 0; i < g.count(); i++)
62  d.set(vals[i], d.bottom());
63 
64  // initialization
65  d.set(vals[g.index(g.entry())], d.initial());
66  OTAWA_AILD(cerr << "INITIAL: " << g.entry() << ": "; d.dump(cerr, vals[g.index(g.entry())]); cerr << io::endl);
67 
68  // first step
69  /*for(typename G::Iterator v(g); v; v++)
70  if(v != g.entry())
71  step(v);*/
72  for(typename G::Successor succ(g, g.entry()); succ; succ++)
73  push(g.sinkOf(*succ));
74 
75  // loop until fixpoint
76  OTAWA_AILD(cerr << "\nINTERPRETING\n");
77 
78  while(todo) {
79  typename G::Vertex v = pop();
80  OTAWA_AILD(cerr << "NEXT: " << v << io::endl);
81  step(v);
82  }
83  }
84 
85  inline void step(typename G::Vertex v) {
86  OTAWA_AILD(cerr << "processing " << v << io::endl);
87 
88  // join of predecessor
89  in(v);
90  OTAWA_AILD(cerr << " - JOIN IN: "; d.dump(cerr, tmp); cerr << io::endl);
91 
92  // update value
93  d.update(v, tmp);
94  OTAWA_AILD(cerr << " - UPDATE: "; d.dump(cerr, tmp); cerr << io::endl);
95 
96  // new value ?
97  if(!d.equals(tmp, vals[g.index(v)])) {
98  OTAWA_AILD(cerr << " - NEW VALUE\n");
99  d.set(vals[g.index(v)], tmp);
100 
101  // add successors
102  for(typename G::Successor succ(g, v); succ; succ++) {
103  push(g.sinkOf(*succ));
104  OTAWA_AILD(cerr << " - PUTTING " << *succ << io::endl);
105  }
106  }
107  }
108 
109  inline const typename T::t& in(typename G::Vertex v) {
110  d.set(tmp, d.bottom());
111  for(typename G::Predecessor pred(g, v); pred; pred++) {
112  d.set(t2, vals[g.index(g.sourceOf(*pred))]);
113  OTAWA_AILD(cerr << " - FILTER " << g.sourceOf(*pred) << "("; d.dump(cerr, t2); cerr << ") = ");
114  d.filter(*pred, t2);
115  OTAWA_AILD(d.dump(cerr, t2); cerr << io::endl);
116  d.join(tmp, t2);
117  OTAWA_AILD(cerr << " - JOIN for in = "; d.dump(cerr, tmp); cerr << io::endl);
118  }
119  if(g.isLoopHeader(v))
120  d.widen(v, tmp);
121  return tmp;
122  }
123 
124  inline const typename T::t& out(typename G::Vertex v) const {
125  return vals[g.index(v)];
126  }
127 
128  class DomainIter: public PreIterator<DomainIter, typename T::t &> {
129  public:
130  inline DomainIter(const AbsIntLiteEx& _ail): ail(_ail), i(-1) { }
131  inline DomainIter(const DomainIter& iter): ail(iter.ail), i(iter.i) { }
132  inline bool ended(void) const { return i >= ail.g.count(); }
133  inline void next(void) { i++; }
134  inline typename T::t& item(void) { if(i == -1) return tmp; else return vals[i]; }
135  private:
137  int i;
138  };
139 
140 private:
141  const G& g;
142  T& d;
143  typename T::t *vals;
144  typename T::t tmp, t2;
147 };
148 
149 
150 // AbsIntLiteExtender class
151 template <class G, class D>
153 public:
154  typedef typename D::t t;
155  inline AbsIntLiteExtender(D& domain): dom(domain) { }
156  inline t initial(void) { return dom.initial(); }
157  inline t bottom(void) { return dom.bottom(); }
158  inline void join(t& d, const t& s) { dom.join(d, s); }
159  inline bool equals(const t& v1, const t& v2) { return dom.equals(v1, v2); }
160  inline void set(t& d, const t& s) { dom.set(d, s); }
161  inline void dump(io::Output& out, const t& v) { dom.dump(out, v); }
162  inline void update(typename G::Vertex v, t &d) { dom.update(v, d); }
163  inline void filter(typename G::Edge e, t &d) { }
164  inline void widen(typename G::Vertex v, t &d) { }
165 private:
166  D& dom;
167 };
168 
169 // AbsIntLite class
170 template <class G, class T>
171 class AbsIntLite: public AbsIntLiteEx<G, AbsIntLiteExtender<G, T> > {
172 public:
173  inline AbsIntLite(const G& graph, T& domain): AbsIntLiteEx<G, AbsIntLiteExtender<G, T> >(graph, e), e(domain) { }
174 private:
176 };
177 
178 } } // otawa::dfa
179 
180 #endif /* OTAWA_DFA_ABSINTLITE_H_ */
AbsIntLiteEx(const G &graph, T &domain)
Definition: AbsIntLite.h:41
const T::t & out(typename G::Vertex v) const
Definition: AbsIntLite.h:124
void dump(io::Output &out, const t &v)
Definition: AbsIntLite.h:161
const T::t & in(typename G::Vertex v)
Definition: AbsIntLite.h:109
G::Vertex pop(void)
Definition: AbsIntLite.h:52
void step(typename G::Vertex v)
Definition: AbsIntLite.h:85
#define OTAWA_AILD(x)
Definition: AbsIntLite.h:33
void widen(typename G::Vertex v, t &d)
Definition: AbsIntLite.h:164
void push(typename G::Vertex v)
Definition: AbsIntLite.h:45
int i
Definition: AbsIntLite.h:137
t initial(void)
Definition: AbsIntLite.h:156
DomainIter(const DomainIter &iter)
Definition: AbsIntLite.h:131
void set(t &d, const t &s)
Definition: AbsIntLite.h:160
bool bit(int index) const
T::t t2
Definition: AbsIntLite.h:144
io::Output cerr
const AbsIntLiteEx & ail
Definition: AbsIntLite.h:136
void join(t &d, const t &s)
Definition: AbsIntLite.h:158
T::t * vals
Definition: AbsIntLite.h:143
T & d
Definition: AbsIntLite.h:142
BitVector set
Definition: AbsIntLite.h:146
AbsIntLiteExtender< G, T > e
Definition: AbsIntLite.h:175
T::t tmp
Definition: AbsIntLite.h:144
Definition: AbsIntLite.h:128
AbsIntLite(const G &graph, T &domain)
Build the analyzer.
Definition: AbsIntLite.h:173
D & dom
Definition: AbsIntLite.h:166
This class provides a light implementation for abstract interpretation.
Definition: AbsIntLite.h:171
void next(void)
Definition: AbsIntLite.h:133
void put(const T &value)
void set(int index) const
sys::SystemOutStream & out
void clear(int index) const
bool equals(const t &v1, const t &v2)
Definition: AbsIntLite.h:159
DomainIter(const AbsIntLiteEx &_ail)
Definition: AbsIntLite.h:130
t bottom(void)
Definition: AbsIntLite.h:157
void update(typename G::Vertex v, t &d)
Definition: AbsIntLite.h:162
AbsIntLiteExtender(D &domain)
Definition: AbsIntLite.h:155
void filter(typename G::Edge e, t &d)
Definition: AbsIntLite.h:163
genstruct::VectorQueue< typename G::Vertex > todo
Definition: AbsIntLite.h:145
T::t & item(void)
Definition: AbsIntLite.h:134
void process(void)
Definition: AbsIntLite.h:58
Definition: AbsIntLite.h:38
bool ended(void) const
Definition: AbsIntLite.h:132
D::t t
Definition: AbsIntLite.h:154
Definition: AbsIntLite.h:152
const G & g
Definition: AbsIntLite.h:141