Shader: Rename Optimize to ConstantPropagation

This commit is contained in:
Jérôme Leclercq 2022-02-22 13:28:01 +01:00
parent 20a86312ff
commit 7ece44b4f4
11 changed files with 118 additions and 114 deletions

View File

@ -4,8 +4,8 @@
#pragma once
#ifndef NAZARA_SHADER_AST_ASTOPTIMIZER_HPP
#define NAZARA_SHADER_AST_ASTOPTIMIZER_HPP
#ifndef NAZARA_SHADER_AST_ASTCONSTANTPROPAGATIONVISITOR_HPP
#define NAZARA_SHADER_AST_ASTCONSTANTPROPAGATIONVISITOR_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Shader/Config.hpp>
@ -16,23 +16,23 @@
namespace Nz::ShaderAst
{
class NAZARA_SHADER_API AstOptimizer : public AstCloner
class NAZARA_SHADER_API AstConstantPropagationVisitor : public AstCloner
{
public:
struct Options;
AstOptimizer() = default;
AstOptimizer(const AstOptimizer&) = delete;
AstOptimizer(AstOptimizer&&) = delete;
~AstOptimizer() = default;
AstConstantPropagationVisitor() = default;
AstConstantPropagationVisitor(const AstConstantPropagationVisitor&) = delete;
AstConstantPropagationVisitor(AstConstantPropagationVisitor&&) = delete;
~AstConstantPropagationVisitor() = default;
inline ExpressionPtr Optimise(Expression& expression);
inline ExpressionPtr Optimise(Expression& expression, const Options& options);
inline StatementPtr Optimise(Statement& statement);
inline StatementPtr Optimise(Statement& statement, const Options& options);
inline ExpressionPtr Process(Expression& expression);
inline ExpressionPtr Process(Expression& expression, const Options& options);
inline StatementPtr Process(Statement& statement);
inline StatementPtr Process(Statement& statement, const Options& options);
AstOptimizer& operator=(const AstOptimizer&) = delete;
AstOptimizer& operator=(AstOptimizer&&) = delete;
AstConstantPropagationVisitor& operator=(const AstConstantPropagationVisitor&) = delete;
AstConstantPropagationVisitor& operator=(AstConstantPropagationVisitor&&) = delete;
struct Options
{
@ -63,12 +63,12 @@ namespace Nz::ShaderAst
Options m_options;
};
inline ExpressionPtr Optimize(Expression& expr);
inline ExpressionPtr Optimize(Expression& expr, const AstOptimizer::Options& options);
inline StatementPtr Optimize(Statement& ast);
inline StatementPtr Optimize(Statement& ast, const AstOptimizer::Options& options);
inline ExpressionPtr PropagateConstants(Expression& expr);
inline ExpressionPtr PropagateConstants(Expression& expr, const AstConstantPropagationVisitor::Options& options);
inline StatementPtr PropagateConstants(Statement& ast);
inline StatementPtr PropagateConstants(Statement& ast, const AstConstantPropagationVisitor::Options& options);
}
#include <Nazara/Shader/Ast/AstOptimizer.inl>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.inl>
#endif // NAZARA_SHADER_AST_ASTOPTIMIZER_HPP
#endif // NAZARA_SHADER_AST_ASTCONSTANTPROPAGATIONVISITOR_HPP

View File

@ -0,0 +1,59 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Shader module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderAst
{
inline ExpressionPtr AstConstantPropagationVisitor::Process(Expression& expression)
{
m_options = {};
return CloneExpression(expression);
}
inline ExpressionPtr AstConstantPropagationVisitor::Process(Expression& expression, const Options& options)
{
m_options = options;
return CloneExpression(expression);
}
inline StatementPtr AstConstantPropagationVisitor::Process(Statement& statement)
{
m_options = {};
return CloneStatement(statement);
}
inline StatementPtr AstConstantPropagationVisitor::Process(Statement& statement, const Options& options)
{
m_options = options;
return CloneStatement(statement);
}
inline ExpressionPtr PropagateConstants(Expression& ast)
{
AstConstantPropagationVisitor optimize;
return optimize.Process(ast);
}
inline ExpressionPtr PropagateConstants(Expression& ast, const AstConstantPropagationVisitor::Options& options)
{
AstConstantPropagationVisitor optimize;
return optimize.Process(ast, options);
}
inline StatementPtr PropagateConstants(Statement& ast)
{
AstConstantPropagationVisitor optimize;
return optimize.Process(ast);
}
inline StatementPtr PropagateConstants(Statement& ast, const AstConstantPropagationVisitor::Options& options)
{
AstConstantPropagationVisitor optimize;
return optimize.Process(ast, options);
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -1,59 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Shader module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Debug.hpp>
namespace Nz::ShaderAst
{
inline ExpressionPtr AstOptimizer::Optimise(Expression& expression)
{
m_options = {};
return CloneExpression(expression);
}
inline ExpressionPtr AstOptimizer::Optimise(Expression& expression, const Options& options)
{
m_options = options;
return CloneExpression(expression);
}
inline StatementPtr AstOptimizer::Optimise(Statement& statement)
{
m_options = {};
return CloneStatement(statement);
}
inline StatementPtr AstOptimizer::Optimise(Statement& statement, const Options& options)
{
m_options = options;
return CloneStatement(statement);
}
inline ExpressionPtr Optimize(Expression& ast)
{
AstOptimizer optimize;
return optimize.Optimise(ast);
}
inline ExpressionPtr Optimize(Expression& ast, const AstOptimizer::Options& options)
{
AstOptimizer optimize;
return optimize.Optimise(ast, options);
}
inline StatementPtr Optimize(Statement& ast)
{
AstOptimizer optimize;
return optimize.Optimise(ast);
}
inline StatementPtr Optimize(Statement& ast, const AstOptimizer::Options& options)
{
AstOptimizer optimize;
return optimize.Optimise(ast, options);
}
}
#include <Nazara/Shader/DebugOff.hpp>

View File

@ -105,7 +105,7 @@ namespace Nz::ShaderAst
ConstantValue ComputeConstantValue(Expression& expr) const;
template<typename T> const T& ComputeExprValue(ExpressionValue<T>& attribute) const;
template<typename T> std::unique_ptr<T> Optimize(T& node) const;
template<typename T> std::unique_ptr<T> PropagateConstants(T& node) const;
void PropagateFunctionFlags(std::size_t funcIndex, FunctionFlags flags, Bitset<>& seen);

View File

@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Shader module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <cassert>
#include <stdexcept>
@ -21,10 +21,14 @@ namespace Nz::ShaderAst
template <typename T>
struct is_complete_helper
{
template <typename U> static auto test(U*)->std::integral_constant<bool, sizeof(U) == sizeof(U)>;
// SFINAE: sizeof in an incomplete type is an error, but since there's another specialization it won't result in a compilation error
template <typename U>
static auto test(U*) -> std::bool_constant<sizeof(U) == sizeof(U)>;
// less specialized overload
static auto test(...) -> std::false_type;
using type = decltype(test((T*)0));
using type = decltype(test(static_cast<T*>(nullptr)));
};
template <typename T>
@ -731,7 +735,7 @@ namespace Nz::ShaderAst
#undef EnableOptimisation
}
ExpressionPtr AstOptimizer::Clone(BinaryExpression& node)
ExpressionPtr AstConstantPropagationVisitor::Clone(BinaryExpression& node)
{
auto lhs = CloneExpression(node.left);
auto rhs = CloneExpression(node.right);
@ -803,7 +807,7 @@ namespace Nz::ShaderAst
return binary;
}
ExpressionPtr AstOptimizer::Clone(CastExpression& node)
ExpressionPtr AstConstantPropagationVisitor::Clone(CastExpression& node)
{
std::array<ExpressionPtr, 4> expressions;
@ -922,7 +926,7 @@ namespace Nz::ShaderAst
return cast;
}
StatementPtr AstOptimizer::Clone(BranchStatement& node)
StatementPtr AstConstantPropagationVisitor::Clone(BranchStatement& node)
{
std::vector<BranchStatement::ConditionalStatement> statements;
StatementPtr elseStatement;
@ -978,7 +982,7 @@ namespace Nz::ShaderAst
return ShaderBuilder::Branch(std::move(statements), std::move(elseStatement));
}
ExpressionPtr AstOptimizer::Clone(ConditionalExpression& node)
ExpressionPtr AstConstantPropagationVisitor::Clone(ConditionalExpression& node)
{
auto cond = CloneExpression(node.condition);
if (cond->GetType() != NodeType::ConstantValueExpression)
@ -999,7 +1003,7 @@ namespace Nz::ShaderAst
return AstCloner::Clone(*node.falsePath);
}
ExpressionPtr AstOptimizer::Clone(ConstantExpression& node)
ExpressionPtr AstConstantPropagationVisitor::Clone(ConstantExpression& node)
{
if (!m_options.constantQueryCallback)
return AstCloner::Clone(node);
@ -1010,7 +1014,7 @@ namespace Nz::ShaderAst
return constant;
}
ExpressionPtr AstOptimizer::Clone(SwizzleExpression& node)
ExpressionPtr AstConstantPropagationVisitor::Clone(SwizzleExpression& node)
{
auto expr = CloneExpression(node.expression);
@ -1061,7 +1065,7 @@ namespace Nz::ShaderAst
return swizzle;
}
ExpressionPtr AstOptimizer::Clone(UnaryExpression& node)
ExpressionPtr AstConstantPropagationVisitor::Clone(UnaryExpression& node)
{
auto expr = CloneExpression(node.expression);
@ -1095,7 +1099,7 @@ namespace Nz::ShaderAst
return unary;
}
StatementPtr AstOptimizer::Clone(ConditionalStatement& node)
StatementPtr AstConstantPropagationVisitor::Clone(ConditionalStatement& node)
{
auto cond = CloneExpression(node.condition);
if (cond->GetType() != NodeType::ConstantValueExpression)
@ -1117,7 +1121,7 @@ namespace Nz::ShaderAst
}
template<BinaryType Type>
ExpressionPtr AstOptimizer::PropagateBinaryConstant(const ConstantValueExpression& lhs, const ConstantValueExpression& rhs)
ExpressionPtr AstConstantPropagationVisitor::PropagateBinaryConstant(const ConstantValueExpression& lhs, const ConstantValueExpression& rhs)
{
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg1)
@ -1146,7 +1150,7 @@ namespace Nz::ShaderAst
}
template<typename TargetType>
ExpressionPtr AstOptimizer::PropagateSingleValueCast(const ConstantValueExpression& operand)
ExpressionPtr AstConstantPropagationVisitor::PropagateSingleValueCast(const ConstantValueExpression& operand)
{
std::unique_ptr<ConstantValueExpression> optimized;
@ -1163,7 +1167,7 @@ namespace Nz::ShaderAst
}
template<std::size_t TargetComponentCount>
ExpressionPtr AstOptimizer::PropagateConstantSwizzle(const std::array<UInt32, 4>& components, const ConstantValueExpression& operand)
ExpressionPtr AstConstantPropagationVisitor::PropagateConstantSwizzle(const std::array<UInt32, 4>& components, const ConstantValueExpression& operand)
{
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg)
@ -1183,7 +1187,7 @@ namespace Nz::ShaderAst
}
template<UnaryType Type>
ExpressionPtr AstOptimizer::PropagateUnaryConstant(const ConstantValueExpression& operand)
ExpressionPtr AstConstantPropagationVisitor::PropagateUnaryConstant(const ConstantValueExpression& operand)
{
std::unique_ptr<ConstantValueExpression> optimized;
std::visit([&](auto&& arg)
@ -1206,7 +1210,7 @@ namespace Nz::ShaderAst
}
template<typename TargetType>
ExpressionPtr AstOptimizer::PropagateVec2Cast(TargetType v1, TargetType v2)
ExpressionPtr AstConstantPropagationVisitor::PropagateVec2Cast(TargetType v1, TargetType v2)
{
std::unique_ptr<ConstantValueExpression> optimized;
@ -1219,7 +1223,7 @@ namespace Nz::ShaderAst
}
template<typename TargetType>
ExpressionPtr AstOptimizer::PropagateVec3Cast(TargetType v1, TargetType v2, TargetType v3)
ExpressionPtr AstConstantPropagationVisitor::PropagateVec3Cast(TargetType v1, TargetType v2, TargetType v3)
{
std::unique_ptr<ConstantValueExpression> optimized;
@ -1232,7 +1236,7 @@ namespace Nz::ShaderAst
}
template<typename TargetType>
ExpressionPtr AstOptimizer::PropagateVec4Cast(TargetType v1, TargetType v2, TargetType v3, TargetType v4)
ExpressionPtr AstConstantPropagationVisitor::PropagateVec4Cast(TargetType v1, TargetType v2, TargetType v3, TargetType v4)
{
std::unique_ptr<ConstantValueExpression> optimized;
@ -1245,7 +1249,7 @@ namespace Nz::ShaderAst
}
StatementPtr AstOptimizer::Unscope(StatementPtr node)
StatementPtr AstConstantPropagationVisitor::Unscope(StatementPtr node)
{
assert(node);

View File

@ -8,7 +8,7 @@
#include <Nazara/Core/StackArray.hpp>
#include <Nazara/Core/StackVector.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
#include <Nazara/Shader/Ast/AstUtils.hpp>
#include <numeric>
@ -719,7 +719,7 @@ namespace Nz::ShaderAst
if (!clone->expression)
throw AstError{ "const variables must have an expression" };
clone->expression = Optimize(*clone->expression);
clone->expression = PropagateConstants(*clone->expression);
if (clone->expression->GetType() != NodeType::ConstantValueExpression)
throw AstError{ "const variable must have constant expressions " };
@ -1426,7 +1426,7 @@ namespace Nz::ShaderAst
ConstantValue SanitizeVisitor::ComputeConstantValue(Expression& expr) const
{
// Run optimizer on constant value to hopefully retrieve a single constant value
ExpressionPtr optimizedExpr = Optimize(expr);
ExpressionPtr optimizedExpr = PropagateConstants(expr);
if (optimizedExpr->GetType() != NodeType::ConstantValueExpression)
throw AstError{"expected a constant expression"};
@ -1464,9 +1464,9 @@ namespace Nz::ShaderAst
}
template<typename T>
std::unique_ptr<T> SanitizeVisitor::Optimize(T& node) const
std::unique_ptr<T> SanitizeVisitor::PropagateConstants(T& node) const
{
AstOptimizer::Options optimizerOptions;
AstConstantPropagationVisitor::Options optimizerOptions;
optimizerOptions.constantQueryCallback = [this](std::size_t constantId) -> const ConstantValue&
{
assert(constantId < m_context->constantValues.size());
@ -1474,7 +1474,7 @@ namespace Nz::ShaderAst
};
// Run optimizer on constant value to hopefully retrieve a single constant value
return static_unique_pointer_cast<T>(ShaderAst::Optimize(node, optimizerOptions));
return static_unique_pointer_cast<T>(ShaderAst::PropagateConstants(node, optimizerOptions));
}
void SanitizeVisitor::PropagateFunctionFlags(std::size_t funcIndex, FunctionFlags flags, Bitset<>& seen)

View File

@ -9,7 +9,7 @@
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/Ast/AstCloner.hpp>
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
#include <Nazara/Shader/Ast/AstUtils.hpp>
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
@ -180,7 +180,7 @@ namespace Nz
{
ShaderAst::StatementPtr tempAst;
tempAst = ShaderAst::Optimize(*targetAst);
tempAst = ShaderAst::PropagateConstants(*targetAst);
optimizedAst = ShaderAst::EliminateUnusedPass(*tempAst);
targetAst = optimizedAst.get();

View File

@ -11,7 +11,7 @@
#include <Nazara/Shader/SpirvData.hpp>
#include <Nazara/Shader/SpirvSection.hpp>
#include <Nazara/Shader/Ast/AstCloner.hpp>
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Ast/AstRecursiveVisitor.hpp>
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
@ -521,7 +521,7 @@ namespace Nz
{
ShaderAst::StatementPtr tempAst;
tempAst = ShaderAst::Optimize(*targetAst);
tempAst = ShaderAst::PropagateConstants(*targetAst);
optimizedAst = ShaderAst::EliminateUnusedPass(*tempAst);
targetAst = optimizedAst.get();

View File

@ -1,7 +1,7 @@
#include <ShaderNode/Widgets/CodeOutputWidget.hpp>
#include <Nazara/Shader/GlslWriter.hpp>
#include <Nazara/Shader/LangWriter.hpp>
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Ast/EliminateUnusedPassVisitor.hpp>
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
#include <Nazara/Shader/SpirvPrinter.hpp>
@ -70,8 +70,8 @@ void CodeOutputWidget::Refresh()
shaderAst = Nz::ShaderAst::Sanitize(*shaderAst, sanitizeOptions);
Nz::ShaderAst::AstOptimizer optimiser;
shaderAst = Nz::ShaderAst::Optimize(*shaderAst);
Nz::ShaderAst::AstConstantPropagationVisitor optimiser;
shaderAst = Nz::ShaderAst::PropagateConstants(*shaderAst);
shaderAst = Nz::ShaderAst::EliminateUnusedPass(*shaderAst);
}

View File

@ -3,7 +3,7 @@
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderLangParser.hpp>
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
#include <catch2/catch.hpp>
#include <cctype>

View File

@ -3,7 +3,7 @@
#include <Nazara/Core/StringExt.hpp>
#include <Nazara/Shader/ShaderBuilder.hpp>
#include <Nazara/Shader/ShaderLangParser.hpp>
#include <Nazara/Shader/Ast/AstOptimizer.hpp>
#include <Nazara/Shader/Ast/AstConstantPropagationVisitor.hpp>
#include <Nazara/Shader/Ast/SanitizeVisitor.hpp>
#include <catch2/catch.hpp>
#include <cctype>
@ -13,7 +13,7 @@ void ExpectOptimization(std::string_view sourceCode, std::string_view expectedOp
Nz::ShaderAst::StatementPtr shader;
REQUIRE_NOTHROW(shader = Nz::ShaderLang::Parse(sourceCode));
REQUIRE_NOTHROW(shader = Nz::ShaderAst::Sanitize(*shader));
REQUIRE_NOTHROW(shader = Nz::ShaderAst::Optimize(*shader));
REQUIRE_NOTHROW(shader = Nz::ShaderAst::PropagateConstants(*shader));
ExpectNZSL(*shader, expectedOptimizedResult);
}