Add an compile option to unroll for-loops with integer indices.
ANGLEBUG=193
TEST=with this option, for-loops with integer indices will be unrolled.
Review URL: http://codereview.appspot.com/4899047
git-svn-id: https://angleproject.googlecode.com/svn/trunk@734 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 16b7bd9..eafe70a 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -5,6 +5,7 @@
//
#include "compiler/DetectRecursion.h"
+#include "compiler/ForLoopUnroll.h"
#include "compiler/Initialize.h"
#include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h"
@@ -155,6 +156,10 @@
if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
success = validateLimitations(root);
+ // Unroll for-loop markup needs to happen after validateLimitations pass.
+ if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
+ ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
+
// Call mapLongVariableNames() before collectAttribsUniforms() so in
// collectAttribsUniforms() we already have the mapped symbol names and
// we could composite mapped and original variable names.
diff --git a/src/compiler/ForLoopUnroll.cpp b/src/compiler/ForLoopUnroll.cpp
index d631af4..fdc3f44 100644
--- a/src/compiler/ForLoopUnroll.cpp
+++ b/src/compiler/ForLoopUnroll.cpp
@@ -6,6 +6,39 @@
#include "compiler/ForLoopUnroll.h"
+namespace {
+
+class IntegerForLoopUnrollMarker : public TIntermTraverser {
+public:
+
+ virtual bool visitLoop(Visit, TIntermLoop* node)
+ {
+ // This is called after ValidateLimitations pass, so all the ASSERT
+ // should never fail.
+ // See ValidateLimitations::validateForLoopInit().
+ ASSERT(node);
+ ASSERT(node->getType() == ELoopFor);
+ ASSERT(node->getInit());
+ TIntermAggregate* decl = node->getInit()->getAsAggregate();
+ ASSERT(decl && decl->getOp() == EOpDeclaration);
+ TIntermSequence& declSeq = decl->getSequence();
+ ASSERT(declSeq.size() == 1);
+ TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
+ ASSERT(declInit && declInit->getOp() == EOpInitialize);
+ ASSERT(declInit->getLeft());
+ TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
+ ASSERT(symbol);
+ TBasicType type = symbol->getBasicType();
+ ASSERT(type == EbtInt || type == EbtFloat);
+ if (type == EbtInt)
+ node->setUnrollFlag(true);
+ return true;
+ }
+
+};
+
+} // anonymous namepsace
+
void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info)
{
ASSERT(node->getType() == ELoopFor);
@@ -109,6 +142,16 @@
mLoopIndexStack.pop_back();
}
+// static
+void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(
+ TIntermNode* root)
+{
+ ASSERT(root);
+
+ IntegerForLoopUnrollMarker marker;
+ root->traverse(&marker);
+}
+
int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
{
TIntermNode* expr = node->getExpression();
diff --git a/src/compiler/ForLoopUnroll.h b/src/compiler/ForLoopUnroll.h
index b2b2b58..e800e25 100644
--- a/src/compiler/ForLoopUnroll.h
+++ b/src/compiler/ForLoopUnroll.h
@@ -36,6 +36,8 @@
void Push(TLoopIndexInfo& info);
void Pop();
+ static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode* root);
+
private:
int getLoopIncrement(TIntermLoop* node);