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.
7 #include "compiler/translator/ForLoopUnroll.h"
9 bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
11 if (mUnrollCondition != kSamplerArrayIndex)
14 // If a sampler array index is also the loop index,
15 // 1) if the index type is integer, mark the loop for unrolling;
16 // 2) if the index type if float, set a flag to later fail compile.
17 switch (node->getOp())
19 case EOpIndexIndirect:
20 if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode())
22 TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode();
23 if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty())
25 mVisitSamplerArrayIndexNodeInsideLoop = true;
26 node->getRight()->traverse(this);
27 mVisitSamplerArrayIndexNodeInsideLoop = false;
28 // We have already visited all the children.
39 bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
41 if (mUnrollCondition == kIntegerIndex)
43 // Check if loop index type is integer.
44 // This is called after ValidateLimitations pass, so all the calls
45 // should be valid. See ValidateLimitations::validateForLoopInit().
46 TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence();
47 TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
48 if (symbol->getBasicType() == EbtInt)
49 node->setUnrollFlag(true);
52 TIntermNode *body = node->getBody();
55 mLoopStack.push(node);
59 // The loop is fully processed - no need to visit children.
63 void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
65 if (!mVisitSamplerArrayIndexNodeInsideLoop)
67 TIntermLoop *loop = mLoopStack.findLoop(symbol);
70 switch (symbol->getBasicType())
73 mSamplerArrayIndexIsFloatLoopIndex = true;
76 loop->setUnrollFlag(true);