LCOV - code coverage report
Current view: top level - gfx/angle/src/compiler/translator - SplitSequenceOperator.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 56 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2016 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             : // SplitSequenceOperator is an AST traverser that detects sequence operator expressions that
       7             : // go through further AST transformations that generate statements, and splits them so that
       8             : // possible side effects of earlier parts of the sequence operator expression are guaranteed to be
       9             : // evaluated before the latter parts of the sequence operator expression are evaluated.
      10             : //
      11             : 
      12             : #include "compiler/translator/SplitSequenceOperator.h"
      13             : 
      14             : #include "compiler/translator/IntermNode.h"
      15             : #include "compiler/translator/IntermNodePatternMatcher.h"
      16             : 
      17             : namespace sh
      18             : {
      19             : 
      20             : namespace
      21             : {
      22             : 
      23           0 : class SplitSequenceOperatorTraverser : public TLValueTrackingTraverser
      24             : {
      25             :   public:
      26             :     SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask,
      27             :                                    const TSymbolTable &symbolTable,
      28             :                                    int shaderVersion);
      29             : 
      30             :     bool visitBinary(Visit visit, TIntermBinary *node) override;
      31             :     bool visitAggregate(Visit visit, TIntermAggregate *node) override;
      32             :     bool visitTernary(Visit visit, TIntermTernary *node) override;
      33             : 
      34             :     void nextIteration();
      35           0 :     bool foundExpressionToSplit() const { return mFoundExpressionToSplit; }
      36             : 
      37             :   protected:
      38             :     // Marked to true once an operation that needs to be hoisted out of the expression has been
      39             :     // found. After that, no more AST updates are performed on that traversal.
      40             :     bool mFoundExpressionToSplit;
      41             :     int mInsideSequenceOperator;
      42             : 
      43             :     IntermNodePatternMatcher mPatternToSplitMatcher;
      44             : };
      45             : 
      46           0 : SplitSequenceOperatorTraverser::SplitSequenceOperatorTraverser(unsigned int patternsToSplitMask,
      47             :                                                                const TSymbolTable &symbolTable,
      48           0 :                                                                int shaderVersion)
      49             :     : TLValueTrackingTraverser(true, false, true, symbolTable, shaderVersion),
      50             :       mFoundExpressionToSplit(false),
      51             :       mInsideSequenceOperator(0),
      52           0 :       mPatternToSplitMatcher(patternsToSplitMask)
      53             : {
      54           0 : }
      55             : 
      56           0 : void SplitSequenceOperatorTraverser::nextIteration()
      57             : {
      58           0 :     mFoundExpressionToSplit = false;
      59           0 :     mInsideSequenceOperator = 0;
      60           0 :     nextTemporaryIndex();
      61           0 : }
      62             : 
      63           0 : bool SplitSequenceOperatorTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
      64             : {
      65           0 :     if (mFoundExpressionToSplit)
      66           0 :         return false;
      67             : 
      68           0 :     if (mInsideSequenceOperator > 0 && visit == PreVisit)
      69             :     {
      70             :         // Detect expressions that need to be simplified
      71           0 :         mFoundExpressionToSplit = mPatternToSplitMatcher.match(node, getParentNode());
      72           0 :         return !mFoundExpressionToSplit;
      73             :     }
      74             : 
      75           0 :     return true;
      76             : }
      77             : 
      78           0 : bool SplitSequenceOperatorTraverser::visitBinary(Visit visit, TIntermBinary *node)
      79             : {
      80           0 :     if (node->getOp() == EOpComma)
      81             :     {
      82           0 :         if (visit == PreVisit)
      83             :         {
      84           0 :             if (mFoundExpressionToSplit)
      85             :             {
      86           0 :                 return false;
      87             :             }
      88           0 :             mInsideSequenceOperator++;
      89             :         }
      90           0 :         else if (visit == PostVisit)
      91             :         {
      92             :             // Split sequence operators starting from the outermost one to preserve correct
      93             :             // execution order.
      94           0 :             if (mFoundExpressionToSplit && mInsideSequenceOperator == 1)
      95             :             {
      96             :                 // Move the left side operand into a separate statement in the parent block.
      97           0 :                 TIntermSequence insertions;
      98           0 :                 insertions.push_back(node->getLeft());
      99           0 :                 insertStatementsInParentBlock(insertions);
     100             :                 // Replace the comma node with its right side operand.
     101           0 :                 queueReplacement(node, node->getRight(), OriginalNode::IS_DROPPED);
     102             :             }
     103           0 :             mInsideSequenceOperator--;
     104             :         }
     105           0 :         return true;
     106             :     }
     107             : 
     108           0 :     if (mFoundExpressionToSplit)
     109           0 :         return false;
     110             : 
     111           0 :     if (mInsideSequenceOperator > 0 && visit == PreVisit)
     112             :     {
     113             :         // Detect expressions that need to be simplified
     114           0 :         mFoundExpressionToSplit =
     115           0 :             mPatternToSplitMatcher.match(node, getParentNode(), isLValueRequiredHere());
     116           0 :         return !mFoundExpressionToSplit;
     117             :     }
     118             : 
     119           0 :     return true;
     120             : }
     121             : 
     122           0 : bool SplitSequenceOperatorTraverser::visitTernary(Visit visit, TIntermTernary *node)
     123             : {
     124           0 :     if (mFoundExpressionToSplit)
     125           0 :         return false;
     126             : 
     127           0 :     if (mInsideSequenceOperator > 0 && visit == PreVisit)
     128             :     {
     129             :         // Detect expressions that need to be simplified
     130           0 :         mFoundExpressionToSplit = mPatternToSplitMatcher.match(node);
     131           0 :         return !mFoundExpressionToSplit;
     132             :     }
     133             : 
     134           0 :     return true;
     135             : }
     136             : 
     137             : }  // namespace
     138             : 
     139           0 : void SplitSequenceOperator(TIntermNode *root,
     140             :                            int patternsToSplitMask,
     141             :                            unsigned int *temporaryIndex,
     142             :                            const TSymbolTable &symbolTable,
     143             :                            int shaderVersion)
     144             : {
     145           0 :     SplitSequenceOperatorTraverser traverser(patternsToSplitMask, symbolTable, shaderVersion);
     146           0 :     ASSERT(temporaryIndex != nullptr);
     147           0 :     traverser.useTemporaryIndex(temporaryIndex);
     148             :     // Separate one expression at a time, and reset the traverser between iterations.
     149           0 :     do
     150             :     {
     151           0 :         traverser.nextIteration();
     152           0 :         root->traverse(&traverser);
     153           0 :         if (traverser.foundExpressionToSplit())
     154           0 :             traverser.updateTree();
     155             :     } while (traverser.foundExpressionToSplit());
     156           0 : }
     157             : 
     158             : }  // namespace sh

Generated by: LCOV version 1.13