Commit 1776fd08 by Olli Etuaho Committed by Commit Bot

Make use of CreateBoolNode in traversers

This is just refactoring to clean up some duplicate code. A new test is added to make sure this doesn't break UnfoldShortCircuitAST. BUG=angleproject:1490 TEST=angle_unittests Change-Id: I108e646f71ba631cbd5dad2055b64e6a30159742 Reviewed-on: https://chromium-review.googlesource.com/894207Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 15443eba
......@@ -6,6 +6,7 @@
#include "compiler/translator/AddAndTrueToLoopCondition.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
namespace sh
......@@ -36,9 +37,7 @@ class AddAndTrueToLoopConditionTraverser : public TIntermTraverser
}
// Constant true.
TConstantUnion *trueConstant = new TConstantUnion();
trueConstant->setBConst(true);
TIntermTyped *trueValue = new TIntermConstantUnion(trueConstant, TType(EbtBool));
TIntermTyped *trueValue = CreateBoolNode(true);
// CONDITION && true.
TIntermBinary *andOp = new TIntermBinary(EOpLogicalAnd, loop->getCondition(), trueValue);
......
......@@ -495,13 +495,11 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root,
RewriteDoWhile(root, &symbolTable);
if (compileOptions & SH_ADD_AND_TRUE_TO_LOOP_CONDITION)
sh::AddAndTrueToLoopCondition(root);
AddAndTrueToLoopCondition(root);
if (compileOptions & SH_UNFOLD_SHORT_CIRCUIT)
{
UnfoldShortCircuitAST unfoldShortCircuit;
root->traverse(&unfoldShortCircuit);
unfoldShortCircuit.updateTree();
UnfoldShortCircuitAST(root);
}
if (compileOptions & SH_REMOVE_POW_WITH_CONSTANT_EXPONENT)
......
......@@ -6,6 +6,10 @@
#include "compiler/translator/UnfoldShortCircuitAST.h"
#include "compiler/translator/IntermNode.h"
#include "compiler/translator/IntermNode_util.h"
#include "compiler/translator/IntermTraverse.h"
namespace sh
{
......@@ -15,26 +19,28 @@ namespace
// "x || y" is equivalent to "x ? true : y".
TIntermTernary *UnfoldOR(TIntermTyped *x, TIntermTyped *y)
{
TConstantUnion *u = new TConstantUnion;
u->setBConst(true);
TIntermConstantUnion *trueNode =
new TIntermConstantUnion(u, TType(EbtBool, EbpUndefined, EvqConst, 1));
return new TIntermTernary(x, trueNode, y);
return new TIntermTernary(x, CreateBoolNode(true), y);
}
// "x && y" is equivalent to "x ? y : false".
TIntermTernary *UnfoldAND(TIntermTyped *x, TIntermTyped *y)
{
TConstantUnion *u = new TConstantUnion;
u->setBConst(false);
TIntermConstantUnion *falseNode =
new TIntermConstantUnion(u, TType(EbtBool, EbpUndefined, EvqConst, 1));
return new TIntermTernary(x, y, falseNode);
return new TIntermTernary(x, y, CreateBoolNode(false));
}
} // namespace anonymous
// This traverser identifies all the short circuit binary nodes that need to
// be replaced, and creates the corresponding replacement nodes. However,
// the actual replacements happen after the traverse through updateTree().
class UnfoldShortCircuitASTTraverser : public TIntermTraverser
{
public:
UnfoldShortCircuitASTTraverser() : TIntermTraverser(true, false, false) {}
bool visitBinary(Visit visit, TIntermBinary *) override;
};
bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node)
bool UnfoldShortCircuitASTTraverser::visitBinary(Visit visit, TIntermBinary *node)
{
TIntermTernary *replacement = nullptr;
......@@ -56,4 +62,13 @@ bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node)
return true;
}
} // anonymous namespace
void UnfoldShortCircuitAST(TIntermBlock *root)
{
UnfoldShortCircuitASTTraverser traverser;
root->traverse(&traverser);
traverser.updateTree();
}
} // namespace sh
......@@ -10,23 +10,12 @@
#ifndef COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
#define COMPILER_TRANSLATOR_UNFOLDSHORTCIRCUITAST_H_
#include "common/angleutils.h"
#include "compiler/translator/IntermTraverse.h"
namespace sh
{
// This traverser identifies all the short circuit binary nodes that need to
// be replaced, and creates the corresponding replacement nodes. However,
// the actual replacements happen after the traverse through updateTree().
class UnfoldShortCircuitAST : public TIntermTraverser
{
public:
UnfoldShortCircuitAST() : TIntermTraverser(true, false, false) {}
class TIntermBlock;
bool visitBinary(Visit visit, TIntermBinary *) override;
};
void UnfoldShortCircuitAST(TIntermBlock *root);
} // namespace sh
......
......@@ -91,6 +91,7 @@
'<(angle_path)/src/tests/compiler_tests/ShaderVariable_test.cpp',
'<(angle_path)/src/tests/compiler_tests/ShCompile_test.cpp',
'<(angle_path)/src/tests/compiler_tests/TypeTracking_test.cpp',
'<(angle_path)/src/tests/compiler_tests/UnfoldShortCircuitAST_test.cpp',
'<(angle_path)/src/tests/compiler_tests/VariablePacker_test.cpp',
'<(angle_path)/src/tests/compiler_tests/VectorizeVectorScalarArithmetic_test.cpp',
'<(angle_path)/src/tests/compiler_tests/WEBGL_multiview_test.cpp',
......
//
// Copyright (c) 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// UnfoldShortCircuitAST_test.cpp:
// Tests shader compilation with SH_UNFOLD_SHORT_CIRCUIT workaround on.
#include "GLSLANG/ShaderLang.h"
#include "angle_gl.h"
#include "gtest/gtest.h"
#include "tests/test_utils/compiler_test.h"
using namespace sh;
class UnfoldShortCircuitASTTest : public MatchOutputCodeTest
{
public:
UnfoldShortCircuitASTTest()
: MatchOutputCodeTest(GL_FRAGMENT_SHADER, SH_UNFOLD_SHORT_CIRCUIT, SH_GLSL_330_CORE_OUTPUT)
{
}
};
// Test unfolding the && operator.
TEST_F(UnfoldShortCircuitASTTest, UnfoldAnd)
{
const std::string &shaderString =
R"(#version 300 es
precision highp float;
out vec4 color;
uniform bool b;
uniform bool b2;
void main()
{
color = vec4(0, 0, 0, 1);
if (b && b2)
{
color = vec4(0, 1, 0, 1);
}
})";
compile(shaderString);
ASSERT_TRUE(foundInCode("(_ub) ? (_ub2) : (false)"));
}
// Test unfolding the || operator.
TEST_F(UnfoldShortCircuitASTTest, UnfoldOr)
{
const std::string &shaderString =
R"(#version 300 es
precision highp float;
out vec4 color;
uniform bool b;
uniform bool b2;
void main()
{
color = vec4(0, 0, 0, 1);
if (b || b2)
{
color = vec4(0, 1, 0, 1);
}
})";
compile(shaderString);
ASSERT_TRUE(foundInCode("(_ub) ? (true) : (_ub2)"));
}
// Test unfolding nested && and || operators. Both should be unfolded.
TEST_F(UnfoldShortCircuitASTTest, UnfoldNested)
{
const std::string &shaderString =
R"(#version 300 es
precision highp float;
out vec4 color;
uniform bool b;
uniform bool b2;
uniform bool b3;
void main()
{
color = vec4(0, 0, 0, 1);
if (b && (b2 || b3))
{
color = vec4(0, 1, 0, 1);
}
})";
compile(shaderString);
ASSERT_TRUE(foundInCode("(_ub) ? (((_ub2) ? (true) : (_ub3))) : (false)"));
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment