OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ManagerAffineExpr.cpp
Go to the documentation of this file.
1 #include "ManagerAffineExpr.hpp"
2 
3 namespace OA {
4 namespace AffineExpr {
5 
7  :
8  mIR(_ir)
9 {
10 }
11 
12 
14  ExprHandle hExp,
15  ProcHandle hProc,
16  const set<OA_ptr<NamedLoc> > & indexVars,
17  const set<OA_ptr<NamedLoc> > & nonConstVars,
18  OA_ptr<Alias::Interface> aliasResults,
19  AffineAnlState *state)
20 {
22  afnExp = new AffineExprAbstraction();
23 
24  // convert the expression into an expression tree
25  OA_ptr<ExprTree> expTree = mIR->getExprTree(hExp);
26 
27  // an affine expression abstraction is constructed by visiting each
28  // of the nodes in an expression tree and determining the expressions
29  // terms and factors. The AffineExprExprTreeVisitor does this.
31  afnExp, mIR, hProc, indexVars, nonConstVars, aliasResults);
32  expTree->acceptVisitor(visitor);
33 
34  // the success or failure of converting the expression tree into an
35  // affine expression abstraction is stored in a state variable passed
36  // as an argument.
37  *state = visitor.getState();
38 
39  return afnExp;
40 }
41 
42 
43 // Visitor class:
44 // ----------------------------------
45 
47  // don't continue when in an error state
48  if(mState != VALID_AFFINE_EXP) { return; }
49 
50  // iterate over children in order to do a post-order traversal
51  for(int i = 0; i < n.num_children(); i++) {
52  ExprTree::ChildNodesIterator iterChildren(n);
53 
54  for(; iterChildren.isValid(); ++iterChildren) {
56  child = iterChildren.current();
57  child->acceptVisitor(*this);
58  }
59  }
60 
61  // determine what to do based on the type of operator
62  OpHandle hOp = n.getHandle();
63  switch(mIR->getOpType(hOp)) {
64  // if it's a plus sign analyze for a term
65  case OP_ADD:
66  case OP_SUBTRACT:
67  term();
68  break;
69 
70  // if it's a multiply sign analyze for a term
71  case OP_MULTIPLY:
72  term();
73  break;
74 
75  // in all other cases change the error state
76  case OP_DIVIDE:
77  case OP_MODULO:
78  case OP_SHIFT_LEFT:
79  case OP_SHIFT_RIGHT:
80  case OP_BIT_AND:
81  case OP_BIT_OR:
82  case OP_BIT_XOR:
83  case OP_OTHER:
85  break;
86  }
87 }
88 
90  // don't continue when in an error state
91  if(mState != VALID_AFFINE_EXP) { return; }
92 
93  // any time a function is called in an affine expression it is
94  // assumed to be non-linear
96 }
97 
99  // don't continue when in an error state
100  if(mState != VALID_AFFINE_EXP) { return; }
101 
102  OA_ptr<NamedLoc> var;
103  // get a named location for the memory reference:
104 
105  // If we have alias information:
106  // ....
107  /*
108  // convert the MRE into a MemRefHandle
109 
110  // use aliasing information to get a named location
111  OA_ptr<LocIterator> locs;
112  locs = mAliasResults->getMayLocs(hMemRef);
113  OA_ptr<Location> loc = locs->current();*
114  OA_ptr<NamedLoc> var = loc.convert<NamedLoc>();
115  var->output(*mIR);
116  */
117 
118  // IF we don't have alias information:
119  // there should be one MRE asscociated with the MemRefNode, if this
120  // is not the case than the variable is considered indirect.
121  MemRefHandle hMemRef = n.getHandle();
122  OA_ptr<MemRefExprIterator> iterMRE = mIR->getMemRefExprIterator(hMemRef);
123  OA_ptr<MemRefExpr> mre = iterMRE->current();
124  (*iterMRE)++;
125  if(iterMRE->isValid()) { mState = INDIRECT_REF; return; }
126 
127  // convert the MRE to a NamedRef, use information from the
128  // NamedRef class to get the location asscociated with it
129  if(mre->isaNamed()) {
130  OA_ptr<Location> loc;
131  OA_ptr<NamedRef> namedRef;
132  namedRef = mre.convert<NamedRef>();
133  SymHandle hSym = namedRef->getSymHandle();
134  loc = mIR->getLocation(mhProc, hSym);
135  var = loc.convert<NamedLoc>();
136  } else { assert(false); }
137 
138  // Now that we've got a location check to see if it's for a valid variable.
139  // It's not valid if the variable has been reassigned or its not
140  if(mNonConstVars.find(var) == mNonConstVars.end()) {
142  return;
143  }
144 
145  // if the variable was legal, recognize it
146  pushVar(var);
147 }
148 
150  assert(false);
151 }
152 
154  int val = mIR->constValIntVal(n.getHandle());
155  pushScaler(val);
156 }
157 
159  // convert the passed var into an object encoded for the stack, then
160  // push it onto the stack
161  StackObj oVar;
162  oVar.var = var;
163  oVar.isVar = true;
164  mStack.push(oVar);
165 }
166 
168  // convert the passed int into an object encoded for the stack, then
169  // push it onto the stack
170  StackObj oVal;
171  oVal.val = val;
172  oVal.isVar = false;
173  mStack.push(oVal);
174 }
175 
177  // don't continue when in an error state
178  if(mState != VALID_AFFINE_EXP) { return; }
179 
180  // pop off the last two items added to the stack
181  StackObj item1 = mStack.top(); mStack.pop();
182  StackObj item2 = mStack.top(); mStack.pop();
183 
184  // if one item is a variable and the other is a scalar set it so
185  // that item 1 is the scalar and item 2 is the variable
186  if(item1.isVar && !item2.isVar) {
187  StackObj tmp = item1;
188  item1 = item2;
189  item2 = tmp;
190  }
191 
192  // if any variable term
193 
194  if(item1.isVar && item2.isVar) {
196  } else {
197  if(item1.isVar) {
198  mAfExp->addTerm(item1.var, item2.val);
199  } else {
200  mAfExp->addTerm(item2.var, item1.val);
201  }
202  }
203 }
204 
205 /*
206 void AffineExprExprTreeVisitor::term() {
207  // don't continue when in an error state
208  if(mState != VALID_AFFINE_EXP) { return; }
209 
210  // check to make sure the last thing added to the stack was a val, add
211  // it as the offset in the affine expression abstraction
212  StackObj item = mStack.top(); mStack.pop();
213  assert(item.isVar == false);
214  mAfExp->setOffset(item.val);
215 }
216 */
217 
218 } } // end namespaces
219