summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp')
-rw-r--r--src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp319
1 files changed, 178 insertions, 141 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp b/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
index 74814f22a7..7766c1abc6 100644
--- a/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
+++ b/src/3rdparty/angle/src/compiler/translator/RemoveDynamicIndexing.cpp
@@ -9,14 +9,20 @@
#include "compiler/translator/RemoveDynamicIndexing.h"
+#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/InfoSink.h"
-#include "compiler/translator/IntermNode.h"
+#include "compiler/translator/IntermNodePatternMatcher.h"
+#include "compiler/translator/IntermNode_util.h"
+#include "compiler/translator/IntermTraverse.h"
#include "compiler/translator/SymbolTable.h"
+namespace sh
+{
+
namespace
{
-TName GetIndexFunctionName(const TType &type, bool write)
+std::string GetIndexFunctionName(const TType &type, bool write)
{
TInfoSinkBase nameSink;
nameSink << "dyn_index_";
@@ -49,31 +55,29 @@ TName GetIndexFunctionName(const TType &type, bool write)
}
nameSink << type.getNominalSize();
}
- TString nameString = TFunction::mangleName(nameSink.c_str());
- TName name(nameString);
- name.setInternal(true);
- return name;
+ return nameSink.str();
}
-TIntermSymbol *CreateBaseSymbol(const TType &type, TQualifier qualifier)
+TIntermSymbol *CreateBaseSymbol(const TType &type, TQualifier qualifier, TSymbolTable *symbolTable)
{
- TIntermSymbol *symbol = new TIntermSymbol(0, "base", type);
+ TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), "base", type);
symbol->setInternal(true);
symbol->getTypePointer()->setQualifier(qualifier);
return symbol;
}
-TIntermSymbol *CreateIndexSymbol()
+TIntermSymbol *CreateIndexSymbol(TSymbolTable *symbolTable)
{
- TIntermSymbol *symbol = new TIntermSymbol(0, "index", TType(EbtInt, EbpHigh));
+ TIntermSymbol *symbol =
+ new TIntermSymbol(symbolTable->nextUniqueId(), "index", TType(EbtInt, EbpHigh));
symbol->setInternal(true);
symbol->getTypePointer()->setQualifier(EvqIn);
return symbol;
}
-TIntermSymbol *CreateValueSymbol(const TType &type)
+TIntermSymbol *CreateValueSymbol(const TType &type, TSymbolTable *symbolTable)
{
- TIntermSymbol *symbol = new TIntermSymbol(0, "value", type);
+ TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), "value", type);
symbol->setInternal(true);
symbol->getTypePointer()->setQualifier(EvqIn);
return symbol;
@@ -86,38 +90,14 @@ TIntermConstantUnion *CreateIntConstantNode(int i)
return new TIntermConstantUnion(constant, TType(EbtInt, EbpHigh));
}
-TIntermBinary *CreateIndexDirectBaseSymbolNode(const TType &indexedType,
- const TType &fieldType,
- const int index,
- TQualifier baseQualifier)
-{
- TIntermBinary *indexNode = new TIntermBinary(EOpIndexDirect);
- indexNode->setType(fieldType);
- TIntermSymbol *baseSymbol = CreateBaseSymbol(indexedType, baseQualifier);
- indexNode->setLeft(baseSymbol);
- indexNode->setRight(CreateIntConstantNode(index));
- return indexNode;
-}
-
-TIntermBinary *CreateAssignValueSymbolNode(TIntermTyped *targetNode, const TType &assignedValueType)
-{
- TIntermBinary *assignNode = new TIntermBinary(EOpAssign);
- assignNode->setType(assignedValueType);
- assignNode->setLeft(targetNode);
- assignNode->setRight(CreateValueSymbol(assignedValueType));
- return assignNode;
-}
-
TIntermTyped *EnsureSignedInt(TIntermTyped *node)
{
if (node->getBasicType() == EbtInt)
return node;
- TIntermAggregate *convertedNode = new TIntermAggregate(EOpConstructInt);
- convertedNode->setType(TType(EbtInt));
- convertedNode->getSequence()->push_back(node);
- convertedNode->setPrecisionFromChildren();
- return convertedNode;
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(node);
+ return TIntermAggregate::CreateConstructor(TType(EbtInt), arguments);
}
TType GetFieldType(const TType &indexedType)
@@ -177,7 +157,10 @@ TType GetFieldType(const TType &indexedType)
// base[1] = value;
// }
// Note that else is not used in above functions to avoid the RewriteElseBlocks transformation.
-TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
+TIntermFunctionDefinition *GetIndexFunctionDefinition(TType type,
+ bool write,
+ const TSymbolUniqueId &functionId,
+ TSymbolTable *symbolTable)
{
ASSERT(!type.isArray());
// Conservatively use highp here, even if the indexed type is not highp. That way the code can't
@@ -185,11 +168,9 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
// highp values are being indexed in the shader. For HLSL precision doesn't matter, but in
// principle this code could be used with multiple backends.
type.setPrecision(EbpHigh);
- TIntermAggregate *indexingFunction = new TIntermAggregate(EOpFunction);
- indexingFunction->setNameObj(GetIndexFunctionName(type, write));
TType fieldType = GetFieldType(type);
- int numCases = 0;
+ int numCases = 0;
if (type.isMatrix())
{
numCases = type.getCols();
@@ -198,41 +179,43 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
{
numCases = type.getNominalSize();
}
- if (write)
- {
- indexingFunction->setType(TType(EbtVoid));
- }
- else
+
+ TType returnType(EbtVoid);
+ if (!write)
{
- indexingFunction->setType(fieldType);
+ returnType = fieldType;
}
- TIntermAggregate *paramsNode = new TIntermAggregate(EOpParameters);
- TQualifier baseQualifier = EvqInOut;
+ std::string functionName = GetIndexFunctionName(type, write);
+ TIntermFunctionPrototype *prototypeNode =
+ CreateInternalFunctionPrototypeNode(returnType, functionName.c_str(), functionId);
+
+ TQualifier baseQualifier = EvqInOut;
if (!write)
baseQualifier = EvqIn;
- TIntermSymbol *baseParam = CreateBaseSymbol(type, baseQualifier);
- paramsNode->getSequence()->push_back(baseParam);
- TIntermSymbol *indexParam = CreateIndexSymbol();
- paramsNode->getSequence()->push_back(indexParam);
+ TIntermSymbol *baseParam = CreateBaseSymbol(type, baseQualifier, symbolTable);
+ prototypeNode->getSequence()->push_back(baseParam);
+ TIntermSymbol *indexParam = CreateIndexSymbol(symbolTable);
+ prototypeNode->getSequence()->push_back(indexParam);
+ TIntermSymbol *valueParam = nullptr;
if (write)
{
- TIntermSymbol *valueParam = CreateValueSymbol(fieldType);
- paramsNode->getSequence()->push_back(valueParam);
+ valueParam = CreateValueSymbol(fieldType, symbolTable);
+ prototypeNode->getSequence()->push_back(valueParam);
}
- indexingFunction->getSequence()->push_back(paramsNode);
- TIntermAggregate *statementList = new TIntermAggregate(EOpSequence);
+ TIntermBlock *statementList = new TIntermBlock();
for (int i = 0; i < numCases; ++i)
{
TIntermCase *caseNode = new TIntermCase(CreateIntConstantNode(i));
statementList->getSequence()->push_back(caseNode);
TIntermBinary *indexNode =
- CreateIndexDirectBaseSymbolNode(type, fieldType, i, baseQualifier);
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(i));
if (write)
{
- TIntermBinary *assignNode = CreateAssignValueSymbolNode(indexNode, fieldType);
+ TIntermBinary *assignNode =
+ new TIntermBinary(EOpAssign, indexNode, valueParam->deepCopy());
statementList->getSequence()->push_back(assignNode);
TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
statementList->getSequence()->push_back(returnNode);
@@ -250,32 +233,33 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
TIntermBranch *breakNode = new TIntermBranch(EOpBreak, nullptr);
statementList->getSequence()->push_back(breakNode);
- TIntermSwitch *switchNode = new TIntermSwitch(CreateIndexSymbol(), statementList);
+ TIntermSwitch *switchNode = new TIntermSwitch(indexParam->deepCopy(), statementList);
- TIntermAggregate *bodyNode = new TIntermAggregate(EOpSequence);
+ TIntermBlock *bodyNode = new TIntermBlock();
bodyNode->getSequence()->push_back(switchNode);
- TIntermBinary *cond = new TIntermBinary(EOpLessThan);
+ TIntermBinary *cond =
+ new TIntermBinary(EOpLessThan, indexParam->deepCopy(), CreateIntConstantNode(0));
cond->setType(TType(EbtBool, EbpUndefined));
- cond->setLeft(CreateIndexSymbol());
- cond->setRight(CreateIntConstantNode(0));
// Two blocks: one accesses (either reads or writes) the first element and returns,
// the other accesses the last element.
- TIntermAggregate *useFirstBlock = new TIntermAggregate(EOpSequence);
- TIntermAggregate *useLastBlock = new TIntermAggregate(EOpSequence);
+ TIntermBlock *useFirstBlock = new TIntermBlock();
+ TIntermBlock *useLastBlock = new TIntermBlock();
TIntermBinary *indexFirstNode =
- CreateIndexDirectBaseSymbolNode(type, fieldType, 0, baseQualifier);
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(0));
TIntermBinary *indexLastNode =
- CreateIndexDirectBaseSymbolNode(type, fieldType, numCases - 1, baseQualifier);
+ new TIntermBinary(EOpIndexDirect, baseParam->deepCopy(), CreateIndexNode(numCases - 1));
if (write)
{
- TIntermBinary *assignFirstNode = CreateAssignValueSymbolNode(indexFirstNode, fieldType);
+ TIntermBinary *assignFirstNode =
+ new TIntermBinary(EOpAssign, indexFirstNode, valueParam->deepCopy());
useFirstBlock->getSequence()->push_back(assignFirstNode);
TIntermBranch *returnNode = new TIntermBranch(EOpReturn, nullptr);
useFirstBlock->getSequence()->push_back(returnNode);
- TIntermBinary *assignLastNode = CreateAssignValueSymbolNode(indexLastNode, fieldType);
+ TIntermBinary *assignLastNode =
+ new TIntermBinary(EOpAssign, indexLastNode, valueParam->deepCopy());
useLastBlock->getSequence()->push_back(assignLastNode);
}
else
@@ -286,19 +270,21 @@ TIntermAggregate *GetIndexFunctionDefinition(TType type, bool write)
TIntermBranch *returnLastNode = new TIntermBranch(EOpReturn, indexLastNode);
useLastBlock->getSequence()->push_back(returnLastNode);
}
- TIntermSelection *ifNode = new TIntermSelection(cond, useFirstBlock, nullptr);
+ TIntermIfElse *ifNode = new TIntermIfElse(cond, useFirstBlock, nullptr);
bodyNode->getSequence()->push_back(ifNode);
bodyNode->getSequence()->push_back(useLastBlock);
- indexingFunction->getSequence()->push_back(bodyNode);
-
+ TIntermFunctionDefinition *indexingFunction =
+ new TIntermFunctionDefinition(prototypeNode, bodyNode);
return indexingFunction;
}
class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
{
public:
- RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable, int shaderVersion);
+ RemoveDynamicIndexingTraverser(TSymbolTable *symbolTable,
+ int shaderVersion,
+ PerformanceDiagnostics *perfDiagnostics);
bool visitBinary(Visit visit, TIntermBinary *node) override;
@@ -309,10 +295,11 @@ class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
bool usedTreeInsertion() const { return mUsedTreeInsertion; }
protected:
- // Sets of types that are indexed. Note that these can not store multiple variants
- // of the same type with different precisions - only one precision gets stored.
- std::set<TType> mIndexedVecAndMatrixTypes;
- std::set<TType> mWrittenVecAndMatrixTypes;
+ // Maps of types that are indexed to the indexing function ids used for them. Note that these
+ // can not store multiple variants of the same type with different precisions - only one
+ // precision gets stored.
+ std::map<TType, TSymbolUniqueId *> mIndexedVecAndMatrixTypes;
+ std::map<TType, TSymbolUniqueId *> mWrittenVecAndMatrixTypes;
bool mUsedTreeInsertion;
@@ -321,62 +308,74 @@ class RemoveDynamicIndexingTraverser : public TLValueTrackingTraverser
// V[j++][i]++.
// where V is an array of vectors, j++ will only be evaluated once.
bool mRemoveIndexSideEffectsInSubtree;
+
+ PerformanceDiagnostics *mPerfDiagnostics;
};
-RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(const TSymbolTable &symbolTable,
- int shaderVersion)
+RemoveDynamicIndexingTraverser::RemoveDynamicIndexingTraverser(
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ PerformanceDiagnostics *perfDiagnostics)
: TLValueTrackingTraverser(true, false, false, symbolTable, shaderVersion),
mUsedTreeInsertion(false),
- mRemoveIndexSideEffectsInSubtree(false)
+ mRemoveIndexSideEffectsInSubtree(false),
+ mPerfDiagnostics(perfDiagnostics)
{
}
void RemoveDynamicIndexingTraverser::insertHelperDefinitions(TIntermNode *root)
{
- TIntermAggregate *rootAgg = root->getAsAggregate();
- ASSERT(rootAgg != nullptr && rootAgg->getOp() == EOpSequence);
+ TIntermBlock *rootBlock = root->getAsBlock();
+ ASSERT(rootBlock != nullptr);
TIntermSequence insertions;
- for (TType type : mIndexedVecAndMatrixTypes)
+ for (auto &type : mIndexedVecAndMatrixTypes)
{
- insertions.push_back(GetIndexFunctionDefinition(type, false));
+ insertions.push_back(
+ GetIndexFunctionDefinition(type.first, false, *type.second, mSymbolTable));
}
- for (TType type : mWrittenVecAndMatrixTypes)
+ for (auto &type : mWrittenVecAndMatrixTypes)
{
- insertions.push_back(GetIndexFunctionDefinition(type, true));
+ insertions.push_back(
+ GetIndexFunctionDefinition(type.first, true, *type.second, mSymbolTable));
}
- mInsertions.push_back(NodeInsertMultipleEntry(rootAgg, 0, insertions, TIntermSequence()));
+ rootBlock->insertChildNodes(0, insertions);
}
// Create a call to dyn_index_*() based on an indirect indexing op node
TIntermAggregate *CreateIndexFunctionCall(TIntermBinary *node,
- TIntermTyped *indexedNode,
- TIntermTyped *index)
+ TIntermTyped *index,
+ const TSymbolUniqueId &functionId)
{
ASSERT(node->getOp() == EOpIndexIndirect);
- TIntermAggregate *indexingCall = new TIntermAggregate(EOpFunctionCall);
+ TIntermSequence *arguments = new TIntermSequence();
+ arguments->push_back(node->getLeft());
+ arguments->push_back(index);
+
+ TType fieldType = GetFieldType(node->getLeft()->getType());
+ std::string functionName = GetIndexFunctionName(node->getLeft()->getType(), false);
+ TIntermAggregate *indexingCall =
+ CreateInternalFunctionCallNode(fieldType, functionName.c_str(), functionId, arguments);
indexingCall->setLine(node->getLine());
- indexingCall->setUserDefined();
- indexingCall->setNameObj(GetIndexFunctionName(indexedNode->getType(), false));
- indexingCall->getSequence()->push_back(indexedNode);
- indexingCall->getSequence()->push_back(index);
-
- TType fieldType = GetFieldType(indexedNode->getType());
- indexingCall->setType(fieldType);
+ indexingCall->getFunctionSymbolInfo()->setKnownToNotHaveSideEffects(true);
return indexingCall;
}
TIntermAggregate *CreateIndexedWriteFunctionCall(TIntermBinary *node,
TIntermTyped *index,
- TIntermTyped *writtenValue)
+ TIntermTyped *writtenValue,
+ const TSymbolUniqueId &functionId)
{
- // Deep copy the left node so that two pointers to the same node don't end up in the tree.
- TIntermNode *leftCopy = node->getLeft()->deepCopy();
- ASSERT(leftCopy != nullptr && leftCopy->getAsTyped() != nullptr);
+ ASSERT(node->getOp() == EOpIndexIndirect);
+ TIntermSequence *arguments = new TIntermSequence();
+ // Deep copy the child nodes so that two pointers to the same node don't end up in the tree.
+ arguments->push_back(node->getLeft()->deepCopy());
+ arguments->push_back(index->deepCopy());
+ arguments->push_back(writtenValue);
+
+ std::string functionName = GetIndexFunctionName(node->getLeft()->getType(), true);
TIntermAggregate *indexedWriteCall =
- CreateIndexFunctionCall(node, leftCopy->getAsTyped(), index);
- indexedWriteCall->setNameObj(GetIndexFunctionName(node->getLeft()->getType(), true));
- indexedWriteCall->setType(TType(EbtVoid));
- indexedWriteCall->getSequence()->push_back(writtenValue);
+ CreateInternalFunctionCallNode(TType(EbtVoid), functionName.c_str(), functionId, arguments);
+ indexedWriteCall->setLine(node->getLine());
return indexedWriteCall;
}
@@ -397,23 +396,40 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// Now v_expr[s0] can be safely executed several times without unintended side effects.
// Init the temp variable holding the index
- TIntermAggregate *initIndex = createTempInitDeclaration(node->getRight());
- TIntermSequence insertions;
- insertions.push_back(initIndex);
- insertStatementsInParentBlock(insertions);
+ TIntermDeclaration *initIndex = createTempInitDeclaration(node->getRight());
+ insertStatementInParentBlock(initIndex);
mUsedTreeInsertion = true;
// 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 (!node->getLeft()->isArray() && node->getLeft()->getBasicType() != EbtStruct)
+ else if (IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(node))
{
+ mPerfDiagnostics->warning(node->getLine(),
+ "Performance: dynamic indexing of vectors and "
+ "matrices is emulated and can be slow.",
+ "[]");
bool write = isLValueRequiredHere();
- TType type = node->getLeft()->getType();
- mIndexedVecAndMatrixTypes.insert(type);
+#if defined(ANGLE_ENABLE_ASSERTS)
+ // Make sure that IntermNodePatternMatcher is consistent with the slightly differently
+ // implemented checks in this traverser.
+ IntermNodePatternMatcher matcher(
+ IntermNodePatternMatcher::kDynamicIndexingOfVectorOrMatrixInLValue);
+ ASSERT(matcher.match(node, getParentNode(), isLValueRequiredHere()) == write);
+#endif
+
+ const TType &type = node->getLeft()->getType();
+ TSymbolUniqueId *indexingFunctionId = new TSymbolUniqueId(mSymbolTable);
+ if (mIndexedVecAndMatrixTypes.find(type) == mIndexedVecAndMatrixTypes.end())
+ {
+ mIndexedVecAndMatrixTypes[type] = indexingFunctionId;
+ }
+ else
+ {
+ indexingFunctionId = mIndexedVecAndMatrixTypes[type];
+ }
if (write)
{
@@ -432,10 +448,30 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
mRemoveIndexSideEffectsInSubtree = true;
return true;
}
+
+ TIntermBinary *leftBinary = node->getLeft()->getAsBinaryNode();
+ if (leftBinary != nullptr &&
+ IntermNodePatternMatcher::IsDynamicIndexingOfVectorOrMatrix(leftBinary))
+ {
+ // This is a case like:
+ // mat2 m;
+ // m[a][b]++;
+ // Process the child node m[a] first.
+ return true;
+ }
+
// TODO(oetuaho@nvidia.com): This is not optimal if the expression using the value
// only writes it and doesn't need the previous value. http://anglebug.com/1116
- mWrittenVecAndMatrixTypes.insert(type);
+ TSymbolUniqueId *indexedWriteFunctionId = new TSymbolUniqueId(mSymbolTable);
+ if (mWrittenVecAndMatrixTypes.find(type) == mWrittenVecAndMatrixTypes.end())
+ {
+ mWrittenVecAndMatrixTypes[type] = indexedWriteFunctionId;
+ }
+ else
+ {
+ indexedWriteFunctionId = mWrittenVecAndMatrixTypes[type];
+ }
TType fieldType = GetFieldType(type);
TIntermSequence insertionsBefore;
@@ -443,28 +479,26 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// Store the index in a temporary signed int variable.
TIntermTyped *indexInitializer = EnsureSignedInt(node->getRight());
- TIntermAggregate *initIndex = createTempInitDeclaration(indexInitializer);
+ TIntermDeclaration *initIndex = createTempInitDeclaration(indexInitializer);
initIndex->setLine(node->getLine());
insertionsBefore.push_back(initIndex);
- TIntermAggregate *indexingCall = CreateIndexFunctionCall(
- node, node->getLeft(), createTempSymbol(indexInitializer->getType()));
-
- // Create a node for referring to the index after the nextTemporaryIndex() call
+ // Create a node for referring to the index after the nextTemporaryId() call
// below.
TIntermSymbol *tempIndex = createTempSymbol(indexInitializer->getType());
- nextTemporaryIndex(); // From now on, creating temporary symbols that refer to the
- // field value.
+ TIntermAggregate *indexingCall =
+ CreateIndexFunctionCall(node, tempIndex, *indexingFunctionId);
+
+ nextTemporaryId(); // From now on, creating temporary symbols that refer to the
+ // field value.
insertionsBefore.push_back(createTempInitDeclaration(indexingCall));
- TIntermAggregate *indexedWriteCall =
- CreateIndexedWriteFunctionCall(node, tempIndex, createTempSymbol(fieldType));
+ TIntermAggregate *indexedWriteCall = CreateIndexedWriteFunctionCall(
+ node, tempIndex, createTempSymbol(fieldType), *indexedWriteFunctionId);
insertionsAfter.push_back(indexedWriteCall);
insertStatementsInParentBlock(insertionsBefore, insertionsAfter);
- NodeUpdateEntry replaceIndex(getParentNode(), node, createTempSymbol(fieldType),
- false);
- mReplacements.push_back(replaceIndex);
+ queueReplacement(createTempSymbol(fieldType), OriginalNode::IS_DROPPED);
mUsedTreeInsertion = true;
}
else
@@ -476,9 +510,8 @@ bool RemoveDynamicIndexingTraverser::visitBinary(Visit visit, TIntermBinary *nod
// If the index_expr is unsigned, we'll convert it to signed.
ASSERT(!mRemoveIndexSideEffectsInSubtree);
TIntermAggregate *indexingCall = CreateIndexFunctionCall(
- node, node->getLeft(), EnsureSignedInt(node->getRight()));
- NodeUpdateEntry replaceIndex(getParentNode(), node, indexingCall, false);
- mReplacements.push_back(replaceIndex);
+ node, EnsureSignedInt(node->getRight()), *indexingFunctionId);
+ queueReplacement(indexingCall, OriginalNode::IS_DROPPED);
}
}
}
@@ -489,25 +522,29 @@ void RemoveDynamicIndexingTraverser::nextIteration()
{
mUsedTreeInsertion = false;
mRemoveIndexSideEffectsInSubtree = false;
- nextTemporaryIndex();
+ nextTemporaryId();
}
} // namespace
void RemoveDynamicIndexing(TIntermNode *root,
- unsigned int *temporaryIndex,
- const TSymbolTable &symbolTable,
- int shaderVersion)
+ TSymbolTable *symbolTable,
+ int shaderVersion,
+ PerformanceDiagnostics *perfDiagnostics)
{
- RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion);
- ASSERT(temporaryIndex != nullptr);
- traverser.useTemporaryIndex(temporaryIndex);
+ RemoveDynamicIndexingTraverser traverser(symbolTable, shaderVersion, perfDiagnostics);
do
{
traverser.nextIteration();
root->traverse(&traverser);
traverser.updateTree();
} while (traverser.usedTreeInsertion());
+ // TODO(oetuaho@nvidia.com): It might be nicer to add the helper definitions also in the middle
+ // of traversal. Now the tree ends up in an inconsistent state in the middle, since there are
+ // function call nodes with no corresponding definition nodes. This needs special handling in
+ // TIntermLValueTrackingTraverser, and creates intricacies that are not easily apparent from a
+ // superficial reading of the code.
traverser.insertHelperDefinitions(root);
- traverser.updateTree();
}
+
+} // namespace sh