ROSE 0.11.145.147
latticeFull.h
1#include <featureTests.h>
2#ifdef ROSE_ENABLE_SOURCE_ANALYSIS
3
4#ifndef LATTICE_FULL_H
5#define LATTICE_FULL_H
6
7#include "cfgUtils.h"
8#include "variables.h"
9#include "nodeState.h"
10#include "lattice.h"
11#include <string>
12#include <map>
13#include <vector>
14
15/******************************
16 *** Commonly used lattices ***
17 ******************************/
18
20{
21 // state can be:
22 // -1 : unset (default value)
23 // 0 : false
24 // 1 : true
25 int state;
26
27 public:
29 { state = -1; }
30
31 private:
32 BoolAndLattice(int state)
33 { this->state = state; }
34
35 public:
36 BoolAndLattice(bool state)
37 { this->state = state; }
38
39 // initializes this Lattice to its default state
40 void initialize()
41 { state = -1; }
42
43 // returns a copy of this lattice
44 Lattice* copy() const;
45
46 // overwrites the state of this Lattice with that of that Lattice
47 void copy(Lattice* that);
48
49 // computes the meet of this and that and saves the result in this
50 // returns true if this causes this to change and false otherwise
51 bool meetUpdate(Lattice* that);
52
53 bool operator==(Lattice* that);
54
55 // returns the current state of this object
56 bool get() const;
57
58 // sets the state of this BoolAndLattice to the given value
59 // returns true if this causes the BoolAndLattice state to change, false otherwise
60 bool set(bool state);
61
62 // sets the state of this lattice to the conjunction of the BoolAndLattice's current state and the given value
63 // returns true if this causes the BoolAndLattice state to change, false otherwise
64 bool andUpd(bool state);
65
66 // Functions used to inform this lattice that a given variable is now in use (e.g. a variable has entered
67 // scope or an expression is being analyzed) or is no longer in use (e.g. a variable has exited scope or
68 // an expression or variable is dead).
69 // It is assumed that a newly-added variable has not been added before and that a variable that is being
70 // removed was previously added
71 // These are empty in this lattice since it is now explicitly aware of variables.
72 /*void addVar(varID var) {};
73 void remVar(varID var) {};*/
74
75 std::string str(std::string indent="");
76};
77
79{
80 int state;
81
82 public:
83 static const int infinity;// = 32768;
84
86 {
87 state = -1;
88 }
89
90 IntMaxLattice(int state)
91 {
92 this->state = state;
93 }
94
95 // initializes this Lattice to its default state
96 void initialize()
97 {
98 state = -1;
99 }
100
101 // returns a copy of this lattice
102 Lattice* copy() const;
103
104 // overwrites the state of this Lattice with that of that Lattice
105 void copy(Lattice* that);
106
107 // computes the meet of this and that and saves the result in this
108 // returns true if this causes this to change and false otherwise
109 bool meetUpdate(Lattice* that);
110
111 bool operator==(Lattice* that);
112
113 // widens this from that and saves the result in this
114 // returns true if this causes this to change and false otherwise
115 bool widenUpdate(InfiniteLattice* that);
116
117 // returns the current state of this object
118 int get() const;
119
120 // sets the state of this lattice to the given value
121 // returns true if this causes the lattice's state to change, false otherwise
122 bool set(int state);
123
124 // increments the state of this lattice by the given value
125 // returns true if this causes the lattice's state to change, false otherwise
126 bool incr(int increment);
127
128 // computes the maximum of the given value and the state of this lattice and saves
129 // the result in this lattice
130 // returns true if this causes the lattice's state to change, false otherwise
131 bool maximum(int value);
132
133 // Functions used to inform this lattice that a given variable is now in use (e.g. a variable has entered
134 // scope or an expression is being analyzed) or is no longer in use (e.g. a variable has exited scope or
135 // an expression or variable is dead).
136 // It is assumed that a newly-added variable has not been added before and that a variable that is being
137 // removed was previously added
138 // These are empty in this lattice since it is now explicitly aware of variables.
139 /*void addVar(varID var) {};
140 void remVar(varID var) {};*/
141
142 std::string str(std::string indent="");
143};
144
145/*########################
146 ### Utility lattices ###
147 ########################*/
148
149// A container lattice to store other lattices
150class ProductLattice : public virtual Lattice
151{
152 public:
153 // The different levels of this lattice
154 static const int uninitialized=0;
155 static const int initialized=1;
156 // This object's current level in the lattice: (uninitialized or initialized)
157 short level;
158
159 protected:
160 std::vector<Lattice*> lattices;
161
162 public:
164 ProductLattice(const std::vector<Lattice*>& lattices);
166
167 void init(const std::vector<Lattice*>& lattices);
168
169 // initializes this Lattice to its default state
170 void initialize();
171
172 const std::vector<Lattice*>& getLattices();
173
174 // initializes the given vector with a copy of the lattices vector
175 void copy_lattices(std::vector<Lattice*>& newLattices) const;
176
177 // overwrites the state of this Lattice with that of that Lattice
178 virtual void copy(Lattice* that);
179
180 // computes the meet of this and that and saves the result in this
181 // returns true if this causes this to change and false otherwise
182 virtual bool meetUpdate(Lattice* that);
183
184 virtual bool operator==(Lattice* that);
185
186 int getLevel() { return level; }
187
188 // Functions used to inform this lattice that a given variable is now in use (e.g. a variable has entered
189 // scope or an expression is being analyzed) or is no longer in use (e.g. a variable has exited scope or
190 // an expression or variable is dead).
191 // It is assumed that a newly-added variable has not been added before and that a variable that is being
192 // removed was previously added
193 // These are empty in this lattice since it is now explicitly aware of variables.
194 /*void addVar(varID var) {};
195 void remVar(varID var) {};*/
196
197 // The string that represents this object
198 // If indent!="", every line of this string must be prefixed by indent
199 // The last character of the returned string should not be '\n', even if it is a multi-line string.
200 virtual std::string str(std::string indent="");
201};
202
203class FiniteProductLattice : public virtual ProductLattice, public virtual FiniteLattice
204{
205 public:
207 {}
208
209 FiniteProductLattice(const std::vector<Lattice*>& lattices) : ProductLattice(lattices), FiniteLattice()
210 {
211 verifyFinite();
212 }
213
215 {
216 verifyFinite();
217 }
218
219 void verifyFinite()
220 {
221 for(std::vector<Lattice*>::iterator it = lattices.begin(); it!=lattices.end(); it++)
222 ROSE_ASSERT((*it)->finiteLattice());
223 }
224
225 using ProductLattice::copy; // removes warning of hiding overloaded virtual function
226
227 // Returns a copy of this lattice
228 Lattice* copy() const override
229 {
230 return new FiniteProductLattice(*this);
231 }
232};
233
234class InfiniteProductLattice : public virtual ProductLattice, public virtual InfiniteLattice
235{
236 public:
238 {}
239
240 InfiniteProductLattice(const std::vector<Lattice*>& lattices) : ProductLattice(lattices), InfiniteLattice()
241 {}
242
244 {}
245
246 using ProductLattice::copy; // removes warning of hiding overloaded virtual function
247
248 // returns a copy of this lattice
249 Lattice* copy() const override
250 {
251 return new InfiniteProductLattice(*this);
252 }
253
254 // Widens this from that and saves the result in this.
255 // Returns true if this causes this to change and false otherwise.
256 bool widenUpdate(InfiniteLattice* that) override;
257};
258
259
261{
262 protected:
263 // if =true, a lattice is created for each scalar variable
264 bool includeScalars;
265 // if =true, a lattice is created for each array variable
266 bool includeArrays;
267 // the function that this lattice is associated with
268 Function func;
269 // map of lattices that correspond to constant variables, for quick search
270 std::map<varID, Lattice*> constVarLattices;
271 // lattice that corresponds to allVar;
272 Lattice* allVarLattice;
273
274 // sample lattice that will be initially associated with every variable (before the analysis)
275 Lattice* perVarLattice;
276
277 // maps variables in a given function to the index of their respective Lattice objects in
278 // the ProductLattice::lattice[] array
279 static std::map<Function, std::map<varID, int> > varLatticeIndex;
280
281 public:
282 // creates a new VariablesProductLattice
283 // includeScalars - if =true, a lattice is created for each scalar variable
284 // includeArrays - if =true, a lattice is created for each array variable
285 // perVarLattice - sample lattice that will be associated with every variable in scope at node n
286 // it should be assumed that the object pointed to by perVarLattice will be either
287 // used internally by this VariablesProductLattice object or deallocated
288 // constVarLattices - map of additional variables and their associated lattices, that will be
289 // incorporated into this VariablesProductLattice in addition to any other lattices for
290 // currently live variables (these correspond to various useful constant variables like zeroVar)
291 // allVarLattice - the lattice associated with allVar (the variable that represents all of memory)
292 // if allVarLattice==NULL, no support is provided for allVar
293 // func - the current function
294 // n - the dataflow node that this lattice will be associated with
295 // state - the NodeState at this dataflow node
296 VariablesProductLattice(bool includeScalars, bool includeArrays, Lattice* perVarLattice,
297 const std::map<varID, Lattice*>& constVarLattices, Lattice* allVarLattice,
298 const Function& func, const DataflowNode& n, const NodeState& state);
299
300 // copy constructor
302
303 public:
304
305 Lattice* getVarLattice(const Function& func, const varID& var);
306
307 protected:
308 // sets up the varLatticeIndex map, if necessary
309 void setUpVarLatticeIndex();
310
311 // returns the index of var among the variables associated with func
312 // or -1 otherwise
313 int getVarIndex(const Function& func, const varID& var);
314
315 public:
316
317 // returns the set of global variables(scalars and/or arrays)
318 varIDSet& getGlobalVars() const;
319 static varIDSet& getGlobalVars(bool includeScalars, bool includeArrays);
320
321 // returns the set of variables(scalars and/or arrays) declared in this function
322 varIDSet& getLocalVars(Function func) const;
323
324 // returns the set of variables(scalars and/or arrays) referenced in this function
325 varIDSet& getRefVars(Function func) const;
326
327 // returns the set of variables(scalars and/or arrays) visible in this function
328 varIDSet getVisibleVars(Function func) const;
329
330 // overwrites the state of this Lattice with that of that Lattice
331 void copy(Lattice* that);
332
333 // Called by analyses to create a copy of this lattice. However, if this lattice maintains any
334 // information on a per-variable basis, these per-variable mappings must be converted from
335 // the current set of variables to another set. This may be needed during function calls,
336 // when dataflow information from the caller/callee needs to be transferred to the callee/calleer.
337 // We do not force child classes to define their own versions of this function since not all
338 // Lattices have per-variable information.
339 // varNameMap - maps all variable names that have changed, in each mapping pair, pair->first is the
340 // old variable and pair->second is the new variable
341 // func - the function that the copy Lattice will now be associated with
342 /*Lattice**/void remapVars(const std::map<varID, varID>& varNameMap, const Function& newFunc);
343
344 // Called by analyses to copy over from the that Lattice dataflow information into this Lattice.
345 // that contains data for a set of variables and incorporateVars must overwrite the state of just
346 // those variables, while leaving its state for other variables alone.
347 // We do not force child classes to define their own versions of this function since not all
348 // Lattices have per-variable information.
349 void incorporateVars(Lattice* that);
350
351 // Functions used to inform this lattice that a given variable is now in use (e.g. a variable has entered
352 // scope or an expression is being analyzed) or is no longer in use (e.g. a variable has exited scope or
353 // an expression or variable is dead).
354 // It is assumed that a newly-added variable has not been added before and that a variable that is being
355 // removed was previously added
356 /*void addVar(varID var);
357 void remVar(varID var);*/
358
359 // The string that represents this object
360 // If indent!="", every line of this string must be prefixed by indent
361 // The last character of the returned string should not be '\n', even if it is a multi-line string.
362 std::string str(std::string indent="");
363};
364
366{
367 public:
368 // creates a new VariablesProductLattice
369 // perVarLattice - sample lattice that will be associated with every variable in scope at node n
370 // it should be assumed that the object pointed to by perVarLattice will be either
371 // used internally by this VariablesProductLattice object or deallocated
372 // constVarLattices - map of additional variables and their associated lattices, that will be
373 // incorporated into this VariablesProductLattice in addition to any other lattices for
374 // currently live variables (these correspond to various useful constant variables like zeroVar)
375 // allVarLattice - the lattice associated with allVar (the variable that represents all of memory)
376 // if allVarLattice==NULL, no support is provided for allVar
377 // func - the current function
378 // n - the dataflow node that this lattice will be associated with
379 // state - the NodeState at this dataflow node
380 FiniteVariablesProductLattice(bool includeScalars, bool includeArrays,
381 Lattice* perVarLattice, const std::map<varID, Lattice*>& constVarLattices, Lattice* allVarLattice,
382 const Function& func, const DataflowNode& n, const NodeState& state) :
383 VariablesProductLattice(includeScalars, includeArrays, perVarLattice, constVarLattices, allVarLattice, func, n, state),
385 {
386 verifyFinite();
387 }
388
391 {
392 verifyFinite();
393 }
394
395 using VariablesProductLattice::copy; // removes warning of hiding overloaded virtual function
396
397 // returns a copy of this lattice
398 Lattice* copy() const override
399 {
400 return new FiniteVariablesProductLattice(*this);
401 }
402};
403
405{
406 public:
407 // creates a new VariablesProductLattice
408 // perVarLattice - sample lattice that will be associated with every variable in scope at node n
409 // it should be assumed that the object pointed to by perVarLattice will be either
410 // used internally by this VariablesProductLattice object or deallocated
411 // constVarLattices - map of additional variables and their associated lattices, that will be
412 // incorporated into this VariablesProductLattice in addition to any other lattices for
413 // currently live variables (these correspond to various useful constant variables like zeroVar)
414 // allVarLattice - the lattice associated with allVar (the variable that represents all of memory)
415 // if allVarLattice==NULL, no support is provided for allVar
416 // func - the current function
417 // n - the dataflow node that this lattice will be associated with
418 // state - the NodeState at this dataflow node
419 InfiniteVariablesProductLattice(bool includeScalars, bool includeArrays,
420 Lattice* perVarLattice, std::map<varID, Lattice*> constVarLattices, Lattice* allVarLattice,
421 const Function& func, const DataflowNode& n, const NodeState& state) :
422 VariablesProductLattice(includeScalars, includeArrays, perVarLattice, constVarLattices, allVarLattice, func, n, state),
424 {
425 }
426
429 {
430 }
431
432 using VariablesProductLattice::copy; // removes warning of hiding overloaded virtual function
433
434 // returns a copy of this lattice
435 Lattice* copy() const override
436 {
437 return new InfiniteVariablesProductLattice(*this);
438 }
439};
440
441#endif
442#endif