blob: 48e87cd57a8828abf677779a2297cb9b063032f6 [file] [log] [blame]
Jamie Madille53c98b2014-02-03 11:57:13 -05001//
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.
5//
6// RewriteElseBlocks.cpp: Implementation for tree transform to change
7// all if-else blocks to if-if blocks.
8//
9
10#include "compiler/translator/RewriteElseBlocks.h"
11#include "compiler/translator/NodeSearch.h"
12#include "compiler/translator/SymbolTable.h"
13
14namespace sh
15{
16
17TIntermSymbol *MakeNewTemporary(const TString &name, TBasicType type)
18{
19 TType variableType(type, EbpHigh, EvqInternal);
20 return new TIntermSymbol(-1, name, variableType);
21}
22
23TIntermBinary *MakeNewBinary(TOperator op, TIntermTyped *left, TIntermTyped *right, const TType &resultType)
24{
25 TIntermBinary *binary = new TIntermBinary(op);
26 binary->setLeft(left);
27 binary->setRight(right);
28 binary->setType(resultType);
29 return binary;
30}
31
32TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
33{
34 TIntermUnary *unary = new TIntermUnary(op, operand->getType());
35 unary->setOperand(operand);
36 return unary;
37}
38
39bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
40{
41 switch (node->getOp())
42 {
43 case EOpSequence:
44 {
45 for (size_t statementIndex = 0; statementIndex != node->getSequence().size(); statementIndex++)
46 {
47 TIntermNode *statement = node->getSequence()[statementIndex];
48 TIntermSelection *selection = statement->getAsSelectionNode();
49 if (selection && selection->getFalseBlock() != NULL)
50 {
51 node->getSequence()[statementIndex] = rewriteSelection(selection);
52 delete selection;
53 }
54 }
55 }
56 break;
57
58 default: break;
59 }
60
61 return true;
62}
63
64TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
65{
66 ASSERT(selection->getFalseBlock() != NULL);
67
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);
81
82 TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration);
83 declaration->getSequence().push_back(storeCondition);
84
85 TIntermAggregate *block = new TIntermAggregate(EOpSequence);
86 block->getSequence().push_back(declaration);
87 block->getSequence().push_back(newIfElse);
88
89 return block;
90}
91
92void RewriteElseBlocks(TIntermNode *node)
93{
94 ElseBlockRewriter rewriter;
95 node->traverse(&rewriter);
96}
97
98}