diff --git a/source/reduce/CMakeLists.txt b/source/reduce/CMakeLists.txt index def4d2104..7651e8664 100644 --- a/source/reduce/CMakeLists.txt +++ b/source/reduce/CMakeLists.txt @@ -30,6 +30,7 @@ set(SPIRV_TOOLS_REDUCE_SOURCES remove_function_reduction_opportunity.h remove_function_reduction_opportunity_finder.h remove_opname_instruction_reduction_opportunity_finder.h + remove_relaxed_precision_decoration_opportunity_finder.h remove_selection_reduction_opportunity.h remove_selection_reduction_opportunity_finder.h remove_unreferenced_instruction_reduction_opportunity_finder.h @@ -56,6 +57,7 @@ set(SPIRV_TOOLS_REDUCE_SOURCES remove_function_reduction_opportunity.cpp remove_function_reduction_opportunity_finder.cpp remove_instruction_reduction_opportunity.cpp + remove_relaxed_precision_decoration_opportunity_finder.cpp remove_selection_reduction_opportunity.cpp remove_selection_reduction_opportunity_finder.cpp remove_unreferenced_instruction_reduction_opportunity_finder.cpp diff --git a/source/reduce/reducer.cpp b/source/reduce/reducer.cpp index a677be35b..ebb5d471e 100644 --- a/source/reduce/reducer.cpp +++ b/source/reduce/reducer.cpp @@ -25,6 +25,7 @@ #include "source/reduce/remove_block_reduction_opportunity_finder.h" #include "source/reduce/remove_function_reduction_opportunity_finder.h" #include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h" +#include "source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h" #include "source/reduce/remove_selection_reduction_opportunity_finder.h" #include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h" #include "source/reduce/simple_conditional_branch_to_branch_opportunity_finder.h" @@ -175,6 +176,8 @@ Reducer::ReductionResultStatus Reducer::Run( void Reducer::AddDefaultReductionPasses() { AddReductionPass(spvtools::MakeUnique< RemoveOpNameInstructionReductionOpportunityFinder>()); + AddReductionPass(spvtools::MakeUnique< + RemoveRelaxedPrecisionDecorationOpportunityFinder>()); AddReductionPass( spvtools::MakeUnique()); AddReductionPass( diff --git a/source/reduce/remove_relaxed_precision_decoration_opportunity_finder.cpp b/source/reduce/remove_relaxed_precision_decoration_opportunity_finder.cpp new file mode 100644 index 000000000..352cefb68 --- /dev/null +++ b/source/reduce/remove_relaxed_precision_decoration_opportunity_finder.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h" + +#include "source/reduce/remove_instruction_reduction_opportunity.h" + +namespace spvtools { +namespace reduce { + +std::vector> +RemoveRelaxedPrecisionDecorationOpportunityFinder::GetAvailableOpportunities( + opt::IRContext* context) const { + std::vector> result; + + // Consider all annotation instructions + for (auto& inst : context->module()->annotations()) { + // We are interested in removing instructions of the form: + // SpvOpDecorate %id RelaxedPrecision + // and + // SpvOpMemberDecorate %id member RelaxedPrecision + if ((inst.opcode() == SpvOpDecorate && + inst.GetSingleWordInOperand(1) == SpvDecorationRelaxedPrecision) || + (inst.opcode() == SpvOpMemberDecorate && + inst.GetSingleWordInOperand(2) == SpvDecorationRelaxedPrecision)) { + result.push_back( + MakeUnique(&inst)); + } + } + return result; +} + +std::string RemoveRelaxedPrecisionDecorationOpportunityFinder::GetName() const { + return "RemoveRelaxedPrecisionDecorationOpportunityFinder"; +} + +} // namespace reduce +} // namespace spvtools diff --git a/source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h b/source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h new file mode 100644 index 000000000..673049cc8 --- /dev/null +++ b/source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h @@ -0,0 +1,36 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SOURCE_REDUCE_REMOVE_RELAXED_PRECISION_OPPORTUNITY_FINDER_H_ +#define SOURCE_REDUCE_REMOVE_RELAXED_PRECISION_OPPORTUNITY_FINDER_H_ + +#include "source/reduce/reduction_opportunity_finder.h" + +namespace spvtools { +namespace reduce { + +// A finder for opportunities to remove relaxed precision decorations. +class RemoveRelaxedPrecisionDecorationOpportunityFinder + : public ReductionOpportunityFinder { + public: + std::vector> GetAvailableOpportunities( + opt::IRContext* context) const override; + + std::string GetName() const override; +}; + +} // namespace reduce +} // namespace spvtools + +#endif // SOURCE_REDUCE_REMOVE_RELAXED_PRECISION_OPPORTUNITY_FINDER_H_ diff --git a/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp b/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp index 8f3243519..dabee50cd 100644 --- a/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp +++ b/source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.cpp @@ -21,11 +21,9 @@ namespace spvtools { namespace reduce { -using opt::IRContext; - std::vector> RemoveUnreferencedInstructionReductionOpportunityFinder:: - GetAvailableOpportunities(IRContext* context) const { + GetAvailableOpportunities(opt::IRContext* context) const { std::vector> result; for (auto& function : *context->module()) { diff --git a/test/reduce/CMakeLists.txt b/test/reduce/CMakeLists.txt index 964abdd5e..2d3b37834 100644 --- a/test/reduce/CMakeLists.txt +++ b/test/reduce/CMakeLists.txt @@ -24,6 +24,7 @@ add_spvtools_unittest(TARGET reduce remove_block_test.cpp remove_function_test.cpp remove_opname_instruction_test.cpp + remove_relaxed_precision_decoration_test.cpp remove_selection_test.cpp remove_unreferenced_instruction_test.cpp structured_loop_to_selection_test.cpp diff --git a/test/reduce/remove_relaxed_precision_decoration_test.cpp b/test/reduce/remove_relaxed_precision_decoration_test.cpp new file mode 100644 index 000000000..f9ff081cc --- /dev/null +++ b/test/reduce/remove_relaxed_precision_decoration_test.cpp @@ -0,0 +1,177 @@ +// Copyright (c) 2019 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h" + +#include "source/opt/build_module.h" +#include "source/reduce/reduction_opportunity.h" +#include "source/reduce/reduction_pass.h" +#include "test/reduce/reduce_test_util.h" + +namespace spvtools { +namespace reduce { +namespace { + +TEST(RemoveRelaxedPrecisionDecorationTest, NothingToRemove) { + const std::string source = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %4 = OpFunction %2 None %3 + %5 = OpLabel + OpReturn + OpFunctionEnd + )"; + + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = + BuildModule(env, consumer, source, kReduceAssembleOption); + const auto ops = RemoveRelaxedPrecisionDecorationOpportunityFinder() + .GetAvailableOpportunities(context.get()); + ASSERT_EQ(0, ops.size()); +} + +TEST(RemoveRelaxedPrecisionDecorationTest, RemoveDecorations) { + const std::string source = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %8 "f" + OpName %12 "i" + OpName %16 "v" + OpName %19 "S" + OpMemberName %19 0 "a" + OpMemberName %19 1 "b" + OpMemberName %19 2 "c" + OpName %21 "s" + OpDecorate %8 RelaxedPrecision + OpDecorate %12 RelaxedPrecision + OpDecorate %16 RelaxedPrecision + OpDecorate %17 RelaxedPrecision + OpDecorate %18 RelaxedPrecision + OpMemberDecorate %19 0 RelaxedPrecision + OpMemberDecorate %19 1 RelaxedPrecision + OpMemberDecorate %19 2 RelaxedPrecision + OpDecorate %22 RelaxedPrecision + OpDecorate %23 RelaxedPrecision + OpDecorate %24 RelaxedPrecision + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeFloat 32 + %7 = OpTypePointer Function %6 + %9 = OpConstant %6 2 + %10 = OpTypeInt 32 1 + %11 = OpTypePointer Function %10 + %13 = OpConstant %10 22 + %14 = OpTypeVector %6 2 + %15 = OpTypePointer Function %14 + %19 = OpTypeStruct %10 %6 %14 + %20 = OpTypePointer Function %19 + %4 = OpFunction %2 None %3 + %5 = OpLabel + %8 = OpVariable %7 Function + %12 = OpVariable %11 Function + %16 = OpVariable %15 Function + %21 = OpVariable %20 Function + OpStore %8 %9 + OpStore %12 %13 + %17 = OpLoad %6 %8 + %18 = OpCompositeConstruct %14 %17 %17 + OpStore %16 %18 + %22 = OpLoad %10 %12 + %23 = OpLoad %6 %8 + %24 = OpLoad %14 %16 + %25 = OpCompositeConstruct %19 %22 %23 %24 + OpStore %21 %25 + OpReturn + OpFunctionEnd + )"; + + const auto env = SPV_ENV_UNIVERSAL_1_3; + const auto consumer = nullptr; + const auto context = + BuildModule(env, consumer, source, kReduceAssembleOption); + const auto ops = RemoveRelaxedPrecisionDecorationOpportunityFinder() + .GetAvailableOpportunities(context.get()); + ASSERT_EQ(11, ops.size()); + + for (auto& op : ops) { + ASSERT_TRUE(op->PreconditionHolds()); + op->TryToApply(); + } + + const std::string expected = R"( + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %4 "main" + OpExecutionMode %4 OriginUpperLeft + OpSource ESSL 310 + OpName %4 "main" + OpName %8 "f" + OpName %12 "i" + OpName %16 "v" + OpName %19 "S" + OpMemberName %19 0 "a" + OpMemberName %19 1 "b" + OpMemberName %19 2 "c" + OpName %21 "s" + %2 = OpTypeVoid + %3 = OpTypeFunction %2 + %6 = OpTypeFloat 32 + %7 = OpTypePointer Function %6 + %9 = OpConstant %6 2 + %10 = OpTypeInt 32 1 + %11 = OpTypePointer Function %10 + %13 = OpConstant %10 22 + %14 = OpTypeVector %6 2 + %15 = OpTypePointer Function %14 + %19 = OpTypeStruct %10 %6 %14 + %20 = OpTypePointer Function %19 + %4 = OpFunction %2 None %3 + %5 = OpLabel + %8 = OpVariable %7 Function + %12 = OpVariable %11 Function + %16 = OpVariable %15 Function + %21 = OpVariable %20 Function + OpStore %8 %9 + OpStore %12 %13 + %17 = OpLoad %6 %8 + %18 = OpCompositeConstruct %14 %17 %17 + OpStore %16 %18 + %22 = OpLoad %10 %12 + %23 = OpLoad %6 %8 + %24 = OpLoad %14 %16 + %25 = OpCompositeConstruct %19 %22 %23 %24 + OpStore %21 %25 + OpReturn + OpFunctionEnd + )"; + + CheckEqual(env, expected, context.get()); +} + +} // namespace +} // namespace reduce +} // namespace spvtools