LCOV - code coverage report
Current view: directory - gfx/angle/src/compiler - intermOut.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 248 0 0.0 %
Date: 2012-06-02 Functions: 12 0 0.0 %

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

Generated by: LCOV version 1.7