zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ForLoopUnroll.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
8 
9 namespace {
10 
11 class IntegerForLoopUnrollMarker : public TIntermTraverser {
12 public:
13 
14  virtual bool visitLoop(Visit, TIntermLoop* node)
15  {
16  // This is called after ValidateLimitations pass, so all the ASSERT
17  // should never fail.
18  // See ValidateLimitations::validateForLoopInit().
19  ASSERT(node);
20  ASSERT(node->getType() == ELoopFor);
21  ASSERT(node->getInit());
22  TIntermAggregate* decl = node->getInit()->getAsAggregate();
23  ASSERT(decl && decl->getOp() == EOpDeclaration);
24  TIntermSequence& declSeq = decl->getSequence();
25  ASSERT(declSeq.size() == 1);
26  TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
27  ASSERT(declInit && declInit->getOp() == EOpInitialize);
28  ASSERT(declInit->getLeft());
29  TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
30  ASSERT(symbol);
31  TBasicType type = symbol->getBasicType();
32  ASSERT(type == EbtInt || type == EbtFloat);
33  if (type == EbtInt)
34  node->setUnrollFlag(true);
35  return true;
36  }
37 
38 };
39 
40 } // anonymous namepsace
41 
43 {
44  ASSERT(node->getType() == ELoopFor);
45  ASSERT(node->getUnrollFlag());
46 
47  TIntermNode* init = node->getInit();
48  ASSERT(init != NULL);
49  TIntermAggregate* decl = init->getAsAggregate();
50  ASSERT((decl != NULL) && (decl->getOp() == EOpDeclaration));
51  TIntermSequence& declSeq = decl->getSequence();
52  ASSERT(declSeq.size() == 1);
53  TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
54  ASSERT((declInit != NULL) && (declInit->getOp() == EOpInitialize));
55  TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
56  ASSERT(symbol != NULL);
57  ASSERT(symbol->getBasicType() == EbtInt);
58 
59  info.id = symbol->getId();
60 
61  ASSERT(declInit->getRight() != NULL);
62  TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion();
63  ASSERT(initNode != NULL);
64 
65  info.initValue = evaluateIntConstant(initNode);
66  info.currentValue = info.initValue;
67 
68  TIntermNode* cond = node->getCondition();
69  ASSERT(cond != NULL);
70  TIntermBinary* binOp = cond->getAsBinaryNode();
71  ASSERT(binOp != NULL);
72  ASSERT(binOp->getRight() != NULL);
73  ASSERT(binOp->getRight()->getAsConstantUnion() != NULL);
74 
75  info.incrementValue = getLoopIncrement(node);
76  info.stopValue = evaluateIntConstant(
77  binOp->getRight()->getAsConstantUnion());
78  info.op = binOp->getOp();
79 }
80 
82 {
83  ASSERT(mLoopIndexStack.size() > 0);
84  TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
85  info.currentValue += info.incrementValue;
86 }
87 
89 {
90  ASSERT(mLoopIndexStack.size() > 0);
91  TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
92  // Relational operator is one of: > >= < <= == or !=.
93  switch (info.op) {
94  case EOpEqual:
95  return (info.currentValue == info.stopValue);
96  case EOpNotEqual:
97  return (info.currentValue != info.stopValue);
98  case EOpLessThan:
99  return (info.currentValue < info.stopValue);
100  case EOpGreaterThan:
101  return (info.currentValue > info.stopValue);
102  case EOpLessThanEqual:
103  return (info.currentValue <= info.stopValue);
104  case EOpGreaterThanEqual:
105  return (info.currentValue >= info.stopValue);
106  default:
107  UNREACHABLE();
108  }
109  return false;
110 }
111 
113 {
114  for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
115  i != mLoopIndexStack.end();
116  ++i) {
117  if (i->id == symbol->getId())
118  return true;
119  }
120  return false;
121 }
122 
124 {
125  for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin();
126  i != mLoopIndexStack.end();
127  ++i) {
128  if (i->id == symbol->getId())
129  return i->currentValue;
130  }
131  UNREACHABLE();
132  return false;
133 }
134 
136 {
137  mLoopIndexStack.push_back(info);
138 }
139 
141 {
142  mLoopIndexStack.pop_back();
143 }
144 
145 // static
147  TIntermNode* root)
148 {
149  ASSERT(root);
150 
151  IntegerForLoopUnrollMarker marker;
152  root->traverse(&marker);
153 }
154 
155 int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
156 {
157  TIntermNode* expr = node->getExpression();
158  ASSERT(expr != NULL);
159  // for expression has one of the following forms:
160  // loop_index++
161  // loop_index--
162  // loop_index += constant_expression
163  // loop_index -= constant_expression
164  // ++loop_index
165  // --loop_index
166  // The last two forms are not specified in the spec, but I am assuming
167  // its an oversight.
168  TIntermUnary* unOp = expr->getAsUnaryNode();
169  TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
170 
171  TOperator op = EOpNull;
172  TIntermConstantUnion* incrementNode = NULL;
173  if (unOp != NULL) {
174  op = unOp->getOp();
175  } else if (binOp != NULL) {
176  op = binOp->getOp();
177  ASSERT(binOp->getRight() != NULL);
178  incrementNode = binOp->getRight()->getAsConstantUnion();
179  ASSERT(incrementNode != NULL);
180  }
181 
182  int increment = 0;
183  // The operator is one of: ++ -- += -=.
184  switch (op) {
185  case EOpPostIncrement:
186  case EOpPreIncrement:
187  ASSERT((unOp != NULL) && (binOp == NULL));
188  increment = 1;
189  break;
190  case EOpPostDecrement:
191  case EOpPreDecrement:
192  ASSERT((unOp != NULL) && (binOp == NULL));
193  increment = -1;
194  break;
195  case EOpAddAssign:
196  ASSERT((unOp == NULL) && (binOp != NULL));
197  increment = evaluateIntConstant(incrementNode);
198  break;
199  case EOpSubAssign:
200  ASSERT((unOp == NULL) && (binOp != NULL));
201  increment = - evaluateIntConstant(incrementNode);
202  break;
203  default:
204  ASSERT(false);
205  }
206 
207  return increment;
208 }
209 
210 int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node)
211 {
212  ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL));
213  return node->getIConst(0);
214 }
215 
TOperator
Definition: intermediate.h:29
virtual TIntermBinary * getAsBinaryNode()
Definition: intermediate.h:408
Visit
Definition: intermediate.h:524
TOperator getOp() const
Definition: intermediate.h:389
TIntermSequence & getSequence()
Definition: intermediate.h:469
TIntermTyped * getCondition()
Definition: intermediate.h:301
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
const GLchar * marker
Definition: gl2ext.h:1092
bool getUnrollFlag()
Definition: intermediate.h:306
int getId() const
Definition: intermediate.h:348
#define NULL
Definition: ftobjs.h:61
virtual TIntermAggregate * getAsAggregate()
Definition: intermediate.h:223
virtual TIntermSymbol * getAsSymbolNode()
Definition: intermediate.h:357
TIntermTyped * getRight() const
Definition: intermediate.h:414
static void init(struct bs2b *bs2b)
Definition: bs2b.c:46
TBasicType getBasicType() const
Definition: intermediate.h:254
virtual TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:375
virtual TIntermBinary * getAsBinaryNode()
Definition: intermediate.h:224
void FillLoopIndexInfo(TIntermLoop *node, TLoopIndexInfo &info)
virtual TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:222
#define ASSERT(expression)
Definition: debug.h:36
int GetLoopIndexValue(TIntermSymbol *symbol)
virtual void traverse(TIntermTraverser *)=0
virtual TIntermUnary * getAsUnaryNode()
Definition: intermediate.h:225
ConstantUnion * getUnionArrayPointer() const
Definition: intermediate.h:369
#define UNREACHABLE()
Definition: debug.h:47
static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode *root)
TOperator op
Definition: ForLoopUnroll.h:14
TBasicType
Definition: BaseTypes.h:36
int getIConst(int index) const
Definition: intermediate.h:371
virtual bool visitLoop(Visit visit, TIntermLoop *)
Definition: intermediate.h:558
void Push(TLoopIndexInfo &info)
TIntermTyped * getExpression()
Definition: intermediate.h:302
void setUnrollFlag(bool flag)
Definition: intermediate.h:305
int i
Definition: pngrutil.c:1377
bool SatisfiesLoopCondition()
TIntermNode * getInit()
Definition: intermediate.h:300
bool NeedsToReplaceSymbolWithValue(TIntermSymbol *symbol)
virtual TIntermAggregate * getAsAggregate()
Definition: intermediate.h:466
TLoopType getType() const
Definition: intermediate.h:299