gfx/angle/src/compiler/intermOut.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-2010 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
michael@0 7 #include "compiler/localintermediate.h"
michael@0 8
michael@0 9 //
michael@0 10 // Two purposes:
michael@0 11 // 1. Show an example of how to iterate tree. Functions can
michael@0 12 // also directly call Traverse() on children themselves to
michael@0 13 // have finer grained control over the process than shown here.
michael@0 14 // See the last function for how to get started.
michael@0 15 // 2. Print out a text based description of the tree.
michael@0 16 //
michael@0 17
michael@0 18 //
michael@0 19 // Use this class to carry along data from node to node in
michael@0 20 // the traversal
michael@0 21 //
michael@0 22 class TOutputTraverser : public TIntermTraverser {
michael@0 23 public:
michael@0 24 TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
michael@0 25 TInfoSinkBase& sink;
michael@0 26
michael@0 27 protected:
michael@0 28 void visitSymbol(TIntermSymbol*);
michael@0 29 void visitConstantUnion(TIntermConstantUnion*);
michael@0 30 bool visitBinary(Visit visit, TIntermBinary*);
michael@0 31 bool visitUnary(Visit visit, TIntermUnary*);
michael@0 32 bool visitSelection(Visit visit, TIntermSelection*);
michael@0 33 bool visitAggregate(Visit visit, TIntermAggregate*);
michael@0 34 bool visitLoop(Visit visit, TIntermLoop*);
michael@0 35 bool visitBranch(Visit visit, TIntermBranch*);
michael@0 36 };
michael@0 37
michael@0 38 TString TType::getCompleteString() const
michael@0 39 {
michael@0 40 TStringStream stream;
michael@0 41
michael@0 42 if (qualifier != EvqTemporary && qualifier != EvqGlobal)
michael@0 43 stream << getQualifierString() << " " << getPrecisionString() << " ";
michael@0 44 if (array)
michael@0 45 stream << "array[" << getArraySize() << "] of ";
michael@0 46 if (matrix)
michael@0 47 stream << size << "X" << size << " matrix of ";
michael@0 48 else if (size > 1)
michael@0 49 stream << size << "-component vector of ";
michael@0 50
michael@0 51 stream << getBasicString();
michael@0 52 return stream.str();
michael@0 53 }
michael@0 54
michael@0 55 //
michael@0 56 // Helper functions for printing, not part of traversing.
michael@0 57 //
michael@0 58
michael@0 59 void OutputTreeText(TInfoSinkBase& sink, TIntermNode* node, const int depth)
michael@0 60 {
michael@0 61 int i;
michael@0 62
michael@0 63 sink.location(node->getLine());
michael@0 64
michael@0 65 for (i = 0; i < depth; ++i)
michael@0 66 sink << " ";
michael@0 67 }
michael@0 68
michael@0 69 //
michael@0 70 // The rest of the file are the traversal functions. The last one
michael@0 71 // is the one that starts the traversal.
michael@0 72 //
michael@0 73 // Return true from interior nodes to have the external traversal
michael@0 74 // continue on to children. If you process children yourself,
michael@0 75 // return false.
michael@0 76 //
michael@0 77
michael@0 78 void TOutputTraverser::visitSymbol(TIntermSymbol* node)
michael@0 79 {
michael@0 80 OutputTreeText(sink, node, depth);
michael@0 81
michael@0 82 sink << "'" << node->getSymbol() << "' ";
michael@0 83 sink << "(" << node->getCompleteString() << ")\n";
michael@0 84 }
michael@0 85
michael@0 86 bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
michael@0 87 {
michael@0 88 TInfoSinkBase& out = sink;
michael@0 89
michael@0 90 OutputTreeText(out, node, depth);
michael@0 91
michael@0 92 switch (node->getOp()) {
michael@0 93 case EOpAssign: out << "move second child to first child"; break;
michael@0 94 case EOpInitialize: out << "initialize first child with second child"; break;
michael@0 95 case EOpAddAssign: out << "add second child into first child"; break;
michael@0 96 case EOpSubAssign: out << "subtract second child into first child"; break;
michael@0 97 case EOpMulAssign: out << "multiply second child into first child"; break;
michael@0 98 case EOpVectorTimesMatrixAssign: out << "matrix mult second child into first child"; break;
michael@0 99 case EOpVectorTimesScalarAssign: out << "vector scale second child into first child"; break;
michael@0 100 case EOpMatrixTimesScalarAssign: out << "matrix scale second child into first child"; break;
michael@0 101 case EOpMatrixTimesMatrixAssign: out << "matrix mult second child into first child"; break;
michael@0 102 case EOpDivAssign: out << "divide second child into first child"; break;
michael@0 103 case EOpIndexDirect: out << "direct index"; break;
michael@0 104 case EOpIndexIndirect: out << "indirect index"; break;
michael@0 105 case EOpIndexDirectStruct: out << "direct index for structure"; break;
michael@0 106 case EOpVectorSwizzle: out << "vector swizzle"; break;
michael@0 107
michael@0 108 case EOpAdd: out << "add"; break;
michael@0 109 case EOpSub: out << "subtract"; break;
michael@0 110 case EOpMul: out << "component-wise multiply"; break;
michael@0 111 case EOpDiv: out << "divide"; break;
michael@0 112 case EOpEqual: out << "Compare Equal"; break;
michael@0 113 case EOpNotEqual: out << "Compare Not Equal"; break;
michael@0 114 case EOpLessThan: out << "Compare Less Than"; break;
michael@0 115 case EOpGreaterThan: out << "Compare Greater Than"; break;
michael@0 116 case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
michael@0 117 case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
michael@0 118
michael@0 119 case EOpVectorTimesScalar: out << "vector-scale"; break;
michael@0 120 case EOpVectorTimesMatrix: out << "vector-times-matrix"; break;
michael@0 121 case EOpMatrixTimesVector: out << "matrix-times-vector"; break;
michael@0 122 case EOpMatrixTimesScalar: out << "matrix-scale"; break;
michael@0 123 case EOpMatrixTimesMatrix: out << "matrix-multiply"; break;
michael@0 124
michael@0 125 case EOpLogicalOr: out << "logical-or"; break;
michael@0 126 case EOpLogicalXor: out << "logical-xor"; break;
michael@0 127 case EOpLogicalAnd: out << "logical-and"; break;
michael@0 128 default: out << "<unknown op>";
michael@0 129 }
michael@0 130
michael@0 131 out << " (" << node->getCompleteString() << ")";
michael@0 132
michael@0 133 out << "\n";
michael@0 134
michael@0 135 return true;
michael@0 136 }
michael@0 137
michael@0 138 bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
michael@0 139 {
michael@0 140 TInfoSinkBase& out = sink;
michael@0 141
michael@0 142 OutputTreeText(out, node, depth);
michael@0 143
michael@0 144 switch (node->getOp()) {
michael@0 145 case EOpNegative: out << "Negate value"; break;
michael@0 146 case EOpVectorLogicalNot:
michael@0 147 case EOpLogicalNot: out << "Negate conditional"; break;
michael@0 148
michael@0 149 case EOpPostIncrement: out << "Post-Increment"; break;
michael@0 150 case EOpPostDecrement: out << "Post-Decrement"; break;
michael@0 151 case EOpPreIncrement: out << "Pre-Increment"; break;
michael@0 152 case EOpPreDecrement: out << "Pre-Decrement"; break;
michael@0 153
michael@0 154 case EOpConvIntToBool: out << "Convert int to bool"; break;
michael@0 155 case EOpConvFloatToBool:out << "Convert float to bool";break;
michael@0 156 case EOpConvBoolToFloat:out << "Convert bool to float";break;
michael@0 157 case EOpConvIntToFloat: out << "Convert int to float"; break;
michael@0 158 case EOpConvFloatToInt: out << "Convert float to int"; break;
michael@0 159 case EOpConvBoolToInt: out << "Convert bool to int"; break;
michael@0 160
michael@0 161 case EOpRadians: out << "radians"; break;
michael@0 162 case EOpDegrees: out << "degrees"; break;
michael@0 163 case EOpSin: out << "sine"; break;
michael@0 164 case EOpCos: out << "cosine"; break;
michael@0 165 case EOpTan: out << "tangent"; break;
michael@0 166 case EOpAsin: out << "arc sine"; break;
michael@0 167 case EOpAcos: out << "arc cosine"; break;
michael@0 168 case EOpAtan: out << "arc tangent"; break;
michael@0 169
michael@0 170 case EOpExp: out << "exp"; break;
michael@0 171 case EOpLog: out << "log"; break;
michael@0 172 case EOpExp2: out << "exp2"; break;
michael@0 173 case EOpLog2: out << "log2"; break;
michael@0 174 case EOpSqrt: out << "sqrt"; break;
michael@0 175 case EOpInverseSqrt: out << "inverse sqrt"; break;
michael@0 176
michael@0 177 case EOpAbs: out << "Absolute value"; break;
michael@0 178 case EOpSign: out << "Sign"; break;
michael@0 179 case EOpFloor: out << "Floor"; break;
michael@0 180 case EOpCeil: out << "Ceiling"; break;
michael@0 181 case EOpFract: out << "Fraction"; break;
michael@0 182
michael@0 183 case EOpLength: out << "length"; break;
michael@0 184 case EOpNormalize: out << "normalize"; break;
michael@0 185 // case EOpDPdx: out << "dPdx"; break;
michael@0 186 // case EOpDPdy: out << "dPdy"; break;
michael@0 187 // case EOpFwidth: out << "fwidth"; break;
michael@0 188
michael@0 189 case EOpAny: out << "any"; break;
michael@0 190 case EOpAll: out << "all"; break;
michael@0 191
michael@0 192 default:
michael@0 193 out.prefix(EPrefixError);
michael@0 194 out << "Bad unary op";
michael@0 195 }
michael@0 196
michael@0 197 out << " (" << node->getCompleteString() << ")";
michael@0 198
michael@0 199 out << "\n";
michael@0 200
michael@0 201 return true;
michael@0 202 }
michael@0 203
michael@0 204 bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
michael@0 205 {
michael@0 206 TInfoSinkBase& out = sink;
michael@0 207
michael@0 208 if (node->getOp() == EOpNull) {
michael@0 209 out.prefix(EPrefixError);
michael@0 210 out << "node is still EOpNull!";
michael@0 211 return true;
michael@0 212 }
michael@0 213
michael@0 214 OutputTreeText(out, node, depth);
michael@0 215
michael@0 216 switch (node->getOp()) {
michael@0 217 case EOpSequence: out << "Sequence\n"; return true;
michael@0 218 case EOpComma: out << "Comma\n"; return true;
michael@0 219 case EOpFunction: out << "Function Definition: " << node->getName(); break;
michael@0 220 case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
michael@0 221 case EOpParameters: out << "Function Parameters: "; break;
michael@0 222
michael@0 223 case EOpConstructFloat: out << "Construct float"; break;
michael@0 224 case EOpConstructVec2: out << "Construct vec2"; break;
michael@0 225 case EOpConstructVec3: out << "Construct vec3"; break;
michael@0 226 case EOpConstructVec4: out << "Construct vec4"; break;
michael@0 227 case EOpConstructBool: out << "Construct bool"; break;
michael@0 228 case EOpConstructBVec2: out << "Construct bvec2"; break;
michael@0 229 case EOpConstructBVec3: out << "Construct bvec3"; break;
michael@0 230 case EOpConstructBVec4: out << "Construct bvec4"; break;
michael@0 231 case EOpConstructInt: out << "Construct int"; break;
michael@0 232 case EOpConstructIVec2: out << "Construct ivec2"; break;
michael@0 233 case EOpConstructIVec3: out << "Construct ivec3"; break;
michael@0 234 case EOpConstructIVec4: out << "Construct ivec4"; break;
michael@0 235 case EOpConstructMat2: out << "Construct mat2"; break;
michael@0 236 case EOpConstructMat3: out << "Construct mat3"; break;
michael@0 237 case EOpConstructMat4: out << "Construct mat4"; break;
michael@0 238 case EOpConstructStruct: out << "Construct structure"; break;
michael@0 239
michael@0 240 case EOpLessThan: out << "Compare Less Than"; break;
michael@0 241 case EOpGreaterThan: out << "Compare Greater Than"; break;
michael@0 242 case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
michael@0 243 case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
michael@0 244 case EOpVectorEqual: out << "Equal"; break;
michael@0 245 case EOpVectorNotEqual: out << "NotEqual"; break;
michael@0 246
michael@0 247 case EOpMod: out << "mod"; break;
michael@0 248 case EOpPow: out << "pow"; break;
michael@0 249
michael@0 250 case EOpAtan: out << "arc tangent"; break;
michael@0 251
michael@0 252 case EOpMin: out << "min"; break;
michael@0 253 case EOpMax: out << "max"; break;
michael@0 254 case EOpClamp: out << "clamp"; break;
michael@0 255 case EOpMix: out << "mix"; break;
michael@0 256 case EOpStep: out << "step"; break;
michael@0 257 case EOpSmoothStep: out << "smoothstep"; break;
michael@0 258
michael@0 259 case EOpDistance: out << "distance"; break;
michael@0 260 case EOpDot: out << "dot-product"; break;
michael@0 261 case EOpCross: out << "cross-product"; break;
michael@0 262 case EOpFaceForward: out << "face-forward"; break;
michael@0 263 case EOpReflect: out << "reflect"; break;
michael@0 264 case EOpRefract: out << "refract"; break;
michael@0 265 case EOpMul: out << "component-wise multiply"; break;
michael@0 266
michael@0 267 case EOpDeclaration: out << "Declaration: "; break;
michael@0 268
michael@0 269 default:
michael@0 270 out.prefix(EPrefixError);
michael@0 271 out << "Bad aggregation op";
michael@0 272 }
michael@0 273
michael@0 274 if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
michael@0 275 out << " (" << node->getCompleteString() << ")";
michael@0 276
michael@0 277 out << "\n";
michael@0 278
michael@0 279 return true;
michael@0 280 }
michael@0 281
michael@0 282 bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
michael@0 283 {
michael@0 284 TInfoSinkBase& out = sink;
michael@0 285
michael@0 286 OutputTreeText(out, node, depth);
michael@0 287
michael@0 288 out << "Test condition and select";
michael@0 289 out << " (" << node->getCompleteString() << ")\n";
michael@0 290
michael@0 291 ++depth;
michael@0 292
michael@0 293 OutputTreeText(sink, node, depth);
michael@0 294 out << "Condition\n";
michael@0 295 node->getCondition()->traverse(this);
michael@0 296
michael@0 297 OutputTreeText(sink, node, depth);
michael@0 298 if (node->getTrueBlock()) {
michael@0 299 out << "true case\n";
michael@0 300 node->getTrueBlock()->traverse(this);
michael@0 301 } else
michael@0 302 out << "true case is null\n";
michael@0 303
michael@0 304 if (node->getFalseBlock()) {
michael@0 305 OutputTreeText(sink, node, depth);
michael@0 306 out << "false case\n";
michael@0 307 node->getFalseBlock()->traverse(this);
michael@0 308 }
michael@0 309
michael@0 310 --depth;
michael@0 311
michael@0 312 return false;
michael@0 313 }
michael@0 314
michael@0 315 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
michael@0 316 {
michael@0 317 TInfoSinkBase& out = sink;
michael@0 318
michael@0 319 size_t size = node->getType().getObjectSize();
michael@0 320
michael@0 321 for (size_t i = 0; i < size; i++) {
michael@0 322 OutputTreeText(out, node, depth);
michael@0 323 switch (node->getUnionArrayPointer()[i].getType()) {
michael@0 324 case EbtBool:
michael@0 325 if (node->getUnionArrayPointer()[i].getBConst())
michael@0 326 out << "true";
michael@0 327 else
michael@0 328 out << "false";
michael@0 329
michael@0 330 out << " (" << "const bool" << ")";
michael@0 331 out << "\n";
michael@0 332 break;
michael@0 333 case EbtFloat:
michael@0 334 out << node->getUnionArrayPointer()[i].getFConst();
michael@0 335 out << " (const float)\n";
michael@0 336 break;
michael@0 337 case EbtInt:
michael@0 338 out << node->getUnionArrayPointer()[i].getIConst();
michael@0 339 out << " (const int)\n";
michael@0 340 break;
michael@0 341 default:
michael@0 342 out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
michael@0 343 break;
michael@0 344 }
michael@0 345 }
michael@0 346 }
michael@0 347
michael@0 348 bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
michael@0 349 {
michael@0 350 TInfoSinkBase& out = sink;
michael@0 351
michael@0 352 OutputTreeText(out, node, depth);
michael@0 353
michael@0 354 out << "Loop with condition ";
michael@0 355 if (node->getType() == ELoopDoWhile)
michael@0 356 out << "not ";
michael@0 357 out << "tested first\n";
michael@0 358
michael@0 359 ++depth;
michael@0 360
michael@0 361 OutputTreeText(sink, node, depth);
michael@0 362 if (node->getCondition()) {
michael@0 363 out << "Loop Condition\n";
michael@0 364 node->getCondition()->traverse(this);
michael@0 365 } else
michael@0 366 out << "No loop condition\n";
michael@0 367
michael@0 368 OutputTreeText(sink, node, depth);
michael@0 369 if (node->getBody()) {
michael@0 370 out << "Loop Body\n";
michael@0 371 node->getBody()->traverse(this);
michael@0 372 } else
michael@0 373 out << "No loop body\n";
michael@0 374
michael@0 375 if (node->getExpression()) {
michael@0 376 OutputTreeText(sink, node, depth);
michael@0 377 out << "Loop Terminal Expression\n";
michael@0 378 node->getExpression()->traverse(this);
michael@0 379 }
michael@0 380
michael@0 381 --depth;
michael@0 382
michael@0 383 return false;
michael@0 384 }
michael@0 385
michael@0 386 bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
michael@0 387 {
michael@0 388 TInfoSinkBase& out = sink;
michael@0 389
michael@0 390 OutputTreeText(out, node, depth);
michael@0 391
michael@0 392 switch (node->getFlowOp()) {
michael@0 393 case EOpKill: out << "Branch: Kill"; break;
michael@0 394 case EOpBreak: out << "Branch: Break"; break;
michael@0 395 case EOpContinue: out << "Branch: Continue"; break;
michael@0 396 case EOpReturn: out << "Branch: Return"; break;
michael@0 397 default: out << "Branch: Unknown Branch"; break;
michael@0 398 }
michael@0 399
michael@0 400 if (node->getExpression()) {
michael@0 401 out << " with expression\n";
michael@0 402 ++depth;
michael@0 403 node->getExpression()->traverse(this);
michael@0 404 --depth;
michael@0 405 } else
michael@0 406 out << "\n";
michael@0 407
michael@0 408 return false;
michael@0 409 }
michael@0 410
michael@0 411 //
michael@0 412 // This function is the one to call externally to start the traversal.
michael@0 413 // Individual functions can be initialized to 0 to skip processing of that
michael@0 414 // type of node. It's children will still be processed.
michael@0 415 //
michael@0 416 void TIntermediate::outputTree(TIntermNode* root)
michael@0 417 {
michael@0 418 if (root == 0)
michael@0 419 return;
michael@0 420
michael@0 421 TOutputTraverser it(infoSink.info);
michael@0 422
michael@0 423 root->traverse(&it);
michael@0 424 }

mercurial