ROSE 0.11.145.147
divAnalysis.h
1#include <featureTests.h>
2#ifdef ROSE_ENABLE_SOURCE_ANALYSIS
3
4#ifndef DIV_ANALYSIS_H
5#define DIV_ANALYSIS_H
6
7#include "genericDataflowCommon.h"
8#include "VirtualCFGIterator.h"
9#include "cfgUtils.h"
10#include "CallGraphTraverse.h"
11#include "analysisCommon.h"
12#include "analysis.h"
13#include "dataflow.h"
14#include "latticeFull.h"
15#include "liveDeadVarAnalysis.h"
16#include "printAnalysisStates.h"
17#include "VariableStateTransfer.h"
18
19#include <map>
20#include <string>
21#include <vector>
22
23extern int divAnalysisDebugLevel;
24
25// Maintains value information about live variables. If a given variable may have more than one value,
26// this object maintains divisibility information about all the possible values (i.e. they're all divisible
27// by x, with y as the remainder), with the divisior,remainder = (1,0) if nothing better can be found.
28// There is one DivLattice object for every variable
30{
31 private:
32 // the current value of the variable (if known)
33 long value;
34 // the <divisor, remainder> pair where for all possible values v of the variable
35 // there exists a multiplier m s.t v = div * m + rem
36 long div;
37 long rem;
38
39 public:
40 // The different levels of this lattice
41 // no information is known about the value of the variable
42 static const int bottom=1;
43 // the value of the variable is known
44 static const int valKnown=2;
45 // value is unknown but the divisibility (div and rem) of this variable is known
46 static const int divKnown=3;
47 // this variable holds more values than can be represented using a single value and divisibility
48 static const int top=4;
49
50 private:
51 // this object's current level in the lattice: (bottom, valKnown, divKnown, top)
52 short level;
53
54 public:
55
57 {
58 value=0;
59 div=-1;
60 rem=-1;
61 level=bottom;
62 }
63
64 DivLattice(long value) {
65 this->value = value;
66 div = -1;
67 rem = -1;
68 level = valKnown;
69 }
70
71 DivLattice(long div, long rem) {
72 value = 0;
73 this->div = div;
74 this->rem = rem;
75 level = divKnown;
76 }
77
78 DivLattice(const DivLattice& that)
79 {
80 this->value = that.value;
81 this->div = that.div;
82 this->rem = that.rem;
83 this->level = that.level;
84 }
85
86 // initializes this Lattice to its default state
87 void initialize()
88 { }
89
90 // returns a copy of this lattice
91 Lattice* copy() const;
92
93 // overwrites the state of this Lattice with that of that Lattice
94 void copy(Lattice* that);
95
96 // returns true if the given value matches the given div, rem combo and false otherwise
97 static bool matchDiv(long value, long div, long rem);
98
99 // Takes two lattices at level divKnown. If the two objects have matching div, rem pairs, returns
100 // true and sets div and rem to those mathching values. Otherwise, returns false;
101 static bool matchDiv(DivLattice* one, DivLattice* two, long& div, long& rem);
102
103 // Takes two lattices at level divKnown. If the two objects have div, rem pairs that make it
104 // possible to add or subtract them them and produce div/rem information where div>1,
105 // returns true and sets div and rem to correspond to the sum of these values.
106 // Otherwise, returns false.
107 // plus - true if the caller want to see one+two and false if one-two
108 static bool matchDivAddSubt(DivLattice* one, DivLattice* two, long& div, long& rem, bool plus);
109
110 // computes the meet of this and that and saves the result in this
111 // returns true if this causes this to change and false otherwise
112 bool meetUpdate(Lattice* that);
113
114 // computes the meet of this and that and returns the result
115 //Lattice* meet(Lattice* that) const;
116
117 bool operator==(Lattice* that);
118
119 /*// widens this from that and saves the result in this
120 // returns true if this causes this to change and false otherwise
121 bool widenUpdate(InfiniteLattice* that);*/
122
123 // returns the current state of this object
124 long getValue() const;
125 long getDiv() const;
126 long getRem() const;
127 short getLevel() const;
128
129 // Sets the state of this lattice to bottom
130 // returns true if this causes the lattice's state to change, false otherwise
131 bool setBot();
132
133 // Sets the state of this lattice to the given value.
134 // returns true if this causes the lattice's state to change, false otherwise
135 bool set(long value);
136
137 // Sets the state of this lattice to the given div/rem state.
138 // returns true if this causes the lattice's state to change, false otherwise
139 bool set(long div, long rem);
140
141 // Sets the state of this lattice to top
142 // returns true if this causes the lattice's state to change, false otherwise
143 bool setTop();
144
145 // Increments the state of this object by increment
146 // returns true if this causes the lattice's state to change, false otherwise
147 bool incr(long increment);
148
149 // Multiplies the state of this object by value
150 // returns true if this causes the lattice's state to change, false otherwise
151 bool mult(long multiplier);
152
153 std::string str(std::string indent="");
154};
155
157{
158 template <class T>
159 void visitIntegerValue(T *sgn);
160 void transferIncrement(SgUnaryOp *sgn);
161 void transferCompoundAdd(SgBinaryOp *sgn);
162
163 typedef void (DivAnalysisTransfer::*TransferOp)(DivLattice *, DivLattice *, DivLattice *);
164 template <typename T>
165 void transferArith(SgBinaryOp *sgn, T transferOp);
166 void transferArith(SgBinaryOp *sgn, TransferOp transferOp);
167 void transferAdditive(DivLattice *arg1Lat, DivLattice *arg2Lat, DivLattice *resLat, bool isAddition);
168 void transferMultiplicative(DivLattice *arg1Lat, DivLattice *arg2Lat, DivLattice *resLat);
169 void transferDivision(DivLattice *arg1Lat, DivLattice *arg2Lat, DivLattice *resLat);
170 void transferMod(DivLattice *arg1Lat, DivLattice *arg2Lat, DivLattice *resLat);
171
172public:
173
174 // removes warning messages regarding overriding virtual function visit below
175 using VariableStateTransfer<DivLattice>::visit;
176
177 // void visit(SgNode *);
178 void visit(SgLongLongIntVal*) override;
179 void visit(SgLongIntVal*) override;
180 void visit(SgIntVal*) override;
181 void visit(SgShortVal*) override;
182 void visit(SgUnsignedLongLongIntVal*) override;
183 void visit(SgUnsignedLongVal*) override;
184 void visit(SgUnsignedIntVal*) override;
185 void visit(SgUnsignedShortVal*) override;
186 void visit(SgValueExp*) override;
187 void visit(SgPlusAssignOp*) override;
188 void visit(SgMinusAssignOp*) override;
189 void visit(SgMultAssignOp*) override;
190 void visit(SgDivAssignOp*) override;
191 void visit(SgModAssignOp*) override;
192 void visit(SgAddOp*) override;
193 void visit(SgSubtractOp*) override;
194 void visit(SgMultiplyOp*) override;
195 void visit(SgDivideOp*) override;
196 void visit(SgModOp*) override;
197 void visit(SgPlusPlusOp*) override;
198 void visit(SgMinusMinusOp*) override;
199 void visit(SgUnaryAddOp*) override;
200 void visit(SgMinusOp*) override;
201
202 bool finish() override {
203 return modified;
204 }
205
206 DivAnalysisTransfer(const Function& func, const DataflowNode& n, NodeState& state, const std::vector<Lattice*>& dfInfo);
207};
208
210{
211 protected:
212 static std::map<varID, Lattice*> constVars;
213 static bool constVars_init;
214
215 // The LiveDeadVarsAnalysis that identifies the live/dead state of all application variables.
216 // Needed to create a FiniteVarsExprsProductLattice.
218
219 public:
221 {
222 this->ldva = ldva;
223 }
224
225 /*// generates the initial variable-specific lattice state for a dataflow node
226 Lattice* genInitVarState(const Function& func, const DataflowNode& n, const NodeState& state);
227
228 // generates the initial non-variable-specific lattice state for a dataflow node
229 Lattice* genInitNonVarState(const Function& func, const DataflowNode& n, const NodeState& state);*/
230
231 // generates the initial lattice state for the given dataflow node, in the given function, with the given NodeState
232 //std::vector<Lattice*> genInitState(const Function& func, const DataflowNode& n, const NodeState& state);
233 void genInitState(const Function& func, const DataflowNode& n, const NodeState& state,
234 std::vector<Lattice*>& initLattices, std::vector<NodeFact*>& initFacts);
235
236 // Returns a map of special constant variables (such as zeroVar) and the lattices that correspond to them
237 // These lattices are assumed to be constants: it is assumed that they are never modified and it is legal to
238 // maintain only one copy of each lattice may for the duration of the analysis.
239 //std::map<varID, Lattice*>& genConstVarLattices() const;
240
241 bool transfer(const Function&, const DataflowNode&, NodeState&, const std::vector<Lattice*>&) {
242 ROSE_ABORT();
243 }
244
245 boost::shared_ptr<IntraDFTransferVisitor> getTransferVisitor(const Function& func, const DataflowNode& n,
246 NodeState& state, const std::vector<Lattice*>& dfInfo) {
247 return boost::shared_ptr<IntraDFTransferVisitor>(new DivAnalysisTransfer(func, n, state, dfInfo));
248 }
249};
250
251// prints the Lattices set by the given DivAnalysis
252void printDivAnalysisStates(DivAnalysis* da, std::string indent="");
253
254#endif
255#endif
This class represents the notion of a binary operator. It is derived from a SgExpression because oper...
This class represents the numeric negation of a value. Not to be confused with SgSubtractOp.
This class represents the notion of a unary operator. It is derived from a SgExpression because opera...
This class represents the notion of an value (expression value).