translator: Refactor node replacement APIs.
BUG=angleproject:851
Change-Id: I50c3b3a4f00b27fed85f09509738513a441c7b5b
Reviewed-on: https://chromium-review.googlesource.com/363990
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Commit-Queue: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
index 3c1a71e..af5bb9c 100644
--- a/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
+++ b/src/compiler/translator/ArrayReturnValueToOutParameter.cpp
@@ -103,7 +103,8 @@
replacementParams->getSequence()->push_back(CreateReturnValueOutSymbol(node->getType()));
replacementParams->setLine(params->getLine());
- replaceWithParent(node, params, replacementParams);
+ queueReplacementWithParent(node, params, replacementParams,
+ OriginalNode::IS_DROPPED);
node->setType(TType(EbtVoid));
@@ -122,7 +123,7 @@
replacement->setLine(node->getLine());
replacement->setType(TType(EbtVoid));
- replace(node, replacement);
+ queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
}
else if (node->getOp() == EOpFunctionCall)
{
@@ -192,7 +193,7 @@
if (rightAgg != nullptr && rightAgg->getOp() == EOpFunctionCall && rightAgg->isUserDefined())
{
TIntermAggregate *replacementCall = CreateReplacementCall(rightAgg, node->getLeft());
- replace(node, replacementCall);
+ queueReplacement(node, replacementCall, OriginalNode::IS_DROPPED);
}
}
return false;
diff --git a/src/compiler/translator/DeferGlobalInitializers.cpp b/src/compiler/translator/DeferGlobalInitializers.cpp
index 6904f94..76addf2 100644
--- a/src/compiler/translator/DeferGlobalInitializers.cpp
+++ b/src/compiler/translator/DeferGlobalInitializers.cpp
@@ -130,7 +130,7 @@
ASSERT(symbolNode->getQualifier() == EvqGlobal);
}
// Remove the initializer from the global scope and just declare the global instead.
- mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, symbolNode, false));
+ queueReplacement(node, symbolNode, OriginalNode::IS_DROPPED);
}
}
return false;
diff --git a/src/compiler/translator/EmulatePrecision.cpp b/src/compiler/translator/EmulatePrecision.cpp
index 11fa35e..5f1454b 100644
--- a/src/compiler/translator/EmulatePrecision.cpp
+++ b/src/compiler/translator/EmulatePrecision.cpp
@@ -495,9 +495,8 @@
{
if (canRoundFloat(node->getType()) && !mDeclaringVariables && !isLValueRequiredHere())
{
- TIntermNode *parent = getParentNode();
TIntermNode *replacement = createRoundingFunctionCallNode(node);
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD);
}
}
@@ -543,7 +542,7 @@
break;
}
TIntermNode *replacement = createRoundingFunctionCallNode(node);
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD);
break;
}
@@ -553,10 +552,9 @@
mEmulateCompoundAdd.insert(
TypePair(type.getBuiltInTypeNameString(),
node->getRight()->getType().getBuiltInTypeNameString()));
- TIntermNode *parent = getParentNode();
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
node->getLeft(), node->getRight(), "add");
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
break;
}
case EOpSubAssign:
@@ -564,10 +562,9 @@
mEmulateCompoundSub.insert(
TypePair(type.getBuiltInTypeNameString(),
node->getRight()->getType().getBuiltInTypeNameString()));
- TIntermNode *parent = getParentNode();
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
node->getLeft(), node->getRight(), "sub");
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
break;
}
case EOpMulAssign:
@@ -579,10 +576,9 @@
mEmulateCompoundMul.insert(
TypePair(type.getBuiltInTypeNameString(),
node->getRight()->getType().getBuiltInTypeNameString()));
- TIntermNode *parent = getParentNode();
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
node->getLeft(), node->getRight(), "mul");
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
break;
}
case EOpDivAssign:
@@ -590,10 +586,9 @@
mEmulateCompoundDiv.insert(
TypePair(type.getBuiltInTypeNameString(),
node->getRight()->getType().getBuiltInTypeNameString()));
- TIntermNode *parent = getParentNode();
TIntermNode *replacement = createCompoundAssignmentFunctionCallNode(
node->getLeft(), node->getRight(), "div");
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, false));
+ queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
break;
}
default:
@@ -649,7 +644,7 @@
parentUsesResult(parent, node))
{
TIntermNode *replacement = createRoundingFunctionCallNode(node);
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD);
}
}
break;
@@ -659,7 +654,7 @@
if (canRoundFloat(node->getType()) && visit == PreVisit && parentUsesResult(parent, node))
{
TIntermNode *replacement = createRoundingFunctionCallNode(node);
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD);
}
break;
}
@@ -681,9 +676,8 @@
default:
if (canRoundFloat(node->getType()) && visit == PreVisit)
{
- TIntermNode *parent = getParentNode();
TIntermNode *replacement = createRoundingFunctionCallNode(node);
- mReplacements.push_back(NodeUpdateEntry(parent, node, replacement, true));
+ queueReplacement(node, replacement, OriginalNode::BECOMES_CHILD);
}
break;
}
diff --git a/src/compiler/translator/ExpandIntegerPowExpressions.cpp b/src/compiler/translator/ExpandIntegerPowExpressions.cpp
index 162925a..93ded88 100644
--- a/src/compiler/translator/ExpandIntegerPowExpressions.cpp
+++ b/src/compiler/translator/ExpandIntegerPowExpressions.cpp
@@ -122,7 +122,7 @@
current = div;
}
- replace(node, current);
+ queueReplacement(node, current, OriginalNode::IS_DROPPED);
return true;
}
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 4481729..fb6bec1 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -2675,19 +2675,28 @@
UNUSED_ASSERTION_VARIABLE(replaced);
}
- mInsertions.clear();
+ clearReplacementQueue();
+}
+
+void TIntermTraverser::clearReplacementQueue()
+{
mReplacements.clear();
mMultiReplacements.clear();
+ mInsertions.clear();
}
-void TIntermTraverser::replace(TIntermNode *original, TIntermNode *replacement)
+void TIntermTraverser::queueReplacement(TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus)
{
- replaceWithParent(getParentNode(), original, replacement);
+ queueReplacementWithParent(getParentNode(), original, replacement, originalStatus);
}
-void TIntermTraverser::replaceWithParent(TIntermNode *parent,
- TIntermNode *original,
- TIntermNode *replacement)
+void TIntermTraverser::queueReplacementWithParent(TIntermNode *parent,
+ TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus)
{
- mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, false));
+ bool originalBecomesChild = (originalStatus == OriginalNode::BECOMES_CHILD);
+ mReplacements.push_back(NodeUpdateEntry(parent, original, replacement, originalBecomesChild));
}
diff --git a/src/compiler/translator/IntermNode.h b/src/compiler/translator/IntermNode.h
index a9a59ac..33878b7 100644
--- a/src/compiler/translator/IntermNode.h
+++ b/src/compiler/translator/IntermNode.h
@@ -672,17 +672,8 @@
{
public:
POOL_ALLOCATOR_NEW_DELETE();
- TIntermTraverser(bool preVisit, bool inVisit, bool postVisit)
- : preVisit(preVisit),
- inVisit(inVisit),
- postVisit(postVisit),
- mDepth(0),
- mMaxDepth(0),
- mInGlobalScope(true),
- mTemporaryIndex(nullptr)
- {
- }
- virtual ~TIntermTraverser() {}
+ TIntermTraverser(bool preVisit, bool inVisit, bool postVisit);
+ virtual ~TIntermTraverser();
virtual void visitSymbol(TIntermSymbol *node) {}
virtual void visitRaw(TIntermRaw *node) {}
@@ -763,24 +754,6 @@
return !mParentBlockStack.empty() && getParentNode() == mParentBlockStack.back().node;
}
- // To replace a single node with another on the parent node
- struct NodeUpdateEntry
- {
- NodeUpdateEntry(TIntermNode *_parent,
- TIntermNode *_original,
- TIntermNode *_replacement,
- bool _originalBecomesChildOfReplacement)
- : parent(_parent),
- original(_original),
- replacement(_replacement),
- originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement) {}
-
- TIntermNode *parent;
- TIntermNode *original;
- TIntermNode *replacement;
- bool originalBecomesChildOfReplacement;
- };
-
// To replace a single node with multiple nodes on the parent aggregate node
struct NodeReplaceWithMultipleEntry
{
@@ -846,8 +819,20 @@
// Increment temporary symbol index.
void nextTemporaryIndex();
- void replace(TIntermNode *original, TIntermNode *replacement);
- void replaceWithParent(TIntermNode *parent, TIntermNode *original, TIntermNode *replacement);
+ enum class OriginalNode
+ {
+ BECOMES_CHILD,
+ IS_DROPPED
+ };
+
+ void clearReplacementQueue();
+ void queueReplacement(TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus);
+ void queueReplacementWithParent(TIntermNode *parent,
+ TIntermNode *original,
+ TIntermNode *replacement,
+ OriginalNode originalStatus);
const bool preVisit;
const bool inVisit;
@@ -864,11 +849,30 @@
// During traversing, save all the changes that need to happen into
// mReplacements/mMultiReplacements, then do them by calling updateTree().
// Multi replacements are processed after single replacements.
- std::vector<NodeUpdateEntry> mReplacements;
std::vector<NodeReplaceWithMultipleEntry> mMultiReplacements;
std::vector<NodeInsertMultipleEntry> mInsertions;
private:
+ // To replace a single node with another on the parent node
+ struct NodeUpdateEntry
+ {
+ NodeUpdateEntry(TIntermNode *_parent,
+ TIntermNode *_original,
+ TIntermNode *_replacement,
+ bool _originalBecomesChildOfReplacement)
+ : parent(_parent),
+ original(_original),
+ replacement(_replacement),
+ originalBecomesChildOfReplacement(_originalBecomesChildOfReplacement)
+ {
+ }
+
+ TIntermNode *parent;
+ TIntermNode *original;
+ TIntermNode *replacement;
+ bool originalBecomesChildOfReplacement;
+ };
+
struct ParentBlock
{
ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn)
@@ -880,6 +884,9 @@
TIntermAggregate *node;
TIntermSequence::size_type pos;
};
+
+ std::vector<NodeUpdateEntry> mReplacements;
+
// All the code blocks from the root to the current node's parent during traversal.
std::vector<ParentBlock> mParentBlockStack;
diff --git a/src/compiler/translator/IntermTraverse.cpp b/src/compiler/translator/IntermTraverse.cpp
index 889bab7..2f66ba7 100644
--- a/src/compiler/translator/IntermTraverse.cpp
+++ b/src/compiler/translator/IntermTraverse.cpp
@@ -63,6 +63,21 @@
it->traverseBranch(this);
}
+TIntermTraverser::TIntermTraverser(bool preVisit, bool inVisit, bool postVisit)
+ : preVisit(preVisit),
+ inVisit(inVisit),
+ postVisit(postVisit),
+ mDepth(0),
+ mMaxDepth(0),
+ mInGlobalScope(true),
+ mTemporaryIndex(nullptr)
+{
+}
+
+TIntermTraverser::~TIntermTraverser()
+{
+}
+
void TIntermTraverser::pushParentBlock(TIntermAggregate *node)
{
mParentBlockStack.push_back(ParentBlock(node, 0));
diff --git a/src/compiler/translator/RecordConstantPrecision.cpp b/src/compiler/translator/RecordConstantPrecision.cpp
index 14e88b7..af1d1d1 100644
--- a/src/compiler/translator/RecordConstantPrecision.cpp
+++ b/src/compiler/translator/RecordConstantPrecision.cpp
@@ -128,7 +128,7 @@
TIntermSequence insertions;
insertions.push_back(createTempInitDeclaration(node, EvqConst));
insertStatementsInParentBlock(insertions);
- mReplacements.push_back(NodeUpdateEntry(getParentNode(), node, createTempSymbol(node->getType()), false));
+ queueReplacement(node, createTempSymbol(node->getType()), OriginalNode::IS_DROPPED);
mFoundHigherPrecisionConstant = true;
}
diff --git a/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/compiler/translator/RemoveDynamicIndexing.cpp
index e846fcc..37955e7 100644
--- a/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -404,8 +404,7 @@
// Replace the index with the temp variable
TIntermSymbol *tempIndex = createTempSymbol(node->getRight()->getType());
- NodeUpdateEntry replaceIndex(node, node->getRight(), tempIndex, false);
- mReplacements.push_back(replaceIndex);
+ queueReplacementWithParent(node, node->getRight(), tempIndex, OriginalNode::IS_DROPPED);
}
else if (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node))
{
@@ -469,9 +468,7 @@
CreateIndexedWriteFunctionCall(node, tempIndex, createTempSymbol(fieldType));
insertionsAfter.push_back(indexedWriteCall);
insertStatementsInParentBlock(insertionsBefore, insertionsAfter);
- NodeUpdateEntry replaceIndex(getParentNode(), node, createTempSymbol(fieldType),
- false);
- mReplacements.push_back(replaceIndex);
+ queueReplacement(node, createTempSymbol(fieldType), OriginalNode::IS_DROPPED);
mUsedTreeInsertion = true;
}
else
@@ -484,8 +481,7 @@
ASSERT(!mRemoveIndexSideEffectsInSubtree);
TIntermAggregate *indexingCall = CreateIndexFunctionCall(
node, node->getLeft(), EnsureSignedInt(node->getRight()));
- NodeUpdateEntry replaceIndex(getParentNode(), node, indexingCall, false);
- mReplacements.push_back(replaceIndex);
+ queueReplacement(node, indexingCall, OriginalNode::IS_DROPPED);
}
}
}
diff --git a/src/compiler/translator/RemovePow.cpp b/src/compiler/translator/RemovePow.cpp
index 6dbb48d..d55e124 100644
--- a/src/compiler/translator/RemovePow.cpp
+++ b/src/compiler/translator/RemovePow.cpp
@@ -75,8 +75,7 @@
exp->setLine(node->getLine());
exp->setType(node->getType());
- NodeUpdateEntry replacePow(getParentNode(), node, exp, false);
- mReplacements.push_back(replacePow);
+ queueReplacement(node, exp, OriginalNode::IS_DROPPED);
// If the x parameter also needs to be replaced, we need to do that in another traversal,
// since it's parent node will change in a way that's not handled correctly by updateTree().
diff --git a/src/compiler/translator/SeparateExpressionsReturningArrays.cpp b/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
index abb0be4..4041be9 100644
--- a/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
+++ b/src/compiler/translator/SeparateExpressionsReturningArrays.cpp
@@ -93,9 +93,7 @@
insertions.push_back(createTempInitDeclaration(node->getLeft()));
insertStatementsInParentBlock(insertions);
- NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()),
- false);
- mReplacements.push_back(replaceVariable);
+ queueReplacement(node, createTempSymbol(node->getType()), OriginalNode::IS_DROPPED);
return false;
}
@@ -116,9 +114,7 @@
insertions.push_back(createTempInitDeclaration(CopyAggregateNode(node)));
insertStatementsInParentBlock(insertions);
- NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(node->getType()),
- false);
- mReplacements.push_back(replaceVariable);
+ queueReplacement(node, createTempSymbol(node->getType()), OriginalNode::IS_DROPPED);
return false;
}
diff --git a/src/compiler/translator/SplitSequenceOperator.cpp b/src/compiler/translator/SplitSequenceOperator.cpp
index 22f9ec6..3ea29b9 100644
--- a/src/compiler/translator/SplitSequenceOperator.cpp
+++ b/src/compiler/translator/SplitSequenceOperator.cpp
@@ -101,9 +101,7 @@
}
insertStatementsInParentBlock(insertions);
// Replace the sequence with its last operand
- NodeUpdateEntry replaceSequence(getParentNode(), node, node->getSequence()->back(),
- false);
- mReplacements.push_back(replaceSequence);
+ queueReplacement(node, node->getSequence()->back(), OriginalNode::IS_DROPPED);
}
mInsideSequenceOperator--;
}
diff --git a/src/compiler/translator/UnfoldShortCircuitAST.cpp b/src/compiler/translator/UnfoldShortCircuitAST.cpp
index e50bf20..3ef555f 100644
--- a/src/compiler/translator/UnfoldShortCircuitAST.cpp
+++ b/src/compiler/translator/UnfoldShortCircuitAST.cpp
@@ -50,8 +50,7 @@
}
if (replacement)
{
- mReplacements.push_back(
- NodeUpdateEntry(getParentNode(), node, replacement, false));
+ queueReplacement(node, replacement, OriginalNode::IS_DROPPED);
}
return true;
}
diff --git a/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/src/compiler/translator/UnfoldShortCircuitToIf.cpp
index 830cce6..79d241d 100644
--- a/src/compiler/translator/UnfoldShortCircuitToIf.cpp
+++ b/src/compiler/translator/UnfoldShortCircuitToIf.cpp
@@ -108,8 +108,7 @@
insertStatementsInParentBlock(insertions);
- NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false);
- mReplacements.push_back(replaceVariable);
+ queueReplacement(node, createTempSymbol(boolType), OriginalNode::IS_DROPPED);
}
return false;
case EOpLogicalAnd:
@@ -133,8 +132,7 @@
insertStatementsInParentBlock(insertions);
- NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false);
- mReplacements.push_back(replaceVariable);
+ queueReplacement(node, createTempSymbol(boolType), OriginalNode::IS_DROPPED);
}
return false;
default:
@@ -183,8 +181,7 @@
insertStatementsInParentBlock(insertions);
TIntermSymbol *ternaryResult = createTempSymbol(node->getType());
- NodeUpdateEntry replaceVariable(getParentNode(), node, ternaryResult, false);
- mReplacements.push_back(replaceVariable);
+ queueReplacement(node, ternaryResult, OriginalNode::IS_DROPPED);
}
return false;
@@ -207,9 +204,7 @@
// We need to unfold the sequence (comma) operator, otherwise the evaluation order of
// statements would be messed up by unfolded operations inside.
// Don't do any other unfolding on this round of traversal.
- mReplacements.clear();
- mMultiReplacements.clear();
- mInsertions.clear();
+ clearReplacementQueue();
if (!copyLoopConditionOrExpression(getParentNode(), node))
{
@@ -227,8 +222,7 @@
insertStatementsInParentBlock(insertions);
- NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false);
- mReplacements.push_back(replaceVariable);
+ queueReplacement(node, (*seq)[i], OriginalNode::IS_DROPPED);
}
}
}
@@ -295,8 +289,8 @@
{
if (mInLoopCondition)
{
- mReplacements.push_back(
- NodeUpdateEntry(parent, node, createTempSymbol(node->getType()), false));
+ queueReplacementWithParent(parent, node, createTempSymbol(node->getType()),
+ OriginalNode::IS_DROPPED);
TIntermAggregate *body = mParentLoop->getBody();
TIntermSequence empty;
if (mParentLoop->getType() == ELoopDoWhile)
@@ -323,13 +317,15 @@
{
// Move the initializer to the newly created outer scope, so that condition can
// depend on it.
- mReplacements.push_back(NodeUpdateEntry(mParentLoop, initializer, nullptr, false));
+ queueReplacementWithParent(mParentLoop, initializer, nullptr,
+ OriginalNode::IS_DROPPED);
loopScope->getSequence()->push_back(initializer);
}
loopScope->getSequence()->push_back(createTempInitDeclaration(node));
loopScope->getSequence()->push_back(mParentLoop);
- mReplacements.push_back(NodeUpdateEntry(mLoopParent, mParentLoop, loopScope, true));
+ queueReplacementWithParent(mLoopParent, mParentLoop, loopScope,
+ OriginalNode::BECOMES_CHILD);
// The second copy of the part of the loop condition is executed inside the loop.
TIntermSequence insertionsInLoop;
@@ -343,7 +339,7 @@
if (mInLoopExpression)
{
TIntermTyped *movedExpression = mParentLoop->getExpression();
- mReplacements.push_back(NodeUpdateEntry(mParentLoop, movedExpression, nullptr, false));
+ queueReplacementWithParent(mParentLoop, movedExpression, nullptr, OriginalNode::IS_DROPPED);
TIntermAggregate *body = mParentLoop->getBody();
TIntermSequence empty;
TIntermSequence insertions;