gfx/angle/src/compiler/UnfoldShortCircuit.cpp

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

michael@0 1 //
michael@0 2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
michael@0 3 // Use of this source code is governed by a BSD-style license that can be
michael@0 4 // found in the LICENSE file.
michael@0 5 //
michael@0 6 // UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements.
michael@0 7 // The results are assigned to s# temporaries, which are used by the main translator instead of
michael@0 8 // the original expression.
michael@0 9 //
michael@0 10
michael@0 11 #include "compiler/UnfoldShortCircuit.h"
michael@0 12
michael@0 13 #include "compiler/InfoSink.h"
michael@0 14 #include "compiler/OutputHLSL.h"
michael@0 15
michael@0 16 namespace sh
michael@0 17 {
michael@0 18 UnfoldShortCircuit::UnfoldShortCircuit(TParseContext &context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL)
michael@0 19 {
michael@0 20 mTemporaryIndex = 0;
michael@0 21 }
michael@0 22
michael@0 23 void UnfoldShortCircuit::traverse(TIntermNode *node)
michael@0 24 {
michael@0 25 int rewindIndex = mTemporaryIndex;
michael@0 26 node->traverse(this);
michael@0 27 mTemporaryIndex = rewindIndex;
michael@0 28 }
michael@0 29
michael@0 30 bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
michael@0 31 {
michael@0 32 TInfoSinkBase &out = mOutputHLSL->getBodyStream();
michael@0 33
michael@0 34 switch (node->getOp())
michael@0 35 {
michael@0 36 case EOpLogicalOr:
michael@0 37 // "x || y" is equivalent to "x ? true : y", which unfolds to "bool s; if(x) s = true; else s = y;",
michael@0 38 // and then further simplifies down to "bool s = x; if(!s) s = y;".
michael@0 39 {
michael@0 40 int i = mTemporaryIndex;
michael@0 41
michael@0 42 out << "bool s" << i << ";\n";
michael@0 43
michael@0 44 out << "{\n";
michael@0 45
michael@0 46 mTemporaryIndex = i + 1;
michael@0 47 node->getLeft()->traverse(this);
michael@0 48 out << "s" << i << " = ";
michael@0 49 mTemporaryIndex = i + 1;
michael@0 50 node->getLeft()->traverse(mOutputHLSL);
michael@0 51 out << ";\n";
michael@0 52 out << "if(!s" << i << ")\n"
michael@0 53 "{\n";
michael@0 54 mTemporaryIndex = i + 1;
michael@0 55 node->getRight()->traverse(this);
michael@0 56 out << " s" << i << " = ";
michael@0 57 mTemporaryIndex = i + 1;
michael@0 58 node->getRight()->traverse(mOutputHLSL);
michael@0 59 out << ";\n"
michael@0 60 "}\n";
michael@0 61
michael@0 62 out << "}\n";
michael@0 63
michael@0 64 mTemporaryIndex = i + 1;
michael@0 65 }
michael@0 66 return false;
michael@0 67 case EOpLogicalAnd:
michael@0 68 // "x && y" is equivalent to "x ? y : false", which unfolds to "bool s; if(x) s = y; else s = false;",
michael@0 69 // and then further simplifies down to "bool s = x; if(s) s = y;".
michael@0 70 {
michael@0 71 int i = mTemporaryIndex;
michael@0 72
michael@0 73 out << "bool s" << i << ";\n";
michael@0 74
michael@0 75 out << "{\n";
michael@0 76
michael@0 77 mTemporaryIndex = i + 1;
michael@0 78 node->getLeft()->traverse(this);
michael@0 79 out << "s" << i << " = ";
michael@0 80 mTemporaryIndex = i + 1;
michael@0 81 node->getLeft()->traverse(mOutputHLSL);
michael@0 82 out << ";\n";
michael@0 83 out << "if(s" << i << ")\n"
michael@0 84 "{\n";
michael@0 85 mTemporaryIndex = i + 1;
michael@0 86 node->getRight()->traverse(this);
michael@0 87 out << " s" << i << " = ";
michael@0 88 mTemporaryIndex = i + 1;
michael@0 89 node->getRight()->traverse(mOutputHLSL);
michael@0 90 out << ";\n"
michael@0 91 "}\n";
michael@0 92
michael@0 93 out << "}\n";
michael@0 94
michael@0 95 mTemporaryIndex = i + 1;
michael@0 96 }
michael@0 97 return false;
michael@0 98 default:
michael@0 99 return true;
michael@0 100 }
michael@0 101 }
michael@0 102
michael@0 103 bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
michael@0 104 {
michael@0 105 TInfoSinkBase &out = mOutputHLSL->getBodyStream();
michael@0 106
michael@0 107 // Unfold "b ? x : y" into "type s; if(b) s = x; else s = y;"
michael@0 108 if (node->usesTernaryOperator())
michael@0 109 {
michael@0 110 int i = mTemporaryIndex;
michael@0 111
michael@0 112 out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n";
michael@0 113
michael@0 114 out << "{\n";
michael@0 115
michael@0 116 mTemporaryIndex = i + 1;
michael@0 117 node->getCondition()->traverse(this);
michael@0 118 out << "if(";
michael@0 119 mTemporaryIndex = i + 1;
michael@0 120 node->getCondition()->traverse(mOutputHLSL);
michael@0 121 out << ")\n"
michael@0 122 "{\n";
michael@0 123 mTemporaryIndex = i + 1;
michael@0 124 node->getTrueBlock()->traverse(this);
michael@0 125 out << " s" << i << " = ";
michael@0 126 mTemporaryIndex = i + 1;
michael@0 127 node->getTrueBlock()->traverse(mOutputHLSL);
michael@0 128 out << ";\n"
michael@0 129 "}\n"
michael@0 130 "else\n"
michael@0 131 "{\n";
michael@0 132 mTemporaryIndex = i + 1;
michael@0 133 node->getFalseBlock()->traverse(this);
michael@0 134 out << " s" << i << " = ";
michael@0 135 mTemporaryIndex = i + 1;
michael@0 136 node->getFalseBlock()->traverse(mOutputHLSL);
michael@0 137 out << ";\n"
michael@0 138 "}\n";
michael@0 139
michael@0 140 out << "}\n";
michael@0 141
michael@0 142 mTemporaryIndex = i + 1;
michael@0 143 }
michael@0 144
michael@0 145 return false;
michael@0 146 }
michael@0 147
michael@0 148 bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node)
michael@0 149 {
michael@0 150 int rewindIndex = mTemporaryIndex;
michael@0 151
michael@0 152 if (node->getInit())
michael@0 153 {
michael@0 154 node->getInit()->traverse(this);
michael@0 155 }
michael@0 156
michael@0 157 if (node->getCondition())
michael@0 158 {
michael@0 159 node->getCondition()->traverse(this);
michael@0 160 }
michael@0 161
michael@0 162 if (node->getExpression())
michael@0 163 {
michael@0 164 node->getExpression()->traverse(this);
michael@0 165 }
michael@0 166
michael@0 167 mTemporaryIndex = rewindIndex;
michael@0 168
michael@0 169 return false;
michael@0 170 }
michael@0 171
michael@0 172 int UnfoldShortCircuit::getNextTemporaryIndex()
michael@0 173 {
michael@0 174 return mTemporaryIndex++;
michael@0 175 }
michael@0 176 }

mercurial