diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp | 186 |
1 files changed, 0 insertions, 186 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp b/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp deleted file mode 100644 index 774f1fc704..0000000000 --- a/src/3rdparty/angle/src/compiler/translator/UnfoldShortCircuitToIf.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// -// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// UnfoldShortCircuitToIf is an AST traverser to convert short-circuiting operators to if-else -// statements. -// The results are assigned to s# temporaries, which are used by the main translator instead of -// the original expression. -// - -#include "compiler/translator/UnfoldShortCircuitToIf.h" - -#include "compiler/translator/IntermNodePatternMatcher.h" -#include "compiler/translator/IntermTraverse.h" - -namespace sh -{ - -namespace -{ - -// Traverser that unfolds one short-circuiting operation at a time. -class UnfoldShortCircuitTraverser : public TIntermTraverser -{ - public: - UnfoldShortCircuitTraverser(TSymbolTable *symbolTable); - - bool visitBinary(Visit visit, TIntermBinary *node) override; - bool visitTernary(Visit visit, TIntermTernary *node) override; - - void nextIteration(); - bool foundShortCircuit() const { return mFoundShortCircuit; } - - protected: - // Marked to true once an operation that needs to be unfolded has been found. - // After that, no more unfolding is performed on that traversal. - bool mFoundShortCircuit; - - IntermNodePatternMatcher mPatternToUnfoldMatcher; -}; - -UnfoldShortCircuitTraverser::UnfoldShortCircuitTraverser(TSymbolTable *symbolTable) - : TIntermTraverser(true, false, true, symbolTable), - mFoundShortCircuit(false), - mPatternToUnfoldMatcher(IntermNodePatternMatcher::kUnfoldedShortCircuitExpression) -{ -} - -bool UnfoldShortCircuitTraverser::visitBinary(Visit visit, TIntermBinary *node) -{ - if (mFoundShortCircuit) - return false; - - if (visit != PreVisit) - return true; - - if (!mPatternToUnfoldMatcher.match(node, getParentNode())) - return true; - - // If our right node doesn't have side effects, we know we don't need to unfold this - // expression: there will be no short-circuiting side effects to avoid - // (note: unfolding doesn't depend on the left node -- it will always be evaluated) - ASSERT(node->getRight()->hasSideEffects()); - - mFoundShortCircuit = true; - - switch (node->getOp()) - { - case EOpLogicalOr: - { - // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; - // else s = y;", - // and then further simplifies down to "bool s = x; if(!s) s = y;". - - TIntermSequence insertions; - TType boolType(EbtBool, EbpUndefined, EvqTemporary); - - ASSERT(node->getLeft()->getType() == boolType); - insertions.push_back(createTempInitDeclaration(node->getLeft())); - - TIntermBlock *assignRightBlock = new TIntermBlock(); - ASSERT(node->getRight()->getType() == boolType); - assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); - - TIntermUnary *notTempSymbol = - new TIntermUnary(EOpLogicalNot, createTempSymbol(boolType)); - TIntermIfElse *ifNode = new TIntermIfElse(notTempSymbol, assignRightBlock, nullptr); - insertions.push_back(ifNode); - - insertStatementsInParentBlock(insertions); - - queueReplacement(createTempSymbol(boolType), OriginalNode::IS_DROPPED); - return false; - } - case EOpLogicalAnd: - { - // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; - // else s = false;", - // and then further simplifies down to "bool s = x; if(s) s = y;". - TIntermSequence insertions; - TType boolType(EbtBool, EbpUndefined, EvqTemporary); - - ASSERT(node->getLeft()->getType() == boolType); - insertions.push_back(createTempInitDeclaration(node->getLeft())); - - TIntermBlock *assignRightBlock = new TIntermBlock(); - ASSERT(node->getRight()->getType() == boolType); - assignRightBlock->getSequence()->push_back(createTempAssignment(node->getRight())); - - TIntermIfElse *ifNode = - new TIntermIfElse(createTempSymbol(boolType), assignRightBlock, nullptr); - insertions.push_back(ifNode); - - insertStatementsInParentBlock(insertions); - - queueReplacement(createTempSymbol(boolType), OriginalNode::IS_DROPPED); - return false; - } - default: - UNREACHABLE(); - return true; - } -} - -bool UnfoldShortCircuitTraverser::visitTernary(Visit visit, TIntermTernary *node) -{ - if (mFoundShortCircuit) - return false; - - if (visit != PreVisit) - return true; - - if (!mPatternToUnfoldMatcher.match(node)) - return true; - - mFoundShortCircuit = true; - - // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;" - TIntermSequence insertions; - - TIntermDeclaration *tempDeclaration = createTempDeclaration(node->getType()); - insertions.push_back(tempDeclaration); - - TIntermBlock *trueBlock = new TIntermBlock(); - TIntermBinary *trueAssignment = createTempAssignment(node->getTrueExpression()); - trueBlock->getSequence()->push_back(trueAssignment); - - TIntermBlock *falseBlock = new TIntermBlock(); - TIntermBinary *falseAssignment = createTempAssignment(node->getFalseExpression()); - falseBlock->getSequence()->push_back(falseAssignment); - - TIntermIfElse *ifNode = - new TIntermIfElse(node->getCondition()->getAsTyped(), trueBlock, falseBlock); - insertions.push_back(ifNode); - - insertStatementsInParentBlock(insertions); - - TIntermSymbol *ternaryResult = createTempSymbol(node->getType()); - queueReplacement(ternaryResult, OriginalNode::IS_DROPPED); - - return false; -} - -void UnfoldShortCircuitTraverser::nextIteration() -{ - mFoundShortCircuit = false; - nextTemporaryId(); -} - -} // namespace - -void UnfoldShortCircuitToIf(TIntermNode *root, TSymbolTable *symbolTable) -{ - UnfoldShortCircuitTraverser traverser(symbolTable); - // Unfold one operator at a time, and reset the traverser between iterations. - do - { - traverser.nextIteration(); - root->traverse(&traverser); - if (traverser.foundShortCircuit()) - traverser.updateTree(); - } while (traverser.foundShortCircuit()); -} - -} // namespace sh |