diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp | 145 |
1 files changed, 51 insertions, 94 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp index e8e1a21d9c..01d627937c 100644 --- a/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp +++ b/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp @@ -3,15 +3,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names from more complex -// expressions, assigning them to a temporary variable a#. +// SeparateExpressionsReturningArrays splits array-returning expressions that are not array names +// from more complex expressions, assigning them to a temporary variable a#. // Examples where a, b and c are all arrays: // (a = b) == (a = c) is split into a = b; type[n] a1 = a; a = c; type[n] a2 = a; a1 == a2; // type d = type[n](...)[i]; is split into type[n] a1 = type[n](...); type d = a1[i]; #include "compiler/translator/SeparateExpressionsReturningArrays.h" -#include "compiler/translator/IntermNode.h" +#include "compiler/translator/IntermNodePatternMatcher.h" +#include "compiler/translator/IntermTraverse.h" + +namespace sh +{ namespace { @@ -20,7 +24,7 @@ namespace class SeparateExpressionsTraverser : public TIntermTraverser { public: - SeparateExpressionsTraverser(); + SeparateExpressionsTraverser(TSymbolTable *symbolTable); bool visitBinary(Visit visit, TIntermBinary *node) override; bool visitAggregate(Visit visit, TIntermAggregate *node) override; @@ -29,14 +33,17 @@ class SeparateExpressionsTraverser : public TIntermTraverser bool foundArrayExpression() const { return mFoundArrayExpression; } protected: - // 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. + // 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. bool mFoundArrayExpression; + + IntermNodePatternMatcher mPatternToSeparateMatcher; }; -SeparateExpressionsTraverser::SeparateExpressionsTraverser() - : TIntermTraverser(true, false, false), - mFoundArrayExpression(false) +SeparateExpressionsTraverser::SeparateExpressionsTraverser(TSymbolTable *symbolTable) + : TIntermTraverser(true, false, false, symbolTable), + mFoundArrayExpression(false), + mPatternToSeparateMatcher(IntermNodePatternMatcher::kExpressionReturningArray) { } @@ -45,27 +52,7 @@ SeparateExpressionsTraverser::SeparateExpressionsTraverser() // and also needs to be replaced in its original location by a different node. TIntermBinary *CopyAssignmentNode(TIntermBinary *node) { - TIntermBinary *copyNode = new TIntermBinary(node->getOp()); - copyNode->setLeft(node->getLeft()); - copyNode->setRight(node->getRight()); - copyNode->setType(node->getType()); - return copyNode; -} - -// Performs a shallow copy of a constructor/function call node. -TIntermAggregate *CopyAggregateNode(TIntermAggregate *node) -{ - TIntermAggregate *copyNode = new TIntermAggregate(node->getOp()); - TIntermSequence *copySeq = copyNode->getSequence(); - copySeq->insert(copySeq->begin(), node->getSequence()->begin(), node->getSequence()->end()); - copyNode->setType(node->getType()); - copyNode->setFunctionId(node->getFunctionId()); - if (node->isUserDefined()) - { - copyNode->setUserDefined(); - } - copyNode->setNameObj(node->getNameObj()); - return copyNode; + return new TIntermBinary(node->getOp(), node->getLeft(), node->getRight()); } bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node) @@ -73,90 +60,59 @@ bool SeparateExpressionsTraverser::visitBinary(Visit visit, TIntermBinary *node) if (mFoundArrayExpression) return false; - // Early return if the expression is not an array or if we're not inside a complex expression. - if (!node->getType().isArray() || parentNodeIsBlock()) + // Return if the expression is not an array or if we're not inside a complex expression. + if (!mPatternToSeparateMatcher.match(node, getParentNode())) return true; - switch (node->getOp()) - { - case EOpAssign: - { - mFoundArrayExpression = true; - - TIntermSequence insertions; - insertions.push_back(CopyAssignmentNode(node)); - // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just use the - // original target of the assignment. Care must be taken so that this doesn't happen when the same array - // symbol is a target of assignment more than once in one expression. - insertions.push_back(createTempInitDeclaration(node->getLeft())); - insertStatementsInParentBlock(insertions); - - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); - } - return false; - default: - return true; - } + ASSERT(node->getOp() == EOpAssign); + + mFoundArrayExpression = true; + + TIntermSequence insertions; + insertions.push_back(CopyAssignmentNode(node)); + // TODO(oetuaho): In some cases it would be more optimal to not add the temporary node, but just + // use the original target of the assignment. Care must be taken so that this doesn't happen + // when the same array symbol is a target of assignment more than once in one expression. + insertions.push_back(createTempInitDeclaration(node->getLeft())); + insertStatementsInParentBlock(insertions); + + queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); + + return false; } bool SeparateExpressionsTraverser::visitAggregate(Visit visit, TIntermAggregate *node) { if (mFoundArrayExpression) - return false; // No need to traverse further - - if (getParentNode() != nullptr) - { - TIntermBinary *parentBinary = getParentNode()->getAsBinaryNode(); - bool parentIsAssignment = (parentBinary != nullptr && - (parentBinary->getOp() == EOpAssign || parentBinary->getOp() == EOpInitialize)); - - if (!node->getType().isArray() || parentNodeIsBlock() || parentIsAssignment) - return true; - - if (node->isConstructor()) - { - mFoundArrayExpression = true; + return false; // No need to traverse further - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); - insertStatementsInParentBlock(insertions); + if (!mPatternToSeparateMatcher.match(node, getParentNode())) + return true; - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); + ASSERT(node->isConstructor() || node->getOp() == EOpCallFunctionInAST); - return false; - } - else if (node->getOp() == EOpFunctionCall) - { - mFoundArrayExpression = true; + mFoundArrayExpression = true; - TIntermSequence insertions; - insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node))); - insertStatementsInParentBlock(insertions); + TIntermSequence insertions; + insertions.push_back(createTempInitDeclaration(node->shallowCopy())); + insertStatementsInParentBlock(insertions); - NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()), false); - mReplacements.push_back(replaceVariable); + queueReplacement(createTempSymbol(node->getType()), OriginalNode::IS_DROPPED); - return false; - } - } - return true; + return false; } void SeparateExpressionsTraverser::nextIteration() { mFoundArrayExpression = false; - nextTemporaryIndex(); + nextTemporaryId(); } -} // namespace +} // namespace -void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *temporaryIndex) +void SeparateExpressionsReturningArrays(TIntermNode *root, TSymbolTable *symbolTable) { - SeparateExpressionsTraverser traverser; - ASSERT(temporaryIndex != nullptr); - traverser.useTemporaryIndex(temporaryIndex); + SeparateExpressionsTraverser traverser(symbolTable); // Separate one expression at a time, and reset the traverser between iterations. do { @@ -164,6 +120,7 @@ void SeparateExpressionsReturningArrays(TIntermNode *root, unsigned int *tempora root->traverse(&traverser); if (traverser.foundArrayExpression()) traverser.updateTree(); - } - while (traverser.foundArrayExpression()); + } while (traverser.foundArrayExpression()); } + +} // namespace sh |