ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VariableStateTransfer.h
Go to the documentation of this file.
1 #ifndef _VARIABLESTATETRANSFER_H
2 #define _VARIABLESTATETRANSFER_H
3 
4 #include "dataflow.h"
5 #include "latticeFull.h"
6 #include "liveDeadVarAnalysis.h"
7 
8 #include <vector>
9 
10 template <class LatticeType>
12 {
13 protected:
14  bool modified;
15  void updateModified(bool latModified) { modified = latModified || modified; }
16 
17  const int debugLevel;
18 
20 
21  LatticeType *getLattice(const SgExpression *sgn) {
22  return sgn ? getLattice(SgExpr2Var(sgn)) : NULL;
23  }
24  LatticeType *getLattice(varID var) {
25  return dynamic_cast<LatticeType *>(prodLat->getVarLattice(var));
26  }
27 
29  bool getLattices(const SgBinaryOp *sgn, LatticeType* &arg1Lat, LatticeType* &arg2Lat, LatticeType* &resLat) {
30  arg1Lat = getLattice(sgn->get_lhs_operand());
31  arg2Lat = getLattice(sgn->get_rhs_operand());
32  resLat = getLattice(sgn);
33 
34  if(isSgCompoundAssignOp(sgn)) {
35  if(resLat==NULL && arg1Lat != NULL)
36  resLat = arg1Lat;
37  }
38  //Dbg::dbg << "transfer B, resLat="<<resLat<<"\n";
39 
40  return (arg1Lat && arg2Lat && resLat);
41  }
42 
43  bool getLattices(const SgUnaryOp *sgn, LatticeType* &arg1Lat, LatticeType* &arg2Lat, LatticeType* &resLat) {
44  arg1Lat = getLattice(sgn->get_operand());
45  resLat = getLattice(sgn);
46 
47  // Unary Update
48  if(isSgMinusMinusOp(sgn) || isSgPlusPlusOp(sgn)) {
49  arg2Lat = new LatticeType(1);
50  }
51  //Dbg::dbg << "res="<<res.str()<<" arg1="<<arg1.str()<<" arg1Lat="<<arg1Lat<<", arg2Lat="<<arg2Lat<<"\n";
52  //Dbg::dbg << "transfer B, resLat="<<resLat<<"\n";
53 
54  return (arg1Lat && arg2Lat && resLat);
55  }
56 
57 public:
58  VariableStateTransfer(const Function& func, const DataflowNode& n, NodeState& state, const std::vector<Lattice*>& dfInfo, const int &debugLevel_)
59  : IntraDFTransferVisitor(func, n, state, dfInfo), modified(false), debugLevel(debugLevel_), prodLat(dynamic_cast<FiniteVarsExprsProductLattice*>(*(dfInfo.begin())))
60  {
61  //Dbg::dbg << "transfer A prodLat="<<prodLat<<"="<<prodLat->str(" ")<<"\n";
62  // Make sure that all the lattices are initialized
63  //prodLat->initialize();
64  const std::vector<Lattice*>& lattices = prodLat->getLattices();
65  for(std::vector<Lattice*>::const_iterator it = lattices.begin(); it!=lattices.end(); it++)
66  (dynamic_cast<LatticeType *>(*it))->initialize();
67  }
68 
69  void visit(SgAssignOp *sgn)
70  {
71  LatticeType *lhsLat, *rhsLat, *resLat;
72  getLattices(sgn, lhsLat, rhsLat, resLat);
73 
74  if(debugLevel>=1) {
75  if(resLat) Dbg::dbg << "resLat=\n "<<resLat->str(" ")<<"\n";
76  if(lhsLat) Dbg::dbg << "lhsLat=\n "<<lhsLat->str(" ")<<"\n";
77  if(rhsLat) Dbg::dbg << "rhsLat=\n "<<rhsLat->str(" ")<<"\n";
78  }
79 
80  // Copy the lattice of the right-hand-side to both the left-hand-side variable and to the assignment expression itself
81  if(resLat) // If the left-hand-side contains a live expression or variable
82  { resLat->copy(rhsLat); modified = true; }
83  if(lhsLat) // If the left-hand-side contains a live expression or variable
84  { lhsLat->copy(rhsLat); modified = true; }
85  }
86 
88  {
89  LatticeType* asgnLat = getLattice(sgn->get_operand());
90  LatticeType* resLat = getLattice(sgn);
91 
92  if(debugLevel>=1) {
93  if(asgnLat) Dbg::dbg << "asgnLat= "<<asgnLat->str(" ")<<"\n";
94  if(resLat) Dbg::dbg << "resLat= "<<resLat->str(" ")<<"\n";
95  }
96 
97  // If the result expression is live
98  if(resLat) { resLat->copy(asgnLat); modified = true; }
99  }
100 
101  // XXX: Right now, we take the meet of all of the elements of the
102  // initializer. This could be enhanced with an improved memory
103  // abstraction to treat each element individually.
105  {
106  LatticeType *res = getLattice(sgn);
108  if (inits.size() > 0) {
109  res->copy(getLattice(inits[0]));
110  modified = true;
111  for (size_t i = 1; i < inits.size(); ++i)
112  res->meetUpdate(getLattice(inits[i]));
113  }
114  }
115 
116  // XXX: This needs to be handled by an inter-procedural analysis
118  { }
119 
120  // XXX: I don't even know what this is - Phil
122  { }
123 
124  void visit(SgInitializedName *initName)
125  {
126  LatticeType* varLat = getLattice(initName);
127 
128  if(varLat) {
129  LatticeType* initLat = getLattice(initName->get_initializer());
130  // If there was no initializer, leave this in its default 'bottom' state
131  if(initLat) {
132  varLat->copy(initLat);
133  modified = true;
134  }
135  }
136  }
137 
138  void visit(SgBinaryOp *sgn) {
139  LatticeType *lhs, *rhs, *res;
140  getLattices(sgn, lhs, rhs, res);
141  if (res) {
142  res->copy(lhs);
143  res->meetUpdate(rhs);
144  modified = true;
145  }
146  }
147 
149  LatticeType *lhs, *rhs, *res;
150  getLattices(sgn, lhs, rhs, res);
151  if (lhs)
152  updateModified(lhs->meetUpdate(rhs));
153  // Liveness of the result implies liveness of LHS
154  if (res) {
155  res->copy(lhs);
156  modified = true;
157  }
158  }
159 
160  void visit(SgCommaOpExp *sgn)
161  {
162  LatticeType *lhsLat, *rhsLat, *resLat;
163  getLattices(sgn, lhsLat, rhsLat, resLat);
164 
165  if (resLat) {
166  resLat->copy(rhsLat);
167  modified = true;
168  }
169  }
170 
172  {
173  LatticeType *condLat = getLattice(sgn->get_conditional_exp()),
174  *trueLat = getLattice(sgn->get_true_exp()),
175  *falseLat = getLattice(sgn->get_false_exp()),
176  *resLat = getLattice(sgn);
177 
178  // Liveness of the result implies liveness of the input expressions
179  if (resLat) {
180  resLat->copy(condLat);
181  resLat->meetUpdate(trueLat);
182  resLat->meetUpdate(falseLat);
183  modified = true;
184  }
185  }
186 
187  void visit(SgScopeOp *)
188  {
189  // Documentation says this is no longer used, so explicitly fail if we see it
190  assert(0);
191  }
192 
194  {
195  LatticeType *res = getLattice(sgn);
196  if (res) {
197  res->copy(getLattice(sgn->get_operand()));
198  modified = true;
199  }
200  }
201 };
202 
203 #endif