gfx/angle/src/compiler/intermOut.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial