zenilib: zenilib/jni/external/angle/src/compiler/UnfoldShortCircuit.cpp Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
UnfoldShortCircuit.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2002-2013 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 // UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements.
7 // The results are assigned to s# temporaries, which are used by the main translator instead of
8 // the original expression.
9 //
10
11 #include "compiler/UnfoldShortCircuit.h"
12
13 #include "compiler/InfoSink.h"
14 #include "compiler/OutputHLSL.h"
15
16 namespace sh
17 {
18 UnfoldShortCircuit::UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL)
19 {
20 mTemporaryIndex = 0;
21 }
22
23 void UnfoldShortCircuit::traverse(TIntermNode *node)
24 {
25 int rewindIndex = mTemporaryIndex;
26 node->traverse(this);
27 mTemporaryIndex = rewindIndex;
28 }
29
30 bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
31 {
32 TInfoSinkBase &out = mOutputHLSL->getBodyStream();
33
34 switch (node->getOp())
35 {
36 case EOpLogicalOr:
37 // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; else s = y;",
38 // and then further simplifies down to "bool s = x; if(!s) s = y;".
39 {
40 int i = mTemporaryIndex;
41
42 out << "bool s" << i << ";\n";
43
44 out << "{\n";
45
46 mTemporaryIndex = i + 1;
47 node->getLeft()->traverse(this);
48 out << "s" << i << " = ";
49 mTemporaryIndex = i + 1;
50 node->getLeft()->traverse(mOutputHLSL);
51 out << ";\n";
52 out << "if(!s" << i << ")\n"
53 "{\n";
54 mTemporaryIndex = i + 1;
55 node->getRight()->traverse(this);
56 out << " s" << i << " = ";
57 mTemporaryIndex = i + 1;
58 node->getRight()->traverse(mOutputHLSL);
59 out << ";\n"
60 "}\n";
61
62 out << "}\n";
63
64 mTemporaryIndex = i + 1;
65 }
66 return false;
67 case EOpLogicalAnd:
68 // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; else s = false;",
69 // and then further simplifies down to "bool s = x; if(s) s = y;".
70 {
71 int i = mTemporaryIndex;
72
73 out << "bool s" << i << ";\n";
74
75 out << "{\n";
76
77 mTemporaryIndex = i + 1;
78 node->getLeft()->traverse(this);
79 out << "s" << i << " = ";
80 mTemporaryIndex = i + 1;
81 node->getLeft()->traverse(mOutputHLSL);
82 out << ";\n";
83 out << "if(s" << i << ")\n"
84 "{\n";
85 mTemporaryIndex = i + 1;
86 node->getRight()->traverse(this);
87 out << " s" << i << " = ";
88 mTemporaryIndex = i + 1;
89 node->getRight()->traverse(mOutputHLSL);
90 out << ";\n"
91 "}\n";
92
93 out << "}\n";
94
95 mTemporaryIndex = i + 1;
96 }
97 return false;
98 default:
99 return true;
100 }
101 }
102
103 bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
104 {
105 TInfoSinkBase &out = mOutputHLSL->getBodyStream();
106
107 // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
108 if (node->usesTernaryOperator())
109 {
110 int i = mTemporaryIndex;
111
112 out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n";
113
114 out << "{\n";
115
116 mTemporaryIndex = i + 1;
117 node->getCondition()->traverse(this);
118 out << "if(";
119 mTemporaryIndex = i + 1;
120 node->getCondition()->traverse(mOutputHLSL);
121 out << ")\n"
122 "{\n";
123 mTemporaryIndex = i + 1;
124 node->getTrueBlock()->traverse(this);
125 out << " s" << i << " = ";
126 mTemporaryIndex = i + 1;
127 node->getTrueBlock()->traverse(mOutputHLSL);
128 out << ";\n"
129 "}\n"
130 "else\n"
131 "{\n";
132 mTemporaryIndex = i + 1;
133 node->getFalseBlock()->traverse(this);
134 out << " s" << i << " = ";
135 mTemporaryIndex = i + 1;
136 node->getFalseBlock()->traverse(mOutputHLSL);
137 out << ";\n"
138 "}\n";
139
140 out << "}\n";
141
142 mTemporaryIndex = i + 1;
143 }
144
145 return false;
146 }
147
148 bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node)
149 {
150 int rewindIndex = mTemporaryIndex;
151
152 if (node->getInit())
153 {
154 node->getInit()->traverse(this);
155 }
156
157 if (node->getCondition())
158 {
159 node->getCondition()->traverse(this);
160 }
161
162 if (node->getExpression())
163 {
164 node->getExpression()->traverse(this);
165 }
166
167 mTemporaryIndex = rewindIndex;
168
169 return false;
170 }
171
172 int UnfoldShortCircuit::getNextTemporaryIndex()
173 {
174 return mTemporaryIndex++;
175 }
176 }
Visit
Visit
Definition: intermediate.h:524
TIntermOperator::getOp
TOperator getOp() const
Definition: intermediate.h:389
TIntermSelection::getTrueBlock
TIntermNode * getTrueBlock() const
Definition: intermediate.h:514
TIntermLoop::getCondition
TIntermTyped * getCondition()
Definition: intermediate.h:301
EOpLogicalOr
Definition: intermediate.h:82
TIntermBinary::getLeft
TIntermTyped * getLeft() const
Definition: intermediate.h:413
TParseContext
Definition: ParseHelper.h:27
TIntermSelection::getFalseBlock
TIntermNode * getFalseBlock() const
Definition: intermediate.h:515
TIntermBinary::getRight
TIntermTyped * getRight() const
Definition: intermediate.h:414
sh::UnfoldShortCircuit::visitSelection
bool visitSelection(Visit visit, TIntermSelection *node)
Definition: UnfoldShortCircuit.cpp:103
TIntermBinary
Definition: intermediate.h:404
TIntermSelection
Definition: intermediate.h:503
TInfoSinkBase
Definition: InfoSink.h:38
sh::OutputHLSL::getBodyStream
TInfoSinkBase & getBodyStream()
Definition: OutputHLSL.cpp:123
TIntermNode::traverse
virtual void traverse(TIntermTraverser *)=0
TIntermSelection::getCondition
TIntermNode * getCondition() const
Definition: intermediate.h:513
TIntermTyped::getType
const TType & getType() const
Definition: intermediate.h:251
sh::UnfoldShortCircuit::traverse
void traverse(TIntermNode *node)
Definition: UnfoldShortCircuit.cpp:23
sh::OutputHLSL
Definition: OutputHLSL.h:25
sh::UnfoldShortCircuit::visitLoop
bool visitLoop(Visit visit, TIntermLoop *node)
Definition: UnfoldShortCircuit.cpp:148
sh::UnfoldShortCircuit::mTemporaryIndex
int mTemporaryIndex
Definition: UnfoldShortCircuit.h:35
sh::UnfoldShortCircuit::getNextTemporaryIndex
int getNextTemporaryIndex()
Definition: UnfoldShortCircuit.cpp:172
TIntermSelection::usesTernaryOperator
bool usesTernaryOperator() const
Definition: intermediate.h:512
TIntermLoop
Definition: intermediate.h:284
sh::UnfoldShortCircuit::UnfoldShortCircuit
UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL)
Definition: UnfoldShortCircuit.cpp:18
EOpLogicalAnd
Definition: intermediate.h:84
UnfoldShortCircuit.h
TIntermLoop::getExpression
TIntermTyped * getExpression()
Definition: intermediate.h:302
TIntermNode
Definition: intermediate.h:206
InfoSink.h
context
TParseContext * context
Definition: glslang_tab.cpp:1907
i
int i
Definition: pngrutil.c:1377
TIntermLoop::getInit
TIntermNode * getInit()
Definition: intermediate.h:300
sh::OutputHLSL::typeString
TString typeString(const TType &type)
Definition: OutputHLSL.cpp:2430
sh::UnfoldShortCircuit::visitBinary
bool visitBinary(Visit visit, TIntermBinary *)
Definition: UnfoldShortCircuit.cpp:30
sh::UnfoldShortCircuit::mOutputHLSL
OutputHLSL *const mOutputHLSL
Definition: UnfoldShortCircuit.h:33
OutputHLSL.h