Commit 1212bcac by Corentin Wallez Committed by Commit Bot

translator: separate declarations after rewriting loops

Otherwise when trying to add the declarations back, things might fail because the loop initialization is a sequence and not a block. BUG=668028 Change-Id: I8d84a25c25765e9655c16ce56604ae08f0f8176c Reviewed-on: https://chromium-review.googlesource.com/414305 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent 00cf8940
...@@ -106,4 +106,13 @@ bool IntermNodePatternMatcher::match(TIntermTernary *node) ...@@ -106,4 +106,13 @@ bool IntermNodePatternMatcher::match(TIntermTernary *node)
return false; return false;
} }
bool IntermNodePatternMatcher::match(TIntermDeclaration *node)
{
if ((mMask & kMultiDeclaration) != 0)
{
return node->getSequence()->size() > 1;
}
return false;
}
} // namespace sh } // namespace sh
...@@ -18,6 +18,7 @@ class TIntermAggregate; ...@@ -18,6 +18,7 @@ class TIntermAggregate;
class TIntermBinary; class TIntermBinary;
class TIntermNode; class TIntermNode;
class TIntermTernary; class TIntermTernary;
class TIntermDeclaration;
class IntermNodePatternMatcher class IntermNodePatternMatcher
{ {
...@@ -34,7 +35,10 @@ class IntermNodePatternMatcher ...@@ -34,7 +35,10 @@ class IntermNodePatternMatcher
kExpressionReturningArray = 0x0002, kExpressionReturningArray = 0x0002,
// Matches dynamic indexing of vectors or matrices in l-values. // Matches dynamic indexing of vectors or matrices in l-values.
kDynamicIndexingOfVectorOrMatrixInLValue = 0x0004 kDynamicIndexingOfVectorOrMatrixInLValue = 0x0004,
// Matches declarations with more than one declared variables
kMultiDeclaration = 0x0008,
}; };
IntermNodePatternMatcher(const unsigned int mask); IntermNodePatternMatcher(const unsigned int mask);
...@@ -46,6 +50,7 @@ class IntermNodePatternMatcher ...@@ -46,6 +50,7 @@ class IntermNodePatternMatcher
bool match(TIntermAggregate *node, TIntermNode *parentNode); bool match(TIntermAggregate *node, TIntermNode *parentNode);
bool match(TIntermTernary *node); bool match(TIntermTernary *node);
bool match(TIntermDeclaration *node);
private: private:
const unsigned int mMask; const unsigned int mMask;
......
...@@ -40,6 +40,7 @@ class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser ...@@ -40,6 +40,7 @@ class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitBinary(Visit visit, TIntermBinary *node) override;
bool visitAggregate(Visit visit, TIntermAggregate *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override;
bool visitTernary(Visit visit, TIntermTernary *node) override; bool visitTernary(Visit visit, TIntermTernary *node) override;
bool visitDeclaration(Visit visit, TIntermDeclaration *node) override;
void nextIteration(); void nextIteration();
bool foundLoopToChange() const { return mFoundLoopToChange; } bool foundLoopToChange() const { return mFoundLoopToChange; }
...@@ -48,7 +49,7 @@ class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser ...@@ -48,7 +49,7 @@ class SimplifyLoopConditionsTraverser : public TLValueTrackingTraverser
// Marked to true once an operation that needs to be hoisted out of the expression has been // Marked to true once an operation that needs to be hoisted out of the expression has been
// found. After that, no more AST updates are performed on that traversal. // found. After that, no more AST updates are performed on that traversal.
bool mFoundLoopToChange; bool mFoundLoopToChange;
bool mInsideLoopConditionOrExpression; bool mInsideLoopInitConditionOrExpression;
IntermNodePatternMatcher mConditionsToSimplify; IntermNodePatternMatcher mConditionsToSimplify;
}; };
...@@ -58,7 +59,7 @@ SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser( ...@@ -58,7 +59,7 @@ SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser(
int shaderVersion) int shaderVersion)
: TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion), : TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion),
mFoundLoopToChange(false), mFoundLoopToChange(false),
mInsideLoopConditionOrExpression(false), mInsideLoopInitConditionOrExpression(false),
mConditionsToSimplify(conditionsToSimplifyMask) mConditionsToSimplify(conditionsToSimplifyMask)
{ {
} }
...@@ -66,24 +67,25 @@ SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser( ...@@ -66,24 +67,25 @@ SimplifyLoopConditionsTraverser::SimplifyLoopConditionsTraverser(
void SimplifyLoopConditionsTraverser::nextIteration() void SimplifyLoopConditionsTraverser::nextIteration()
{ {
mFoundLoopToChange = false; mFoundLoopToChange = false;
mInsideLoopConditionOrExpression = false; mInsideLoopInitConditionOrExpression = false;
nextTemporaryIndex(); nextTemporaryIndex();
} }
// The visit functions operate in three modes:
// 1. If a matching expression has already been found, we return early since only one loop can
// be transformed on one traversal.
// 2. We try to find loops. In case a node is not inside a loop and can not contain loops, we
// stop traversing the subtree.
// 3. If we're inside a loop initialization, condition or expression, we check for expressions
// that should be moved out of the loop condition or expression. If one is found, the loop
// is processed.
bool SimplifyLoopConditionsTraverser::visitBinary(Visit visit, TIntermBinary *node) bool SimplifyLoopConditionsTraverser::visitBinary(Visit visit, TIntermBinary *node)
{ {
// The visit functions operate in three modes:
// 1. If a matching expression has already been found, we return early since only one loop can
// be transformed on one traversal.
// 2. We try to find loops. In case a node is not inside a loop and can not contain loops, we
// stop traversing the subtree.
// 3. If we're inside a loop condition or expression, we check for expressions that should be
// moved out of the loop condition or expression. If one is found, the loop is processed.
if (mFoundLoopToChange) if (mFoundLoopToChange)
return false; return false;
if (!mInsideLoopConditionOrExpression) if (!mInsideLoopInitConditionOrExpression)
return false; return false;
mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode(), isLValueRequiredHere()); mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode(), isLValueRequiredHere());
...@@ -95,8 +97,7 @@ bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggrega ...@@ -95,8 +97,7 @@ bool SimplifyLoopConditionsTraverser::visitAggregate(Visit visit, TIntermAggrega
if (mFoundLoopToChange) if (mFoundLoopToChange)
return false; return false;
// If we're outside a loop condition, we only need to traverse nodes that may contain loops. if (!mInsideLoopInitConditionOrExpression)
if (!mInsideLoopConditionOrExpression)
return false; return false;
mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode()); mFoundLoopToChange = mConditionsToSimplify.match(node, getParentNode());
...@@ -108,8 +109,19 @@ bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary * ...@@ -108,8 +109,19 @@ bool SimplifyLoopConditionsTraverser::visitTernary(Visit visit, TIntermTernary *
if (mFoundLoopToChange) if (mFoundLoopToChange)
return false; return false;
// Don't traverse ternary operators outside loop conditions. if (!mInsideLoopInitConditionOrExpression)
if (!mInsideLoopConditionOrExpression) return false;
mFoundLoopToChange = mConditionsToSimplify.match(node);
return !mFoundLoopToChange;
}
bool SimplifyLoopConditionsTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node)
{
if (mFoundLoopToChange)
return false;
if (!mInsideLoopInitConditionOrExpression)
return false; return false;
mFoundLoopToChange = mConditionsToSimplify.match(node); mFoundLoopToChange = mConditionsToSimplify.match(node);
...@@ -127,12 +139,23 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) ...@@ -127,12 +139,23 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
// Note: No need to traverse the loop init node. // Note: No need to traverse the loop init node.
mInsideLoopConditionOrExpression = true; mInsideLoopInitConditionOrExpression = true;
TLoopType loopType = node->getType(); TLoopType loopType = node->getType();
if (node->getCondition()) if (!mFoundLoopToChange && node->getInit())
{
node->getInit()->traverse(this);
}
if (!mFoundLoopToChange && node->getCondition())
{ {
node->getCondition()->traverse(this); node->getCondition()->traverse(this);
}
if (!mFoundLoopToChange && node->getExpression())
{
node->getExpression()->traverse(this);
}
if (mFoundLoopToChange) if (mFoundLoopToChange)
{ {
...@@ -173,7 +196,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) ...@@ -173,7 +196,7 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
// do { // do {
// { body; } // { body; }
// s0 = expr; // s0 = expr;
// while (s0); // } while (s0);
TIntermSequence tempInitSeq; TIntermSequence tempInitSeq;
tempInitSeq.push_back(createTempInitDeclaration(CreateBoolConstantNode(true))); tempInitSeq.push_back(createTempInitDeclaration(CreateBoolConstantNode(true)));
insertStatementsInParentBlock(tempInitSeq); insertStatementsInParentBlock(tempInitSeq);
...@@ -230,33 +253,8 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node) ...@@ -230,33 +253,8 @@ void SimplifyLoopConditionsTraverser::traverseLoop(TIntermLoop *node)
OriginalNode::IS_DROPPED); OriginalNode::IS_DROPPED);
} }
} }
}
if (!mFoundLoopToChange && node->getExpression())
{
node->getExpression()->traverse(this);
if (mFoundLoopToChange)
{
ASSERT(loopType == ELoopFor);
// Move the loop expression to inside the loop.
// Transform:
// for (init; expr; exprB) { body; }
// into
// for (init; expr; ) { { body; } exprB; }
TIntermTyped *loopExpression = node->getExpression();
node->setExpression(nullptr);
TIntermBlock *oldBody = node->getBody();
node->setBody(new TIntermBlock());
if (oldBody != nullptr)
{
node->getBody()->getSequence()->push_back(oldBody);
}
node->getBody()->getSequence()->push_back(loopExpression);
}
}
mInsideLoopConditionOrExpression = false; mInsideLoopInitConditionOrExpression = false;
if (!mFoundLoopToChange && node->getBody()) if (!mFoundLoopToChange && node->getBody())
node->getBody()->traverse(this); node->getBody()->traverse(this);
......
...@@ -39,16 +39,19 @@ void TranslatorHLSL::translate(TIntermNode *root, ShCompileOptions compileOption ...@@ -39,16 +39,19 @@ void TranslatorHLSL::translate(TIntermNode *root, ShCompileOptions compileOption
sh::AddDefaultReturnStatements(root); sh::AddDefaultReturnStatements(root);
SeparateDeclarations(root);
// Note that SimplifyLoopConditions needs to be run before any other AST transformations that // Note that SimplifyLoopConditions needs to be run before any other AST transformations that
// may need to generate new statements from loop conditions or loop expressions. // may need to generate new statements from loop conditions or loop expressions.
SimplifyLoopConditions(root, SimplifyLoopConditions(root,
IntermNodePatternMatcher::kExpressionReturningArray | IntermNodePatternMatcher::kExpressionReturningArray |
IntermNodePatternMatcher::kUnfoldedShortCircuitExpression | IntermNodePatternMatcher::kUnfoldedShortCircuitExpression |
IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue, IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue |
IntermNodePatternMatcher::kMultiDeclaration,
getTemporaryIndex(), getSymbolTable(), getShaderVersion()); getTemporaryIndex(), getSymbolTable(), getShaderVersion());
// Note that separate declarations need to be run before other AST transformations that
// generate new statements from expressions.
SeparateDeclarations(root);
SplitSequenceOperator(root, SplitSequenceOperator(root,
IntermNodePatternMatcher::kExpressionReturningArray | IntermNodePatternMatcher::kExpressionReturningArray |
IntermNodePatternMatcher::kUnfoldedShortCircuitExpression | IntermNodePatternMatcher::kUnfoldedShortCircuitExpression |
......
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