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

          Line data    Source code
       1             : //
       2             : // Copyright (c) 2014 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             : // RewriteElseBlocks.cpp: Implementation for tree transform to change
       7             : //   all if-else blocks to if-if blocks.
       8             : //
       9             : 
      10             : #include "compiler/translator/RewriteElseBlocks.h"
      11             : 
      12             : #include "compiler/translator/Intermediate.h"
      13             : #include "compiler/translator/NodeSearch.h"
      14             : #include "compiler/translator/SymbolTable.h"
      15             : 
      16             : namespace sh
      17             : {
      18             : 
      19             : namespace
      20             : {
      21             : 
      22           0 : class ElseBlockRewriter : public TIntermTraverser
      23             : {
      24             :   public:
      25             :     ElseBlockRewriter();
      26             : 
      27             :   protected:
      28             :     bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *aggregate) override;
      29             :     bool visitBlock(Visit visit, TIntermBlock *block) override;
      30             : 
      31             :   private:
      32             :     const TType *mFunctionType;
      33             : 
      34             :     TIntermNode *rewriteIfElse(TIntermIfElse *ifElse);
      35             : };
      36             : 
      37           0 : ElseBlockRewriter::ElseBlockRewriter()
      38             :     : TIntermTraverser(true, false, true),
      39           0 :       mFunctionType(NULL)
      40           0 : {}
      41             : 
      42           0 : bool ElseBlockRewriter::visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node)
      43             : {
      44             :     // Store the current function context (see comment below)
      45           0 :     mFunctionType = ((visit == PreVisit) ? &node->getType() : nullptr);
      46           0 :     return true;
      47             : }
      48             : 
      49           0 : bool ElseBlockRewriter::visitBlock(Visit visit, TIntermBlock *node)
      50             : {
      51           0 :     if (visit == PostVisit)
      52             :     {
      53           0 :         for (size_t statementIndex = 0; statementIndex != node->getSequence()->size();
      54             :              statementIndex++)
      55             :         {
      56           0 :             TIntermNode *statement = (*node->getSequence())[statementIndex];
      57           0 :             TIntermIfElse *ifElse  = statement->getAsIfElseNode();
      58           0 :             if (ifElse && ifElse->getFalseBlock() != nullptr)
      59             :             {
      60           0 :                 (*node->getSequence())[statementIndex] = rewriteIfElse(ifElse);
      61             :             }
      62             :         }
      63             :     }
      64           0 :     return true;
      65             : }
      66             : 
      67           0 : TIntermNode *ElseBlockRewriter::rewriteIfElse(TIntermIfElse *ifElse)
      68             : {
      69           0 :     ASSERT(ifElse != nullptr);
      70             : 
      71           0 :     nextTemporaryIndex();
      72             : 
      73           0 :     TIntermDeclaration *storeCondition = createTempInitDeclaration(ifElse->getCondition());
      74             : 
      75           0 :     TIntermBlock *falseBlock = nullptr;
      76             : 
      77           0 :     TType boolType(EbtBool, EbpUndefined, EvqTemporary);
      78             : 
      79           0 :     if (ifElse->getFalseBlock())
      80             :     {
      81           0 :         TIntermBlock *negatedElse = nullptr;
      82             :         // crbug.com/346463
      83             :         // D3D generates error messages claiming a function has no return value, when rewriting
      84             :         // an if-else clause that returns something non-void in a function. By appending dummy
      85             :         // returns (that are unreachable) we can silence this compile error.
      86           0 :         if (mFunctionType && mFunctionType->getBasicType() != EbtVoid)
      87             :         {
      88           0 :             TString typeString = mFunctionType->getStruct() ? mFunctionType->getStruct()->name() :
      89           0 :                 mFunctionType->getBasicString();
      90           0 :             TString rawText = "return (" + typeString + ")0";
      91           0 :             TIntermRaw *returnNode = new TIntermRaw(*mFunctionType, rawText);
      92           0 :             negatedElse            = new TIntermBlock();
      93           0 :             negatedElse->getSequence()->push_back(returnNode);
      94             :         }
      95             : 
      96           0 :         TIntermSymbol *conditionSymbolElse = createTempSymbol(boolType);
      97           0 :         TIntermUnary *negatedCondition     = new TIntermUnary(EOpLogicalNot, conditionSymbolElse);
      98             :         TIntermIfElse *falseIfElse =
      99           0 :             new TIntermIfElse(negatedCondition, ifElse->getFalseBlock(), negatedElse);
     100           0 :         falseBlock = TIntermediate::EnsureBlock(falseIfElse);
     101             :     }
     102             : 
     103           0 :     TIntermSymbol *conditionSymbolSel = createTempSymbol(boolType);
     104             :     TIntermIfElse *newIfElse =
     105           0 :         new TIntermIfElse(conditionSymbolSel, ifElse->getTrueBlock(), falseBlock);
     106             : 
     107           0 :     TIntermBlock *block = new TIntermBlock();
     108           0 :     block->getSequence()->push_back(storeCondition);
     109           0 :     block->getSequence()->push_back(newIfElse);
     110             : 
     111           0 :     return block;
     112             : }
     113             : 
     114             : }
     115             : 
     116           0 : void RewriteElseBlocks(TIntermNode *node, unsigned int *temporaryIndex)
     117             : {
     118           0 :     ElseBlockRewriter rewriter;
     119           0 :     rewriter.useTemporaryIndex(temporaryIndex);
     120           0 :     node->traverse(&rewriter);
     121           0 : }
     122             : 
     123             : }

Generated by: LCOV version 1.13