2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
6 // RewriteElseBlocks.cpp: Implementation for tree transform to change
7 // all if-else blocks to if-if blocks.
10 #include "compiler/translator/RewriteElseBlocks.h"
11 #include "compiler/translator/NodeSearch.h"
12 #include "compiler/translator/SymbolTable.h"
17 TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type)
19 TType variableType(type, EbpHigh, EvqInternal);
20 return new TIntermSymbol(-1, name, variableType);
23 TIntermBinary *MakeNewBinary(TOperator op, TIntermTyped *left, TIntermTyped *right, const TType &resultType)
25 TIntermBinary *binary = new TIntermBinary(op);
26 binary->setLeft(left);
27 binary->setRight(right);
28 binary->setType(resultType);
32 TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
34 TIntermUnary *unary = new TIntermUnary(op, operand->getType());
35 unary->setOperand(operand);
39 bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
41 switch (node->getOp())
45 for (size_t statementIndex = 0; statementIndex != node->getSequence().size(); statementIndex++)
47 TIntermNode *statement = node->getSequence()[statementIndex];
48 TIntermSelection *selection = statement->getAsSelectionNode();
49 if (selection && selection->getFalseBlock() != NULL)
51 node->getSequence()[statementIndex] = rewriteSelection(selection);
64 TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
66 ASSERT(selection->getFalseBlock() != NULL);
68 TString temporaryName = "cond_" + str(mTemporaryIndex++);
69 TIntermTyped *typedCondition = selection->getCondition()->getAsTyped();
70 TType resultType(EbtBool, EbpUndefined);
71 TIntermSymbol *conditionSymbolA = MakeNewTemporary(temporaryName, EbtBool);
72 TIntermSymbol *conditionSymbolB = MakeNewTemporary(temporaryName, EbtBool);
73 TIntermSymbol *conditionSymbolC = MakeNewTemporary(temporaryName, EbtBool);
74 TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolA,
75 typedCondition, resultType);
76 TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolB);
77 TIntermSelection *falseBlock = new TIntermSelection(negatedCondition,
78 selection->getFalseBlock(), NULL);
79 TIntermSelection *newIfElse = new TIntermSelection(conditionSymbolC,
80 selection->getTrueBlock(), falseBlock);
82 TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration);
83 declaration->getSequence().push_back(storeCondition);
85 TIntermAggregate *block = new TIntermAggregate(EOpSequence);
86 block->getSequence().push_back(declaration);
87 block->getSequence().push_back(newIfElse);
92 void RewriteElseBlocks(TIntermNode *node)
94 ElseBlockRewriter rewriter;
95 node->traverse(&rewriter);