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 7 #include "compiler/translator/RewriteUnaryMinusOperatorFloat.h" 8 9 #include "compiler/translator/IntermNode_util.h" 10 #include "compiler/translator/IntermTraverse.h" 11 12 namespace sh 13 { 14 15 namespace 16 { 17 18 class Traverser : public TIntermTraverser 19 { 20 public: 21 static void Apply(TIntermNode *root); 22 23 private: 24 Traverser(); 25 bool visitUnary(Visit visit, TIntermUnary *node) override; 26 void nextIteration(); 27 28 bool mFound = false; 29 }; 30 31 // static Apply(TIntermNode * root)32void Traverser::Apply(TIntermNode *root) 33 { 34 Traverser traverser; 35 do 36 { 37 traverser.nextIteration(); 38 root->traverse(&traverser); 39 if (traverser.mFound) 40 { 41 traverser.updateTree(); 42 } 43 } while (traverser.mFound); 44 } 45 Traverser()46Traverser::Traverser() : TIntermTraverser(true, false, false) 47 { 48 } 49 nextIteration()50void Traverser::nextIteration() 51 { 52 mFound = false; 53 } 54 visitUnary(Visit visit,TIntermUnary * node)55bool Traverser::visitUnary(Visit visit, TIntermUnary *node) 56 { 57 if (mFound) 58 { 59 return false; 60 } 61 62 // Detect if the current operator is unary minus operator. 63 if (node->getOp() != EOpNegative) 64 { 65 return true; 66 } 67 68 // Detect if the current operand is a float variable. 69 TIntermTyped *fValue = node->getOperand(); 70 if (!fValue->getType().isScalarFloat()) 71 { 72 return true; 73 } 74 75 // 0.0 - float 76 TIntermTyped *zero = CreateZeroNode(fValue->getType()); 77 zero->setLine(fValue->getLine()); 78 TIntermBinary *sub = new TIntermBinary(EOpSub, zero, fValue); 79 sub->setLine(fValue->getLine()); 80 81 queueReplacement(sub, OriginalNode::IS_DROPPED); 82 83 mFound = true; 84 return false; 85 } 86 87 } // anonymous namespace 88 RewriteUnaryMinusOperatorFloat(TIntermNode * root)89void RewriteUnaryMinusOperatorFloat(TIntermNode *root) 90 { 91 Traverser::Apply(root); 92 } 93 94 } // namespace sh 95