translator: remove code related to for-loop unrolling
For loop unrolling is not used and causes the translator fuzzer to find
a hang when unrolling tons of nested loops (duh).
Also remove MMap.h which was unused.
This is essentially a revert of https://codereview.appspot.com/4331048
BUG=chromium:665255
Change-Id: Id6940f7e306d4ed53bc992f751e9ffe733190f17
Reviewed-on: https://chromium-review.googlesource.com/412023
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index de9d98f..e49196d 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -16,7 +16,6 @@
#include "compiler/translator/DeferGlobalInitializers.h"
#include "compiler/translator/EmulateGLFragColorBroadcast.h"
#include "compiler/translator/EmulatePrecision.h"
-#include "compiler/translator/ForLoopUnroll.h"
#include "compiler/translator/Initialize.h"
#include "compiler/translator/InitializeParseContext.h"
#include "compiler/translator/InitializeVariables.h"
@@ -370,26 +369,6 @@
}
}
- // Unroll for-loop markup needs to happen after validateLimitations pass.
- if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
- {
- ForLoopUnrollMarker marker(ForLoopUnrollMarker::kIntegerIndex,
- shouldRunLoopAndIndexingValidation(compileOptions));
- root->traverse(&marker);
- }
- if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX))
- {
- ForLoopUnrollMarker marker(ForLoopUnrollMarker::kSamplerArrayIndex,
- shouldRunLoopAndIndexingValidation(compileOptions));
- root->traverse(&marker);
- if (marker.samplerArrayIndexIsFloatLoopIndex())
- {
- infoSink.info.prefix(EPrefixError);
- infoSink.info << "sampler array index is float loop index";
- success = false;
- }
- }
-
// Built-in function emulation needs to happen after validateLimitations pass.
if (success)
{
@@ -506,17 +485,6 @@
compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL;
}
- ShCompileOptions unrollFlags =
- SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX | SH_UNROLL_FOR_LOOP_WITH_SAMPLER_ARRAY_INDEX;
- if ((compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION) != 0 &&
- (compileOptions & unrollFlags) != 0)
- {
- infoSink.info.prefix(EPrefixError);
- infoSink.info
- << "Unsupported compile flag combination: unroll & ADD_TRUE_TO_LOOP_CONDITION";
- return false;
- }
-
TScopedPoolAllocator scopedAlloc(&allocator);
TIntermBlock *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
diff --git a/src/compiler/translator/ForLoopUnroll.cpp b/src/compiler/translator/ForLoopUnroll.cpp
deleted file mode 100644
index 58cce84..0000000
--- a/src/compiler/translator/ForLoopUnroll.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//
-// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/ForLoopUnroll.h"
-
-#include "compiler/translator/ValidateLimitations.h"
-#include "angle_gl.h"
-
-namespace sh
-{
-
-bool ForLoopUnrollMarker::visitBinary(Visit, TIntermBinary *node)
-{
- if (mUnrollCondition != kSamplerArrayIndex)
- return true;
-
- // If a sampler array index is also the loop index,
- // 1) if the index type is integer, mark the loop for unrolling;
- // 2) if the index type if float, set a flag to later fail compile.
- switch (node->getOp())
- {
- case EOpIndexIndirect:
- if (node->getLeft() != NULL && node->getRight() != NULL && node->getLeft()->getAsSymbolNode())
- {
- TIntermSymbol *symbol = node->getLeft()->getAsSymbolNode();
- if (IsSampler(symbol->getBasicType()) && symbol->isArray() && !mLoopStack.empty())
- {
- mVisitSamplerArrayIndexNodeInsideLoop = true;
- node->getRight()->traverse(this);
- mVisitSamplerArrayIndexNodeInsideLoop = false;
- // We have already visited all the children.
- return false;
- }
- }
- break;
- default:
- break;
- }
- return true;
-}
-
-bool ForLoopUnrollMarker::visitLoop(Visit, TIntermLoop *node)
-{
- bool canBeUnrolled = mHasRunLoopValidation;
- if (!mHasRunLoopValidation)
- {
- canBeUnrolled = ValidateLimitations::IsLimitedForLoop(node);
- }
- if (mUnrollCondition == kIntegerIndex && canBeUnrolled)
- {
- // Check if loop index type is integer.
- // This is called after ValidateLimitations pass, so the loop has the limited form specified
- // in ESSL 1.00 appendix A.
- TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
- TIntermSymbol *symbol = (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
- if (symbol->getBasicType() == EbtInt)
- node->setUnrollFlag(true);
- }
-
- TIntermNode *body = node->getBody();
- if (body != nullptr)
- {
- if (canBeUnrolled)
- {
- mLoopStack.push(node);
- body->traverse(this);
- mLoopStack.pop();
- }
- else
- {
- body->traverse(this);
- }
- }
- // The loop is fully processed - no need to visit children.
- return false;
-}
-
-void ForLoopUnrollMarker::visitSymbol(TIntermSymbol* symbol)
-{
- if (!mVisitSamplerArrayIndexNodeInsideLoop)
- return;
- TIntermLoop *loop = mLoopStack.findLoop(symbol);
- if (loop)
- {
- switch (symbol->getBasicType())
- {
- case EbtFloat:
- mSamplerArrayIndexIsFloatLoopIndex = true;
- break;
- case EbtInt:
- loop->setUnrollFlag(true);
- break;
- default:
- UNREACHABLE();
- }
- }
-}
-
-} // namespace sh
diff --git a/src/compiler/translator/ForLoopUnroll.h b/src/compiler/translator/ForLoopUnroll.h
deleted file mode 100644
index cda89b2..0000000
--- a/src/compiler/translator/ForLoopUnroll.h
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
-#define COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
-
-#include "compiler/translator/LoopInfo.h"
-
-namespace sh
-{
-
-// This class detects for-loops that needs to be unrolled.
-// Currently we support two unroll conditions:
-// 1) kForLoopWithIntegerIndex: unroll if the index type is integer.
-// 2) kForLoopWithSamplerArrayIndex: unroll where a sampler array index
-// is also the loop integer index, and reject and fail a compile
-// where a sampler array index is also the loop float index.
-class ForLoopUnrollMarker : public TIntermTraverser
-{
- public:
- enum UnrollCondition
- {
- kIntegerIndex,
- kSamplerArrayIndex
- };
-
- ForLoopUnrollMarker(UnrollCondition condition, bool hasRunLoopValidation)
- : TIntermTraverser(true, false, false),
- mUnrollCondition(condition),
- mSamplerArrayIndexIsFloatLoopIndex(false),
- mVisitSamplerArrayIndexNodeInsideLoop(false),
- mHasRunLoopValidation(hasRunLoopValidation)
- {
- }
-
- bool visitBinary(Visit, TIntermBinary *node) override;
- bool visitLoop(Visit, TIntermLoop *node) override;
- void visitSymbol(TIntermSymbol *node) override;
-
- bool samplerArrayIndexIsFloatLoopIndex() const
- {
- return mSamplerArrayIndexIsFloatLoopIndex;
- }
-
- private:
- UnrollCondition mUnrollCondition;
- TLoopStack mLoopStack;
- bool mSamplerArrayIndexIsFloatLoopIndex;
- bool mVisitSamplerArrayIndexNodeInsideLoop;
- bool mHasRunLoopValidation;
-};
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_FORLOOPUNROLL_H_
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index 94811bd..50b6ff0 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -201,7 +201,7 @@
TIntermTyped *cond,
TIntermTyped *expr,
TIntermBlock *body)
- : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body), mUnrollFlag(false)
+ : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body)
{
}
@@ -219,17 +219,12 @@
void setExpression(TIntermTyped *expression) { mExpr = expression; }
void setBody(TIntermBlock *body) { mBody = body; }
- void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
- bool getUnrollFlag() const { return mUnrollFlag; }
-
protected:
TLoopType mType;
TIntermNode *mInit; // for-loop initialization
TIntermTyped *mCond; // loop exit condition
TIntermTyped *mExpr; // for-loop expression
TIntermBlock *mBody; // loop body
-
- bool mUnrollFlag; // Whether the loop should be unrolled or not.
};
//
diff --git a/src/compiler/translator/LoopInfo.cpp b/src/compiler/translator/LoopInfo.cpp
deleted file mode 100644
index 48fa244..0000000
--- a/src/compiler/translator/LoopInfo.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#include "compiler/translator/LoopInfo.h"
-
-namespace sh
-{
-
-namespace
-{
-
-int EvaluateIntConstant(TIntermConstantUnion *node)
-{
- ASSERT(node && node->getUnionArrayPointer());
- return node->getIConst(0);
-}
-
-int GetLoopIntIncrement(TIntermLoop *node)
-{
- TIntermNode *expr = node->getExpression();
- // for expression has one of the following forms:
- // loop_index++
- // loop_index--
- // loop_index += constant_expression
- // loop_index -= constant_expression
- // ++loop_index
- // --loop_index
- // The last two forms are not specified in the spec, but I am assuming
- // its an oversight.
- TIntermUnary *unOp = expr->getAsUnaryNode();
- TIntermBinary *binOp = unOp ? NULL : expr->getAsBinaryNode();
-
- TOperator op = EOpNull;
- TIntermConstantUnion *incrementNode = NULL;
- if (unOp)
- {
- op = unOp->getOp();
- }
- else if (binOp)
- {
- op = binOp->getOp();
- ASSERT(binOp->getRight());
- incrementNode = binOp->getRight()->getAsConstantUnion();
- ASSERT(incrementNode);
- }
-
- int increment = 0;
- // The operator is one of: ++ -- += -=.
- switch (op)
- {
- case EOpPostIncrement:
- case EOpPreIncrement:
- ASSERT(unOp && !binOp);
- increment = 1;
- break;
- case EOpPostDecrement:
- case EOpPreDecrement:
- ASSERT(unOp && !binOp);
- increment = -1;
- break;
- case EOpAddAssign:
- ASSERT(!unOp && binOp);
- increment = EvaluateIntConstant(incrementNode);
- break;
- case EOpSubAssign:
- ASSERT(!unOp && binOp);
- increment = - EvaluateIntConstant(incrementNode);
- break;
- default:
- UNREACHABLE();
- }
-
- return increment;
-}
-
-} // namespace anonymous
-
-TLoopIndexInfo::TLoopIndexInfo()
- : mId(-1),
- mType(EbtVoid),
- mInitValue(0),
- mStopValue(0),
- mIncrementValue(0),
- mOp(EOpNull),
- mCurrentValue(0)
-{
-}
-
-void TLoopIndexInfo::fillInfo(TIntermLoop *node)
-{
- if (node == NULL)
- return;
-
- // Here we assume all the operations are valid, because the loop node is
- // already validated in ValidateLimitations.
- TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
- TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
- TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
-
- mId = symbol->getId();
- mType = symbol->getBasicType();
-
- if (mType == EbtInt)
- {
- TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion();
- mInitValue = EvaluateIntConstant(initNode);
- mCurrentValue = mInitValue;
- mIncrementValue = GetLoopIntIncrement(node);
-
- TIntermBinary* binOp = node->getCondition()->getAsBinaryNode();
- mStopValue = EvaluateIntConstant(
- binOp->getRight()->getAsConstantUnion());
- mOp = binOp->getOp();
- }
-}
-
-bool TLoopIndexInfo::satisfiesLoopCondition() const
-{
- // Relational operator is one of: > >= < <= == or !=.
- switch (mOp)
- {
- case EOpEqual:
- return (mCurrentValue == mStopValue);
- case EOpNotEqual:
- return (mCurrentValue != mStopValue);
- case EOpLessThan:
- return (mCurrentValue < mStopValue);
- case EOpGreaterThan:
- return (mCurrentValue > mStopValue);
- case EOpLessThanEqual:
- return (mCurrentValue <= mStopValue);
- case EOpGreaterThanEqual:
- return (mCurrentValue >= mStopValue);
- default:
- UNREACHABLE();
- return false;
- }
-}
-
-TLoopInfo::TLoopInfo()
- : loop(NULL)
-{
-}
-
-TLoopInfo::TLoopInfo(TIntermLoop *node)
- : loop(node)
-{
- index.fillInfo(node);
-}
-
-TIntermLoop *TLoopStack::findLoop(TIntermSymbol *symbol)
-{
- if (!symbol)
- return NULL;
- for (iterator iter = begin(); iter != end(); ++iter)
- {
- if (iter->index.getId() == symbol->getId())
- return iter->loop;
- }
- return NULL;
-}
-
-TLoopIndexInfo *TLoopStack::getIndexInfo(TIntermSymbol *symbol)
-{
- if (!symbol)
- return NULL;
- for (iterator iter = begin(); iter != end(); ++iter)
- {
- if (iter->index.getId() == symbol->getId())
- return &(iter->index);
- }
- return NULL;
-}
-
-void TLoopStack::step()
-{
- ASSERT(!empty());
- rbegin()->index.step();
-}
-
-bool TLoopStack::satisfiesLoopCondition()
-{
- ASSERT(!empty());
- return rbegin()->index.satisfiesLoopCondition();
-}
-
-bool TLoopStack::needsToReplaceSymbolWithValue(TIntermSymbol *symbol)
-{
- TIntermLoop *loop = findLoop(symbol);
- return loop && loop->getUnrollFlag();
-}
-
-int TLoopStack::getLoopIndexValue(TIntermSymbol *symbol)
-{
- TLoopIndexInfo *info = getIndexInfo(symbol);
- ASSERT(info);
- return info->getCurrentValue();
-}
-
-void TLoopStack::push(TIntermLoop *loop)
-{
- TLoopInfo info(loop);
- push_back(info);
-}
-
-void TLoopStack::pop()
-{
- pop_back();
-}
-
-} // namespace sh
diff --git a/src/compiler/translator/LoopInfo.h b/src/compiler/translator/LoopInfo.h
deleted file mode 100644
index 393aa64..0000000
--- a/src/compiler/translator/LoopInfo.h
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef COMPILER_TRANSLATOR_LOOPINFO_H_
-#define COMPILER_TRANSLATOR_LOOPINFO_H_
-
-#include "compiler/translator/IntermNode.h"
-
-namespace sh
-{
-
-class TLoopIndexInfo
-{
- public:
- TLoopIndexInfo();
-
- // If type is EbtInt, fill all fields of the structure with info
- // extracted from a loop node.
- // If type is not EbtInt, only fill id and type.
- void fillInfo(TIntermLoop *node);
-
- int getId() const { return mId; }
- void setId(int id) { mId = id; }
- TBasicType getType() const { return mType; }
- void setType(TBasicType type) { mType = type; }
- int getCurrentValue() const { return mCurrentValue; }
-
- void step() { mCurrentValue += mIncrementValue; }
-
- // Check if the current value satisfies the loop condition.
- bool satisfiesLoopCondition() const;
-
- private:
- int mId;
- TBasicType mType; // Either EbtInt or EbtFloat
-
- // Below fields are only valid if the index's type is int.
- int mInitValue;
- int mStopValue;
- int mIncrementValue;
- TOperator mOp;
- int mCurrentValue;
-};
-
-struct TLoopInfo
-{
- TLoopIndexInfo index;
- TIntermLoop *loop;
-
- TLoopInfo();
- TLoopInfo(TIntermLoop *node);
-};
-
-class TLoopStack : public TVector<TLoopInfo>
-{
- public:
- // Search loop stack for a loop whose index matches the input symbol.
- TIntermLoop *findLoop(TIntermSymbol *symbol);
-
- // Find the loop index info in the loop stack by the input symbol.
- TLoopIndexInfo *getIndexInfo(TIntermSymbol *symbol);
-
- // Update the currentValue for the next loop iteration.
- void step();
-
- // Return false if loop condition is no longer satisfied.
- bool satisfiesLoopCondition();
-
- // Check if the symbol is the index of a loop that's unrolled.
- bool needsToReplaceSymbolWithValue(TIntermSymbol *symbol);
-
- // Return the current value of a given loop index symbol.
- int getLoopIndexValue(TIntermSymbol *symbol);
-
- void push(TIntermLoop *info);
- void pop();
-};
-
-} // namespace sh
-
-#endif // COMPILER_TRANSLATOR_LOOPINFO_H_
-
diff --git a/src/compiler/translator/MMap.h b/src/compiler/translator/MMap.h
deleted file mode 100644
index fca8439..0000000
--- a/src/compiler/translator/MMap.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef COMPILER_TRANSLATOR_MMAP_H_
-#define COMPILER_TRANSLATOR_MMAP_H_
-
-//
-// Encapsulate memory mapped files
-//
-
-class TMMap {
-public:
- TMMap(const char* fileName) :
- fSize(-1), // -1 is the error value returned by GetFileSize()
- fp(NULL),
- fBuff(0) // 0 is the error value returned by MapViewOfFile()
- {
- if ((fp = fopen(fileName, "r")) == NULL)
- return;
- char c = getc(fp);
- fSize = 0;
- while (c != EOF) {
- fSize++;
- c = getc(fp);
- }
- if (c == EOF)
- fSize++;
- rewind(fp);
- fBuff = (char*)malloc(sizeof(char) * fSize);
- int count = 0;
- c = getc(fp);
- while (c != EOF) {
- fBuff[count++] = c;
- c = getc(fp);
- }
- fBuff[count++] = c;
- }
-
- char* getData() { return fBuff; }
- int getSize() { return fSize; }
-
- ~TMMap() {
- if (fp != NULL)
- fclose(fp);
- }
-
-private:
- int fSize; // size of file to map in
- FILE *fp;
- char* fBuff; // the actual data;
-};
-
-#endif // COMPILER_TRANSLATOR_MMAP_H_
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 2c32b2e..6860edc 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -376,10 +376,7 @@
void TOutputGLSLBase::visitSymbol(TIntermSymbol *node)
{
TInfoSinkBase &out = objSink();
- if (mLoopUnrollStack.needsToReplaceSymbolWithValue(node))
- out << mLoopUnrollStack.getLoopIndexValue(node);
- else
- out << hashVariableName(node->getName());
+ out << hashVariableName(node->getName());
if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType());
@@ -1124,49 +1121,22 @@
TLoopType loopType = node->getType();
- // Only for loops can be unrolled
- ASSERT(!node->getUnrollFlag() || loopType == ELoopFor);
-
if (loopType == ELoopFor) // for loop
{
- if (!node->getUnrollFlag())
- {
- out << "for (";
- if (node->getInit())
- node->getInit()->traverse(this);
- out << "; ";
+ out << "for (";
+ if (node->getInit())
+ node->getInit()->traverse(this);
+ out << "; ";
- if (node->getCondition())
- node->getCondition()->traverse(this);
- out << "; ";
+ if (node->getCondition())
+ node->getCondition()->traverse(this);
+ out << "; ";
- if (node->getExpression())
- node->getExpression()->traverse(this);
- out << ")\n";
+ if (node->getExpression())
+ node->getExpression()->traverse(this);
+ out << ")\n";
- visitCodeBlock(node->getBody());
- }
- else
- {
- // Need to put a one-iteration loop here to handle break.
- TIntermSequence *declSeq = node->getInit()->getAsDeclarationNode()->getSequence();
- TIntermSymbol *indexSymbol =
- (*declSeq)[0]->getAsBinaryNode()->getLeft()->getAsSymbolNode();
- TString name = hashVariableName(indexSymbol->getName());
- out << "for (int " << name << " = 0; "
- << name << " < 1; "
- << "++" << name << ")\n";
-
- out << "{\n";
- mLoopUnrollStack.push(node);
- while (mLoopUnrollStack.satisfiesLoopCondition())
- {
- visitCodeBlock(node->getBody());
- mLoopUnrollStack.step();
- }
- mLoopUnrollStack.pop();
- out << "}\n";
- }
+ visitCodeBlock(node->getBody());
}
else if (loopType == ELoopWhile) // while loop
{
diff --git a/src/compiler/translator/OutputGLSLBase.h b/src/compiler/translator/OutputGLSLBase.h
index ede4c49..e4db93b 100644
--- a/src/compiler/translator/OutputGLSLBase.h
+++ b/src/compiler/translator/OutputGLSLBase.h
@@ -10,7 +10,6 @@
#include <set>
#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/LoopInfo.h"
#include "compiler/translator/ParseContext.h"
namespace sh
@@ -91,9 +90,6 @@
// This set contains all the ids of the structs from every scope.
std::set<int> mDeclaredStructs;
- // Stack of loops that need to be unrolled.
- TLoopStack mLoopUnrollStack;
-
ShArrayIndexClampingStrategy mClampingStrategy;
// name hashing.
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index 75a0c51..29f1aa3 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -16,6 +16,17 @@
namespace
{
+int GetLoopSymbolId(TIntermLoop *loop)
+{
+ // Here we assume all the operations are valid, because the loop node is
+ // already validated before this call.
+ TIntermSequence *declSeq = loop->getInit()->getAsDeclarationNode()->getSequence();
+ TIntermBinary *declInit = (*declSeq)[0]->getAsBinaryNode();
+ TIntermSymbol *symbol = declInit->getLeft()->getAsSymbolNode();
+
+ return symbol->getId();
+}
+
// Traverses a node to check if it represents a constant index expression.
// Definition:
// constant-index-expressions are a superset of constant-expressions.
@@ -28,10 +39,8 @@
class ValidateConstIndexExpr : public TIntermTraverser
{
public:
- ValidateConstIndexExpr(TLoopStack& stack)
- : TIntermTraverser(true, false, false),
- mValid(true),
- mLoopStack(stack)
+ ValidateConstIndexExpr(const std::vector<int> &loopSymbols)
+ : TIntermTraverser(true, false, false), mValid(true), mLoopSymbolIds(loopSymbols)
{
}
@@ -44,14 +53,15 @@
// constant index expression.
if (mValid)
{
- mValid = (symbol->getQualifier() == EvqConst) ||
- (mLoopStack.findLoop(symbol));
+ bool isLoopSymbol = std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(),
+ symbol->getId()) != mLoopSymbolIds.end();
+ mValid = (symbol->getQualifier() == EvqConst) || isLoopSymbol;
}
}
private:
bool mValid;
- TLoopStack& mLoopStack;
+ const std::vector<int> mLoopSymbolIds;
};
} // namespace anonymous
@@ -80,9 +90,9 @@
TIntermNode *body = loop->getBody();
if (body != nullptr)
{
- validate.mLoopStack.push(loop);
+ validate.mLoopSymbolIds.push_back(GetLoopSymbolId(loop));
body->traverse(&validate);
- validate.mLoopStack.pop();
+ validate.mLoopSymbolIds.pop_back();
}
return (validate.mNumErrors == 0);
}
@@ -140,9 +150,9 @@
TIntermNode *body = node->getBody();
if (body != NULL)
{
- mLoopStack.push(node);
+ mLoopSymbolIds.push_back(GetLoopSymbolId(node));
body->traverse(this);
- mLoopStack.pop();
+ mLoopSymbolIds.pop_back();
}
// The loop is fully processed - no need to visit children.
@@ -163,12 +173,13 @@
bool ValidateLimitations::withinLoopBody() const
{
- return !mLoopStack.empty();
+ return !mLoopSymbolIds.empty();
}
bool ValidateLimitations::isLoopIndex(TIntermSymbol *symbol)
{
- return mLoopStack.findLoop(symbol) != NULL;
+ return std::find(mLoopSymbolIds.begin(), mLoopSymbolIds.end(), symbol->getId()) !=
+ mLoopSymbolIds.end();
}
bool ValidateLimitations::validateLoopType(TIntermLoop *node)
@@ -474,7 +485,7 @@
{
ASSERT(node != NULL);
- ValidateConstIndexExpr validate(mLoopStack);
+ ValidateConstIndexExpr validate(mLoopSymbolIds);
node->traverse(&validate);
return validate.isValid();
}
diff --git a/src/compiler/translator/ValidateLimitations.h b/src/compiler/translator/ValidateLimitations.h
index 4c84f9d..63db402 100644
--- a/src/compiler/translator/ValidateLimitations.h
+++ b/src/compiler/translator/ValidateLimitations.h
@@ -8,7 +8,6 @@
#define COMPILER_TRANSLATOR_VALIDATELIMITATIONS_H_
#include "compiler/translator/IntermNode.h"
-#include "compiler/translator/LoopInfo.h"
namespace sh
{
@@ -58,7 +57,7 @@
sh::GLenum mShaderType;
TInfoSinkBase *mSink;
int mNumErrors;
- TLoopStack mLoopStack;
+ std::vector<int> mLoopSymbolIds;
bool mValidateIndexing;
bool mValidateInnerLoops;
};