zenilib: zenilib/jni/external/angle/src/compiler/ForLoopUnroll.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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
7 #include "compiler/ForLoopUnroll.h"
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
42 void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info)
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
81 void ForLoopUnroll::Step()
82 {
83 ASSERT(mLoopIndexStack.size() > 0);
84 TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1];
85 info.currentValue += info.incrementValue;
86 }
87
88 bool ForLoopUnroll::SatisfiesLoopCondition()
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
112 bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol)
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
123 int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol)
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
135 void ForLoopUnroll::Push(TLoopIndexInfo& info)
136 {
137 mLoopIndexStack.push_back(info);
138 }
139
140 void ForLoopUnroll::Pop()
141 {
142 mLoopIndexStack.pop_back();
143 }
144
145 // static
146 void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(
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
TOperator
Definition: intermediate.h:29
TIntermBinary::getAsBinaryNode
virtual TIntermBinary * getAsBinaryNode()
Definition: intermediate.h:408
Visit
Visit
Definition: intermediate.h:524
TIntermOperator::getOp
TOperator getOp() const
Definition: intermediate.h:389
TIntermAggregate::getSequence
TIntermSequence & getSequence()
Definition: intermediate.h:469
TIntermLoop::getCondition
TIntermTyped * getCondition()
Definition: intermediate.h:301
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
marker
const GLchar * marker
Definition: gl2ext.h:1092
ELoopFor
Definition: intermediate.h:279
TIntermLoop::getUnrollFlag
bool getUnrollFlag()
Definition: intermediate.h:306
TIntermSymbol::getId
int getId() const
Definition: intermediate.h:348
NULL
#define NULL
Definition: ftobjs.h:61
TIntermNode::getAsAggregate
virtual TIntermAggregate * getAsAggregate()
Definition: intermediate.h:223
TIntermSymbol::getAsSymbolNode
virtual TIntermSymbol * getAsSymbolNode()
Definition: intermediate.h:357
EOpInitialize
Definition: intermediate.h:179
TIntermBinary::getRight
TIntermTyped * getRight() const
Definition: intermediate.h:414
ForLoopUnroll::Pop
void Pop()
Definition: ForLoopUnroll.cpp:140
init
static void init(struct bs2b *bs2b)
Definition: bs2b.c:46
TIntermTyped::getBasicType
TBasicType getBasicType() const
Definition: intermediate.h:254
TIntermConstantUnion::getAsConstantUnion
virtual TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:375
EOpGreaterThan
Definition: intermediate.h:72
EOpPreIncrement
Definition: intermediate.h:49
TIntermNode::getAsBinaryNode
virtual TIntermBinary * getAsBinaryNode()
Definition: intermediate.h:224
EOpDeclaration
Definition: intermediate.h:36
TLoopIndexInfo::stopValue
int stopValue
Definition: ForLoopUnroll.h:12
EbtInt
Definition: BaseTypes.h:40
EbtFloat
Definition: BaseTypes.h:39
TIntermAggregate
Definition: intermediate.h:460
TIntermBinary
Definition: intermediate.h:404
TLoopIndexInfo::currentValue
int currentValue
Definition: ForLoopUnroll.h:15
ForLoopUnroll::FillLoopIndexInfo
void FillLoopIndexInfo(TIntermLoop *node, TLoopIndexInfo &info)
Definition: ForLoopUnroll.cpp:42
TIntermNode::getAsConstantUnion
virtual TIntermConstantUnion * getAsConstantUnion()
Definition: intermediate.h:222
TLoopIndexInfo::initValue
int initValue
Definition: ForLoopUnroll.h:11
ASSERT
#define ASSERT(expression)
Definition: debug.h:36
ForLoopUnroll::GetLoopIndexValue
int GetLoopIndexValue(TIntermSymbol *symbol)
Definition: ForLoopUnroll.cpp:123
TIntermNode::traverse
virtual void traverse(TIntermTraverser *)=0
TIntermNode::getAsUnaryNode
virtual TIntermUnary * getAsUnaryNode()
Definition: intermediate.h:225
TIntermConstantUnion::getUnionArrayPointer
ConstantUnion * getUnionArrayPointer() const
Definition: intermediate.h:369
UNREACHABLE
#define UNREACHABLE()
Definition: debug.h:47
EOpPostIncrement
Definition: intermediate.h:47
EOpNull
Definition: intermediate.h:30
TIntermTraverser
Definition: intermediate.h:539
ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling
static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode *root)
Definition: ForLoopUnroll.cpp:146
TLoopIndexInfo::op
TOperator op
Definition: ForLoopUnroll.h:14
ForLoopUnroll.h
TLoopIndexInfo::id
int id
Definition: ForLoopUnroll.h:10
EOpLessThan
Definition: intermediate.h:71
TBasicType
TBasicType
Definition: BaseTypes.h:36
TIntermConstantUnion::getIConst
int getIConst(int index) const
Definition: intermediate.h:371
TLoopIndexInfo
Definition: ForLoopUnroll.h:9
EOpEqual
Definition: intermediate.h:67
TIntermTraverser::visitLoop
virtual bool visitLoop(Visit visit, TIntermLoop *)
Definition: intermediate.h:558
TIntermSymbol
Definition: intermediate.h:340
TIntermLoop
Definition: intermediate.h:284
ForLoopUnroll::Push
void Push(TLoopIndexInfo &info)
Definition: ForLoopUnroll.cpp:135
TIntermUnary
Definition: intermediate.h:431
TIntermLoop::getExpression
TIntermTyped * getExpression()
Definition: intermediate.h:302
TVector< TIntermNode * >
EOpPostDecrement
Definition: intermediate.h:48
TIntermNode
Definition: intermediate.h:206
ForLoopUnroll::Step
void Step()
Definition: ForLoopUnroll.cpp:81
EOpAddAssign
Definition: intermediate.h:180
TIntermLoop::setUnrollFlag
void setUnrollFlag(bool flag)
Definition: intermediate.h:305
i
int i
Definition: pngrutil.c:1377
ForLoopUnroll::SatisfiesLoopCondition
bool SatisfiesLoopCondition()
Definition: ForLoopUnroll.cpp:88
TIntermLoop::getInit
TIntermNode * getInit()
Definition: intermediate.h:300
EOpGreaterThanEqual
Definition: intermediate.h:74
EOpLessThanEqual
Definition: intermediate.h:73
EOpNotEqual
Definition: intermediate.h:68
EOpPreDecrement
Definition: intermediate.h:50
ForLoopUnroll::NeedsToReplaceSymbolWithValue
bool NeedsToReplaceSymbolWithValue(TIntermSymbol *symbol)
Definition: ForLoopUnroll.cpp:112
TIntermConstantUnion
Definition: intermediate.h:365
TIntermAggregate::getAsAggregate
virtual TIntermAggregate * getAsAggregate()
Definition: intermediate.h:466
TLoopIndexInfo::incrementValue
int incrementValue
Definition: ForLoopUnroll.h:13
EOpSubAssign
Definition: intermediate.h:181
TIntermLoop::getType
TLoopType getType() const
Definition: intermediate.h:299