ROSE 0.11.145.147
VariableStateTransfer.h
1#include <featureTests.h>
2#ifdef ROSE_ENABLE_SOURCE_ANALYSIS
3
4#ifndef _VARIABLESTATETRANSFER_H
5#define _VARIABLESTATETRANSFER_H
6
7#include "dataflow.h"
8#include "latticeFull.h"
9#include "liveDeadVarAnalysis.h"
10
11#include <vector>
12
13template <class LatticeType>
15{
16protected:
17 bool modified;
18 void updateModified(bool latModified) { modified = latModified || modified; }
19
20 const int debugLevel;
21
23
24 LatticeType *getLattice(const SgExpression *sgn) {
25 return sgn ? getLattice(SgExpr2Var(sgn)) : NULL;
26 }
27 LatticeType *getLattice(varID var) {
28 return dynamic_cast<LatticeType *>(prodLat->getVarLattice(var));
29 }
30
32 bool getLattices(const SgBinaryOp *sgn, LatticeType* &arg1Lat, LatticeType* &arg2Lat, LatticeType* &resLat) {
33 arg1Lat = getLattice(sgn->get_lhs_operand());
34 arg2Lat = getLattice(sgn->get_rhs_operand());
35 resLat = getLattice(sgn);
36
37 if(isSgCompoundAssignOp(sgn)) {
38 if(resLat==NULL && arg1Lat != NULL)
39 resLat = arg1Lat;
40 }
41 //Dbg::dbg << "transfer B, resLat="<<resLat<<"\n";
42
43 return (arg1Lat && arg2Lat && resLat);
44 }
45
46 bool getLattices(const SgUnaryOp *sgn, LatticeType* &arg1Lat, LatticeType* &arg2Lat, LatticeType* &resLat) {
47 arg1Lat = getLattice(sgn->get_operand());
48 resLat = getLattice(sgn);
49
50 // Unary Update
51 if(isSgMinusMinusOp(sgn) || isSgPlusPlusOp(sgn)) {
52 arg2Lat = new LatticeType(1);
53 }
54 //Dbg::dbg << "res="<<res.str()<<" arg1="<<arg1.str()<<" arg1Lat="<<arg1Lat<<", arg2Lat="<<arg2Lat<<"\n";
55 //Dbg::dbg << "transfer B, resLat="<<resLat<<"\n";
56
57 return (arg1Lat && arg2Lat && resLat);
58 }
59
60public:
61 VariableStateTransfer(const Function& func, const DataflowNode& n, NodeState& state, const std::vector<Lattice*>& dfInfo, const int &debugLevel_)
62 : IntraDFTransferVisitor(func, n, state, dfInfo), modified(false), debugLevel(debugLevel_), prodLat(dynamic_cast<FiniteVarsExprsProductLattice*>(*(dfInfo.begin())))
63 {
64 //Dbg::dbg << "transfer A prodLat="<<prodLat<<"="<<prodLat->str(" ")<<"\n";
65 // Make sure that all the lattices are initialized
66 //prodLat->initialize();
67 const std::vector<Lattice*>& lattices = prodLat->getLattices();
68 for(std::vector<Lattice*>::const_iterator it = lattices.begin(); it!=lattices.end(); it++)
69 (dynamic_cast<LatticeType *>(*it))->initialize();
70 }
71
72 void visit(SgAssignOp *sgn)
73 {
74 LatticeType *lhsLat, *rhsLat, *resLat;
75 getLattices(sgn, lhsLat, rhsLat, resLat);
76
77 if(debugLevel>=1) {
78 if(resLat) Dbg::dbg << "resLat=\n "<<resLat->str(" ")<<"\n";
79 if(lhsLat) Dbg::dbg << "lhsLat=\n "<<lhsLat->str(" ")<<"\n";
80 if(rhsLat) Dbg::dbg << "rhsLat=\n "<<rhsLat->str(" ")<<"\n";
81 }
82
83 // Copy the lattice of the right-hand-side to both the left-hand-side variable and to the assignment expression itself
84 if(resLat) // If the left-hand-side contains a live expression or variable
85 { resLat->copy(rhsLat); modified = true; }
86 if(lhsLat) // If the left-hand-side contains a live expression or variable
87 { lhsLat->copy(rhsLat); modified = true; }
88 }
89
90 void visit(SgAssignInitializer *sgn)
91 {
92 LatticeType* asgnLat = getLattice(sgn->get_operand());
93 LatticeType* resLat = getLattice(sgn);
94
95 if(debugLevel>=1) {
96 if(asgnLat) Dbg::dbg << "asgnLat= "<<asgnLat->str(" ")<<"\n";
97 if(resLat) Dbg::dbg << "resLat= "<<resLat->str(" ")<<"\n";
98 }
99
100 // If the result expression is live
101 if(resLat) { resLat->copy(asgnLat); modified = true; }
102 }
103
104 // XXX: Right now, we take the meet of all of the elements of the
105 // initializer. This could be enhanced with an improved memory
106 // abstraction to treat each element individually.
107 void visit(SgAggregateInitializer *sgn)
108 {
109 LatticeType *res = getLattice(sgn);
110 SgExpressionPtrList &inits = sgn->get_initializers()->get_expressions();
111 if (inits.size() > 0) {
112 res->copy(getLattice(inits[0]));
113 modified = true;
114 for (size_t i = 1; i < inits.size(); ++i)
115 res->meetUpdate(getLattice(inits[i]));
116 }
117 }
118
119 // XXX: This needs to be handled by an inter-procedural analysis
120 void visit(SgConstructorInitializer*)
121 { }
122
123 // XXX: I don't even know what this is - Phil
124 void visit(SgDesignatedInitializer*)
125 { }
126
127 void visit(SgInitializedName *initName)
128 {
129 LatticeType* varLat = getLattice(initName);
130
131 if(varLat) {
132 LatticeType* initLat = getLattice(initName->get_initializer());
133 // If there was no initializer, leave this in its default 'bottom' state
134 if(initLat) {
135 varLat->copy(initLat);
136 modified = true;
137 }
138 }
139 }
140
141 void visit(SgBinaryOp *sgn) {
142 LatticeType *lhs, *rhs, *res;
143 getLattices(sgn, lhs, rhs, res);
144 if (res) {
145 res->copy(lhs);
146 res->meetUpdate(rhs);
147 modified = true;
148 }
149 }
150
151 void visit(SgCompoundAssignOp *sgn) {
152 LatticeType *lhs, *rhs, *res;
153 getLattices(sgn, lhs, rhs, res);
154 if (lhs)
155 updateModified(lhs->meetUpdate(rhs));
156 // Liveness of the result implies liveness of LHS
157 if (res) {
158 res->copy(lhs);
159 modified = true;
160 }
161 }
162
163 void visit(SgCommaOpExp *sgn)
164 {
165 LatticeType *lhsLat, *rhsLat, *resLat;
166 getLattices(sgn, lhsLat, rhsLat, resLat);
167
168 if (resLat) {
169 resLat->copy(rhsLat);
170 modified = true;
171 }
172 }
173
174 void visit(SgConditionalExp *sgn)
175 {
176 LatticeType *condLat = getLattice(sgn->get_conditional_exp()),
177 *trueLat = getLattice(sgn->get_true_exp()),
178 *falseLat = getLattice(sgn->get_false_exp()),
179 *resLat = getLattice(sgn);
180
181 // Liveness of the result implies liveness of the input expressions
182 if (resLat) {
183 resLat->copy(condLat);
184 resLat->meetUpdate(trueLat);
185 resLat->meetUpdate(falseLat);
186 modified = true;
187 }
188 }
189
190 void visit(SgScopeOp *)
191 {
192 // Documentation says this is no longer used, so explicitly fail if we see it
193 ROSE_ABORT();
194 }
195
196 void visit(SgBitComplementOp *sgn)
197 {
198 LatticeType *res = getLattice(sgn);
199 if (res) {
200 res->copy(getLattice(sgn->get_operand()));
201 modified = true;
202 }
203 }
204};
205
206#endif
207#endif
Apply an analysis A's transfer function at a particular AST node type.
Definition dataflow.h:88
SgExprListExp * get_initializers() const
Returns the rhs.
This class represents the rhs of a variable declaration which includes an optional assignment (e....
SgExpression * get_operand() const
Returns the rhs.
This class represents the notion of a binary operator. It is derived from a SgExpression because oper...
SgExpression * get_lhs_operand() const
returns SgExpression pointer to the lhs operand associated with this binary operator.
SgExpression * get_rhs_operand() const
returns SgExpression pointer to the rhs operand associated with this binary operator.
This class represents the concept of a C trinary conditional expression (e.g. "test ?...
SgExpression * get_true_exp() const
Access function for p_true_exp.
SgExpression * get_conditional_exp() const
Access function for p_conditional_exp.
SgExpression * get_false_exp() const
Access function for p_false_exp.
This class represents the call of a class constructor to initialize a variable. For example "Foo foo;...
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes,...
This class represents the notion of a declared variable.
This class was part of CC++ support from a long time ago.
This class represents the notion of a unary operator. It is derived from a SgExpression because opera...
SgExpression * get_operand() const
returns SgExpression pointer to the operand associated with this unary operator.
bool getLattices(const SgBinaryOp *sgn, LatticeType *&arg1Lat, LatticeType *&arg2Lat, LatticeType *&resLat)
create three lattices from a binary operation: lhs, rhs, and result lattices
ROSE_DLL_API void initialize()
Initialize diagnostics-related global variables.