Commit 3fed4306 by Olli Etuaho

Unfold short-circuiting operators in loop conditions correctly

Sometimes short-circuiting operators need to be unfolded to if statements. If the unfolded operator is inside a loop condition or expression, it needs to be evaluated repeatedly inside the loop. Add logic to UnfoldShortCircuitToIf that can move or copy the unfolded part of loop conditions or expressions to inside the loop. The exact changes that need to be done depend on the type of the loop. For loops may require also moving the initializer to outside the loop. The unfolded expression inside a loop condition or expression is moved or copied to inside the loop on the first traversal of the loop node, and unfolding to if is deferred until a second traversal. This keeps the code relatively simple. BUG=angleproject:1167 TEST=WebGL 2 conformance tests, dEQP-GLES2.functional.shaders.*select_iteration_count* Change-Id: Ieffc0ea858186054378d387dca9aa64a5fa95137 Reviewed-on: https://chromium-review.googlesource.com/310230Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 15c2ac30
...@@ -261,7 +261,7 @@ bool TIntermLoop::replaceChildNode( ...@@ -261,7 +261,7 @@ bool TIntermLoop::replaceChildNode(
REPLACE_IF_IS(mInit, TIntermNode, original, replacement); REPLACE_IF_IS(mInit, TIntermNode, original, replacement);
REPLACE_IF_IS(mCond, TIntermTyped, original, replacement); REPLACE_IF_IS(mCond, TIntermTyped, original, replacement);
REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement); REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement);
REPLACE_IF_IS(mBody, TIntermNode, original, replacement); REPLACE_IF_IS(mBody, TIntermAggregate, original, replacement);
return false; return false;
} }
......
...@@ -173,14 +173,13 @@ class TIntermLoop : public TIntermNode ...@@ -173,14 +173,13 @@ class TIntermLoop : public TIntermNode
{ {
public: public:
TIntermLoop(TLoopType type, TIntermLoop(TLoopType type,
TIntermNode *init, TIntermTyped *cond, TIntermTyped *expr, TIntermNode *init,
TIntermNode *body) TIntermTyped *cond,
: mType(type), TIntermTyped *expr,
mInit(init), TIntermAggregate *body)
mCond(cond), : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body), mUnrollFlag(false)
mExpr(expr), {
mBody(body), }
mUnrollFlag(false) { }
TIntermLoop *getAsLoopNode() override { return this; } TIntermLoop *getAsLoopNode() override { return this; }
void traverse(TIntermTraverser *it) override; void traverse(TIntermTraverser *it) override;
...@@ -190,7 +189,7 @@ class TIntermLoop : public TIntermNode ...@@ -190,7 +189,7 @@ class TIntermLoop : public TIntermNode
TIntermNode *getInit() { return mInit; } TIntermNode *getInit() { return mInit; }
TIntermTyped *getCondition() { return mCond; } TIntermTyped *getCondition() { return mCond; }
TIntermTyped *getExpression() { return mExpr; } TIntermTyped *getExpression() { return mExpr; }
TIntermNode *getBody() { return mBody; } TIntermAggregate *getBody() { return mBody; }
void setUnrollFlag(bool flag) { mUnrollFlag = flag; } void setUnrollFlag(bool flag) { mUnrollFlag = flag; }
bool getUnrollFlag() const { return mUnrollFlag; } bool getUnrollFlag() const { return mUnrollFlag; }
...@@ -200,7 +199,7 @@ class TIntermLoop : public TIntermNode ...@@ -200,7 +199,7 @@ class TIntermLoop : public TIntermNode
TIntermNode *mInit; // for-loop initialization TIntermNode *mInit; // for-loop initialization
TIntermTyped *mCond; // loop exit condition TIntermTyped *mCond; // loop exit condition
TIntermTyped *mExpr; // for-loop expression TIntermTyped *mExpr; // for-loop expression
TIntermNode *mBody; // loop body TIntermAggregate *mBody; // loop body
bool mUnrollFlag; // Whether the loop should be unrolled or not. bool mUnrollFlag; // Whether the loop should be unrolled or not.
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment