summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/SeparateExpressionsReturningArrays.cpp145
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