ROSE  0.11.50.0
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 
13 template <class LatticeType>
15 {
16 protected:
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 
60 public:
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 *sgn)
121  { }
122 
123  // XXX: I don't even know what this is - Phil
124  void visit(SgDesignatedInitializer *sgn)
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
SgExprListExp * get_initializers() const
Returns the rhs.
This class represents the notion of a binary operator. It is derived from a SgExpression because oper...
This class represents the notion of a unary operator. It is derived from a SgExpression because opera...
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 declared variable.
This class represents the concept of a C trinary conditional expression (e.g. "test ...
This class represents the notion of an expression. Expressions are derived from SgLocatedNodes, since similar to statement, expressions have a concrete location within the user's source code.
Apply an analysis A's transfer function at a particular AST node type.
Definition: dataflow.h:87
SgExpression * get_true_exp() const
Access function for p_true_exp.
SgExpression * get_false_exp() const
Access function for p_false_exp.
ROSE_DLL_API void initialize()
Initialize diagnostics-related global variables.
SgExpression * get_rhs_operand() const
returns SgExpression pointer to the rhs operand associated with this binary operator.
SgExpression * get_conditional_exp() const
Access function for p_conditional_exp.
bool getLattices(const SgBinaryOp *sgn, LatticeType *&arg1Lat, LatticeType *&arg2Lat, LatticeType *&resLat)
create three lattices from a binary operation: lhs, rhs, and result lattices
SgExpression * get_lhs_operand() const
returns SgExpression pointer to the lhs operand associated with this binary operator.
This class represents the notion of an initializer for a variable declaration or expression in a func...
This class was part of CC++ support from a long time ago.
SgExpression * get_operand() const
returns SgExpression pointer to the operand associated with this unary operator.