Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / compiler / translator / ForLoopUnroll.cpp
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/translator/ForLoopUnroll.h"
8
9 bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
10 {
11     if (mUnrollCondition != kSamplerArrayIndex)
12         return true;
13
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())
18     {
19       case EOpIndexIndirect:
20         if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode())
21         {
22             TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode();
23             if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty())
24             {
25                 mVisitSamplerArrayIndexNodeInsideLoop = true;
26                 node->getRight()->traverse(this);
27                 mVisitSamplerArrayIndexNodeInsideLoop = false;
28                 // We have already visited all the children.
29                 return false;
30             }
31         }
32         break;
33       default:
34         break;
35     }
36     return true;
37 }
38
39 bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
40 {
41     if (mUnrollCondition == kIntegerIndex)
42     {
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);
50     }
51
52     TIntermNode *body = node->getBody();
53     if (body != NULL)
54     {
55         mLoopStack.push(node);
56         body->traverse(this);
57         mLoopStack.pop();
58     }
59     // The loop is fully processed - no need to visit children.
60     return false;
61 }
62
63 void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
64 {
65     if (!mVisitSamplerArrayIndexNodeInsideLoop)
66         return;
67     TIntermLoop *loop = mLoopStack.findLoop(symbol);
68     if (loop)
69     {
70         switch (symbol->getBasicType())
71         {
72           case EbtFloat:
73             mSamplerArrayIndexIsFloatLoopIndex = true;
74             break;
75           case EbtInt:
76             loop->setUnrollFlag(true);
77             break;
78           default:
79             UNREACHABLE();
80         }
81     }
82 }