blob: f3be20d9783b71846d67b282df6d897e3e0db9b6 [file] [log] [blame]
zmo@google.com0b8d4eb2011-04-04 19:17:11 +00001//
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
zmo@google.com0b8d4eb2011-04-04 19:17:11 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/ForLoopUnroll.h"
zmo@google.com0b8d4eb2011-04-04 19:17:11 +00008
Zhenyao Mo550c6002014-02-26 15:40:48 -08009bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
10{
11 if (mUnrollCondition != kSamplerArrayIndex)
zmo@google.com0c6bb7a2011-08-17 19:39:58 +000012 return true;
zmo@google.com0c6bb7a2011-08-17 19:39:58 +000013
Zhenyao Mo550c6002014-02-26 15:40:48 -080014 // 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;
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000033 default:
Zhenyao Mo550c6002014-02-26 15:40:48 -080034 break;
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000035 }
Zhenyao Mo550c6002014-02-26 15:40:48 -080036 return true;
37}
38
39bool 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().
Zhenyao Moe40d1e92014-07-16 17:40:36 -070046 TIntermSequence *declSeq = node->getInit()->getAsAggregate()->getSequence();
47 TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
Zhenyao Mo550c6002014-02-26 15:40:48 -080048 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.
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000060 return false;
61}
62
Zhenyao Mo550c6002014-02-26 15:40:48 -080063void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000064{
Zhenyao Mo550c6002014-02-26 15:40:48 -080065 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;
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000074 break;
Zhenyao Mo550c6002014-02-26 15:40:48 -080075 case EbtInt:
76 loop->setUnrollFlag(true);
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000077 break;
Zhenyao Mo550c6002014-02-26 15:40:48 -080078 default:
79 UNREACHABLE();
80 }
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000081 }
zmo@google.com0b8d4eb2011-04-04 19:17:11 +000082}