Commit 56eea884 by Olli Etuaho

Refactoring: make tracking parent block position in AST traversal reusable

Add a helper function to make it easier for traverser classes to insert statements, and use it in UnfoldShortCircuitToIf. BUG=angleproject:971 TEST=angle_end2end_tests, WebGL conformance tests Change-Id: I141bdd8abf4b01988581e6cb27c2320bf38370ac Reviewed-on: https://chromium-review.googlesource.com/272140Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent d94f6647
...@@ -629,6 +629,10 @@ class TIntermTraverser : angle::NonCopyable ...@@ -629,6 +629,10 @@ class TIntermTraverser : angle::NonCopyable
return mPath.size() == 0 ? NULL : mPath.back(); return mPath.size() == 0 ? NULL : mPath.back();
} }
void pushParentBlock(TIntermAggregate *node);
void incrementParentBlockPos();
void popParentBlock();
// Return the original name if hash function pointer is NULL; // Return the original name if hash function pointer is NULL;
// otherwise return the hashed name. // otherwise return the hashed name.
static TString hash(const TString& name, ShHashFunction64 hashFunction); static TString hash(const TString& name, ShHashFunction64 hashFunction);
...@@ -704,6 +708,28 @@ class TIntermTraverser : angle::NonCopyable ...@@ -704,6 +708,28 @@ class TIntermTraverser : angle::NonCopyable
std::vector<NodeUpdateEntry> mReplacements; std::vector<NodeUpdateEntry> mReplacements;
std::vector<NodeReplaceWithMultipleEntry> mMultiReplacements; std::vector<NodeReplaceWithMultipleEntry> mMultiReplacements;
std::vector<NodeInsertMultipleEntry> mInsertions; std::vector<NodeInsertMultipleEntry> mInsertions;
// Helper to insert statements in the parent block (sequence) of the node currently being traversed.
// The statements will be inserted before the node being traversed once updateTree is called.
// Should only be called during PreVisit or PostVisit from sequence nodes.
// Note that inserting more than one set of nodes to the same parent node on a single updateTree call is not
// supported.
void insertStatementsInParentBlock(const TIntermSequence &insertions);
private:
struct ParentBlock
{
ParentBlock(TIntermAggregate *nodeIn, TIntermSequence::size_type posIn)
: node(nodeIn),
pos(posIn)
{
}
TIntermAggregate *node;
TIntermSequence::size_type pos;
};
// All the code blocks from the root to the current node's parent during traversal.
std::vector<ParentBlock> mParentBlockStack;
}; };
// //
......
...@@ -6,6 +6,35 @@ ...@@ -6,6 +6,35 @@
#include "compiler/translator/IntermNode.h" #include "compiler/translator/IntermNode.h"
void TIntermTraverser::pushParentBlock(TIntermAggregate *node)
{
if (rightToLeft)
mParentBlockStack.push_back(ParentBlock(node, node->getSequence()->size() - 1));
else
mParentBlockStack.push_back(ParentBlock(node, 0));
}
void TIntermTraverser::incrementParentBlockPos()
{
if (rightToLeft)
--mParentBlockStack.back().pos;
else
++mParentBlockStack.back().pos;
}
void TIntermTraverser::popParentBlock()
{
ASSERT(!mParentBlockStack.empty());
mParentBlockStack.pop_back();
}
void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertions)
{
ASSERT(!mParentBlockStack.empty());
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions);
mInsertions.push_back(insert);
}
// //
// Traverse the intermediate representation tree, and // Traverse the intermediate representation tree, and
// call a node type specific function for each node. // call a node type specific function for each node.
...@@ -119,6 +148,9 @@ void TIntermAggregate::traverse(TIntermTraverser *it) ...@@ -119,6 +148,9 @@ void TIntermAggregate::traverse(TIntermTraverser *it)
if (visit) if (visit)
{ {
if (mOp == EOpSequence)
it->pushParentBlock(this);
it->incrementDepth(this); it->incrementDepth(this);
if (it->rightToLeft) if (it->rightToLeft)
...@@ -133,6 +165,10 @@ void TIntermAggregate::traverse(TIntermTraverser *it) ...@@ -133,6 +165,10 @@ void TIntermAggregate::traverse(TIntermTraverser *it)
if (*sit != mSequence.front()) if (*sit != mSequence.front())
visit = it->visitAggregate(InVisit, this); visit = it->visitAggregate(InVisit, this);
} }
if (mOp == EOpSequence)
{
it->incrementParentBlockPos();
}
} }
} }
else else
...@@ -147,10 +183,17 @@ void TIntermAggregate::traverse(TIntermTraverser *it) ...@@ -147,10 +183,17 @@ void TIntermAggregate::traverse(TIntermTraverser *it)
if (*sit != mSequence.back()) if (*sit != mSequence.back())
visit = it->visitAggregate(InVisit, this); visit = it->visitAggregate(InVisit, this);
} }
if (mOp == EOpSequence)
{
it->incrementParentBlockPos();
}
} }
} }
it->decrementDepth(); it->decrementDepth();
if (mOp == EOpSequence)
it->popParentBlock();
} }
if (visit && it->postVisit) if (visit && it->postVisit)
......
...@@ -37,19 +37,6 @@ class UnfoldShortCircuitTraverser : public TIntermTraverser ...@@ -37,19 +37,6 @@ class UnfoldShortCircuitTraverser : public TIntermTraverser
// After that, no more unfolding is performed on that traversal. // After that, no more unfolding is performed on that traversal.
bool mFoundShortCircuit; bool mFoundShortCircuit;
struct ParentBlock
{
ParentBlock(TIntermAggregate *_node, TIntermSequence::size_type _pos)
: node(_node),
pos(_pos)
{
}
TIntermAggregate *node;
TIntermSequence::size_type pos;
};
std::vector<ParentBlock> mParentBlockStack;
TIntermSymbol *createTempSymbol(const TType &type); TIntermSymbol *createTempSymbol(const TType &type);
TIntermAggregate *createTempInitDeclaration(const TType &type, TIntermTyped *initializer); TIntermAggregate *createTempInitDeclaration(const TType &type, TIntermTyped *initializer);
TIntermBinary *createTempAssignment(const TType &type, TIntermTyped *rightNode); TIntermBinary *createTempAssignment(const TType &type, TIntermTyped *rightNode);
...@@ -131,8 +118,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ...@@ -131,8 +118,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr); TIntermSelection *ifNode = new TIntermSelection(notTempSymbol, assignRightBlock, nullptr);
insertions.push_back(ifNode); insertions.push_back(ifNode);
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions); insertStatementsInParentBlock(insertions);
mInsertions.push_back(insert);
NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false);
mReplacements.push_back(replaceVariable); mReplacements.push_back(replaceVariable);
...@@ -155,8 +141,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) ...@@ -155,8 +141,7 @@ bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node)
TIntermSelection *ifNode = new TIntermSelection(createTempSymbol(boolType), assignRightBlock, nullptr); TIntermSelection *ifNode = new TIntermSelection(createTempSymbol(boolType), assignRightBlock, nullptr);
insertions.push_back(ifNode); insertions.push_back(ifNode);
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions); insertStatementsInParentBlock(insertions);
mInsertions.push_back(insert);
NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false); NodeUpdateEntry replaceVariable(getParentNode(), node, createTempSymbol(boolType), false);
mReplacements.push_back(replaceVariable); mReplacements.push_back(replaceVariable);
...@@ -194,8 +179,7 @@ bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection * ...@@ -194,8 +179,7 @@ bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection *
TIntermSelection *ifNode = new TIntermSelection(node->getCondition()->getAsTyped(), trueBlock, falseBlock); TIntermSelection *ifNode = new TIntermSelection(node->getCondition()->getAsTyped(), trueBlock, falseBlock);
insertions.push_back(ifNode); insertions.push_back(ifNode);
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions); insertStatementsInParentBlock(insertions);
mInsertions.push_back(insert);
TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); TIntermSymbol *ternaryResult = createTempSymbol(node->getType());
NodeUpdateEntry replaceVariable(getParentNode(), node, ternaryResult, false); NodeUpdateEntry replaceVariable(getParentNode(), node, ternaryResult, false);
...@@ -211,23 +195,7 @@ bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate * ...@@ -211,23 +195,7 @@ bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *
if (visit == PreVisit && mFoundShortCircuit) if (visit == PreVisit && mFoundShortCircuit)
return false; // No need to traverse further return false; // No need to traverse further
if (node->getOp() == EOpSequence) if (node->getOp() == EOpComma)
{
if (visit == PreVisit)
{
mParentBlockStack.push_back(ParentBlock(node, 0));
}
else if (visit == InVisit)
{
++mParentBlockStack.back().pos;
}
else
{
ASSERT(visit == PostVisit);
mParentBlockStack.pop_back();
}
}
else if (node->getOp() == EOpComma)
{ {
ASSERT(visit != PreVisit || !mFoundShortCircuit); ASSERT(visit != PreVisit || !mFoundShortCircuit);
...@@ -255,8 +223,8 @@ bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate * ...@@ -255,8 +223,8 @@ bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *
++i; ++i;
} }
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions); insertStatementsInParentBlock(insertions);
mInsertions.push_back(insert);
NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false); NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false);
mReplacements.push_back(replaceVariable); mReplacements.push_back(replaceVariable);
} }
......
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