Refactored reducer so that the 'finding' functionality of a reduction pass are separated from the generic functionality for tracking progress of a pass. With this change, we now have a ReductionOpportunityFinder abstract class, with many subclasses for each type of reduction, and just one ReductionPass class, which has an associated finder. (#2321)

Sounds good.
This commit is contained in:
Alastair Donaldson 2019-01-23 22:07:58 +00:00 committed by Steven Perron
parent b1be6763f6
commit 86d0d9be25
29 changed files with 288 additions and 259 deletions

View File

@ -14,33 +14,34 @@
set(SPIRV_TOOLS_REDUCE_SOURCES
change_operand_reduction_opportunity.h
change_operand_to_undef_reduction_opportunity.h
operand_to_const_reduction_pass.h
operand_to_undef_reduction_pass.h
operand_to_dominating_id_reduction_pass.h
operand_to_const_reduction_opportunity_finder.h
operand_to_undef_reduction_opportunity_finder.h
operand_to_dominating_id_reduction_opportunity_finder.h
reducer.h
reduction_opportunity.h
reduction_opportunity_finder.h
reduction_pass.h
reduction_util.h
remove_instruction_reduction_opportunity.h
remove_opname_instruction_reduction_pass.h
remove_unreferenced_instruction_reduction_pass.h
remove_opname_instruction_reduction_opportunity_finder.h
remove_unreferenced_instruction_reduction_opportunity_finder.h
structured_loop_to_selection_reduction_opportunity.h
structured_loop_to_selection_reduction_pass.h
structured_loop_to_selection_reduction_opportunity_finder.h
change_operand_reduction_opportunity.cpp
change_operand_to_undef_reduction_opportunity.cpp
operand_to_const_reduction_pass.cpp
operand_to_undef_reduction_pass.cpp
operand_to_dominating_id_reduction_pass.cpp
operand_to_const_reduction_opportunity_finder.cpp
operand_to_undef_reduction_opportunity_finder.cpp
operand_to_dominating_id_reduction_opportunity_finder.cpp
reducer.cpp
reduction_opportunity.cpp
reduction_pass.cpp
reduction_util.cpp
remove_instruction_reduction_opportunity.cpp
remove_unreferenced_instruction_reduction_pass.cpp
remove_opname_instruction_reduction_pass.cpp
remove_unreferenced_instruction_reduction_opportunity_finder.cpp
remove_opname_instruction_reduction_opportunity_finder.cpp
structured_loop_to_selection_reduction_opportunity.cpp
structured_loop_to_selection_reduction_pass.cpp
structured_loop_to_selection_reduction_opportunity_finder.cpp
)
if(MSVC)

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/reduce/operand_to_const_reduction_pass.h"
#include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
#include "source/opt/instruction.h"
#include "source/reduce/change_operand_reduction_opportunity.h"
@ -23,7 +23,7 @@ namespace reduce {
using namespace opt;
std::vector<std::unique_ptr<ReductionOpportunity>>
OperandToConstReductionPass::GetAvailableOpportunities(
OperandToConstReductionOpportunityFinder::GetAvailableOpportunities(
opt::IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
assert(result.empty());
@ -75,7 +75,7 @@ OperandToConstReductionPass::GetAvailableOpportunities(
return result;
}
std::string OperandToConstReductionPass::GetName() const {
std::string OperandToConstReductionOpportunityFinder::GetName() const {
return "OperandToConstReductionPass";
}

View File

@ -15,27 +15,23 @@
#ifndef SOURCE_REDUCE_OPERAND_TO_CONST_REDUCTION_PASS_H_
#define SOURCE_REDUCE_OPERAND_TO_CONST_REDUCTION_PASS_H_
#include "source/reduce/reduction_pass.h"
#include "source/reduce/reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
// A reduction pass for replacing id operands of instructions with ids of
// A finder for opportunities to replace id operands of instructions with ids of
// constants. This reduces the extent to which ids of non-constants are used,
// paving the way for instructions that generate them to be eliminated by other
// passes.
class OperandToConstReductionPass : public ReductionPass {
// paving the way for instructions that generate them to be eliminated.
class OperandToConstReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit OperandToConstReductionPass(const spv_target_env target_env)
: ReductionPass(target_env) {}
OperandToConstReductionOpportunityFinder() = default;
~OperandToConstReductionPass() override = default;
~OperandToConstReductionOpportunityFinder() override = default;
std::string GetName() const final;
protected:
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "operand_to_dominating_id_reduction_pass.h"
#include "operand_to_dominating_id_reduction_opportunity_finder.h"
#include "change_operand_reduction_opportunity.h"
#include "source/opt/instruction.h"
@ -22,7 +22,7 @@ namespace reduce {
using namespace opt;
std::vector<std::unique_ptr<ReductionOpportunity>>
OperandToDominatingIdReductionPass::GetAvailableOpportunities(
OperandToDominatingIdReductionOpportunityFinder::GetAvailableOpportunities(
opt::IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
@ -55,11 +55,12 @@ OperandToDominatingIdReductionPass::GetAvailableOpportunities(
return result;
}
void OperandToDominatingIdReductionPass::GetOpportunitiesForDominatingInst(
std::vector<std::unique_ptr<ReductionOpportunity>>* opportunities,
opt::Instruction* candidate_dominator,
opt::Function::iterator candidate_dominator_block, opt::Function* function,
opt::IRContext* context) const {
void OperandToDominatingIdReductionOpportunityFinder::
GetOpportunitiesForDominatingInst(
std::vector<std::unique_ptr<ReductionOpportunity>>* opportunities,
opt::Instruction* candidate_dominator,
opt::Function::iterator candidate_dominator_block,
opt::Function* function, opt::IRContext* context) const {
assert(candidate_dominator->HasResultId());
assert(candidate_dominator->type_id());
auto dominator_analysis = context->GetDominatorAnalysis(function);
@ -106,7 +107,7 @@ void OperandToDominatingIdReductionPass::GetOpportunitiesForDominatingInst(
}
}
std::string OperandToDominatingIdReductionPass::GetName() const {
std::string OperandToDominatingIdReductionOpportunityFinder::GetName() const {
return "OperandToDominatingIdReductionPass";
}

View File

@ -15,33 +15,30 @@
#ifndef SOURCE_REDUCE_OPERAND_TO_DOMINATING_ID_REDUCTION_PASS_H_
#define SOURCE_REDUCE_OPERAND_TO_DOMINATING_ID_REDUCTION_PASS_H_
#include "reduction_pass.h"
#include "reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
// A reduction pass that aims to bring to SPIR-V (and generalize) the idea from
// human-readable languages of e.g. replacing an expression with one of its
// arguments, (x + y) -> x, or with a reference to an identifier that was
// assigned to higher up in the program. The generalization of this is to
// replace an id with a different id of the same type defined in some
// dominating instruction.
// A finder that aims to bring to SPIR-V (and generalize) the idea from
// human-readable languages of e.g. finding opportunities to replace an
// expression with one of its arguments, (x + y) -> x, or with a reference to an
// identifier that was assigned to higher up in the program. The generalization
// of this is to replace an id with a different id of the same type defined in
// some dominating instruction.
//
// If id x is defined and then used several times, changing each use of x to
// some dominating definition may eventually allow the statement defining x
// to be eliminated by another pass.
class OperandToDominatingIdReductionPass : public ReductionPass {
class OperandToDominatingIdReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit OperandToDominatingIdReductionPass(const spv_target_env target_env)
: ReductionPass(target_env) {}
OperandToDominatingIdReductionOpportunityFinder() = default;
~OperandToDominatingIdReductionPass() override = default;
~OperandToDominatingIdReductionOpportunityFinder() override = default;
std::string GetName() const final;
protected:
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/reduce/operand_to_undef_reduction_pass.h"
#include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
#include "source/opt/instruction.h"
#include "source/reduce/change_operand_to_undef_reduction_opportunity.h"
@ -23,7 +23,7 @@ namespace reduce {
using namespace opt;
std::vector<std::unique_ptr<ReductionOpportunity>>
OperandToUndefReductionPass::GetAvailableOpportunities(
OperandToUndefReductionOpportunityFinder::GetAvailableOpportunities(
IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
@ -86,7 +86,7 @@ OperandToUndefReductionPass::GetAvailableOpportunities(
return result;
}
std::string OperandToUndefReductionPass::GetName() const {
std::string OperandToUndefReductionOpportunityFinder::GetName() const {
return "OperandToUndefReductionPass";
}

View File

@ -15,24 +15,22 @@
#ifndef SOURCE_REDUCE_OPERAND_TO_UNDEF_REDUCTION_PASS_H_
#define SOURCE_REDUCE_OPERAND_TO_UNDEF_REDUCTION_PASS_H_
#include "source/reduce/reduction_pass.h"
#include "source/reduce/reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
// A reduction pass for replacing id operands of instructions with ids of undef.
class OperandToUndefReductionPass : public ReductionPass {
// A finder of opportunities to replace id operands of instructions with ids of
// undef.
class OperandToUndefReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit OperandToUndefReductionPass(const spv_target_env target_env)
: ReductionPass(target_env) {}
OperandToUndefReductionOpportunityFinder() = default;
~OperandToUndefReductionPass() override = default;
~OperandToUndefReductionOpportunityFinder() override = default;
std::string GetName() const final;
protected:
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

View File

@ -16,8 +16,8 @@
#include <functional>
#include <string>
#include "source/reduce/change_operand_reduction_opportunity.h"
#include "source/reduce/operand_to_const_reduction_pass.h"
#include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
#include "source/reduce/reduction_opportunity.h"
#include "source/reduce/reduction_pass.h"
#include "source/reduce/remove_instruction_reduction_opportunity.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_pass.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"

View File

@ -141,8 +141,9 @@ Reducer::ReductionResultStatus Reducer::Run(
}
void Reducer::AddReductionPass(
std::unique_ptr<ReductionPass>&& reduction_pass) {
impl_->passes.push_back(std::move(reduction_pass));
std::unique_ptr<ReductionOpportunityFinder>&& finder) {
impl_->passes.push_back(spvtools::MakeUnique<ReductionPass>(
impl_->target_env, std::move(finder)));
}
bool Reducer::Impl::ReachedStepLimit(uint32_t current_step,

View File

@ -75,9 +75,9 @@ class Reducer {
void SetInterestingnessFunction(
InterestingnessFunction interestingness_function);
// Adds a reduction pass to the sequence of passes that will be iterated
// over.
void AddReductionPass(std::unique_ptr<ReductionPass>&& reduction_pass);
// Adds a reduction pass based on the given finder to the sequence of passes
// that will be iterated over.
void AddReductionPass(std::unique_ptr<ReductionOpportunityFinder>&& finder);
// Reduces the given SPIR-V module |binary_out|.
// The reduced binary ends up in |binary_out|.

View File

@ -0,0 +1,43 @@
// 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_REDUCTION_OPPORTUNITY_FINDER_H_
#define SOURCE_REDUCE_REDUCTION_OPPORTUNITY_FINDER_H_
#include "reduction_opportunity.h"
#include "source/opt/ir_context.h"
namespace spvtools {
namespace reduce {
// Abstract class for finding opportunities for reducing a SPIR-V module.
class ReductionOpportunityFinder {
public:
ReductionOpportunityFinder() = default;
virtual ~ReductionOpportunityFinder() = default;
// Finds and returns the reduction opportunities relevant to this pass that
// could be applied to the given SPIR-V module.
virtual std::vector<std::unique_ptr<ReductionOpportunity>>
GetAvailableOpportunities(opt::IRContext* context) const = 0;
// Provides a name for the finder.
virtual std::string GetName() const = 0;
};
} // namespace reduce
} // namespace spvtools
#endif // SOURCE_REDUCE_REDUCTION_OPPORTUNITY_FINDER_H_

View File

@ -34,7 +34,7 @@ std::vector<uint32_t> ReductionPass::TryApplyReduction(
assert(context);
std::vector<std::unique_ptr<ReductionOpportunity>> opportunities =
GetAvailableOpportunities(context.get());
finder_->GetAvailableOpportunities(context.get());
if (!is_initialized_) {
is_initialized_ = true;
@ -82,5 +82,7 @@ bool ReductionPass::ReachedMinimumGranularity() const {
return granularity_ == 1;
}
std::string ReductionPass::GetName() const { return finder_->GetName(); }
} // namespace reduce
} // namespace spvtools

View File

@ -17,7 +17,7 @@
#include "spirv-tools/libspirv.hpp"
#include "reduction_opportunity.h"
#include "reduction_opportunity_finder.h"
#include "source/opt/ir_context.h"
namespace spvtools {
@ -32,12 +32,14 @@ namespace reduce {
// again, until the minimum granularity is reached.
class ReductionPass {
public:
// Constructs a reduction pass with a given target environment, |target_env|.
// Initially the pass is uninitialized.
explicit ReductionPass(const spv_target_env target_env)
: target_env_(target_env), is_initialized_(false) {}
virtual ~ReductionPass() = default;
// Constructs a reduction pass with a given target environment, |target_env|,
// and a given finder of reduction opportunities, |finder|. Initially the
// pass is uninitialized.
explicit ReductionPass(const spv_target_env target_env,
std::unique_ptr<ReductionOpportunityFinder> finder)
: target_env_(target_env),
finder_(std::move(finder)),
is_initialized_(false) {}
// Applies the reduction pass to the given binary.
std::vector<uint32_t> TryApplyReduction(const std::vector<uint32_t>& binary);
@ -49,18 +51,13 @@ class ReductionPass {
// applied has reached a minimum.
bool ReachedMinimumGranularity() const;
// Returns the name of the reduction pass (useful for monitoring reduction
// progress).
virtual std::string GetName() const = 0;
protected:
// Finds and returns the reduction opportunities relevant to this pass that
// could be applied to the given SPIR-V module.
virtual std::vector<std::unique_ptr<ReductionOpportunity>>
GetAvailableOpportunities(opt::IRContext* context) const = 0;
// Returns the name associated with this reduction pass (based on its
// associated finder).
std::string GetName() const;
private:
const spv_target_env target_env_;
const std::unique_ptr<ReductionOpportunityFinder> finder_;
MessageConsumer consumer_;
bool is_initialized_;
uint32_t index_;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "remove_opname_instruction_reduction_pass.h"
#include "remove_opname_instruction_reduction_opportunity_finder.h"
#include "remove_instruction_reduction_opportunity.h"
#include "source/opcode.h"
#include "source/opt/instruction.h"
@ -23,7 +23,7 @@ namespace reduce {
using namespace opt;
std::vector<std::unique_ptr<ReductionOpportunity>>
RemoveOpNameInstructionReductionPass::GetAvailableOpportunities(
RemoveOpNameInstructionReductionOpportunityFinder::GetAvailableOpportunities(
opt::IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
@ -36,7 +36,7 @@ RemoveOpNameInstructionReductionPass::GetAvailableOpportunities(
return result;
}
std::string RemoveOpNameInstructionReductionPass::GetName() const {
std::string RemoveOpNameInstructionReductionOpportunityFinder::GetName() const {
return "RemoveOpNameInstructionReductionPass";
}

View File

@ -15,27 +15,24 @@
#ifndef SOURCE_REDUCE_REMOVE_OPNAME_INSTRUCTION_REDUCTION_PASS_H_
#define SOURCE_REDUCE_REMOVE_OPNAME_INSTRUCTION_REDUCTION_PASS_H_
#include "reduction_pass.h"
#include "reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
// A reduction pass for removing OpName instructions. As well as making the
// module smaller, removing an OpName instruction may create opportunities
// A finder for opportunities to remove OpName instructions. As well as making
// the module smaller, removing an OpName instruction may create opportunities
// for subsequently removing the instructions that create the ids to which the
// OpName applies.
class RemoveOpNameInstructionReductionPass : public ReductionPass {
class RemoveOpNameInstructionReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit RemoveOpNameInstructionReductionPass(const spv_target_env target_env)
: ReductionPass(target_env) {}
RemoveOpNameInstructionReductionOpportunityFinder() = default;
~RemoveOpNameInstructionReductionPass() override = default;
~RemoveOpNameInstructionReductionOpportunityFinder() override = default;
std::string GetName() const final;
protected:
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "remove_unreferenced_instruction_reduction_pass.h"
#include "remove_unreferenced_instruction_reduction_opportunity_finder.h"
#include "remove_instruction_reduction_opportunity.h"
#include "source/opcode.h"
#include "source/opt/instruction.h"
@ -23,8 +23,8 @@ namespace reduce {
using namespace opt;
std::vector<std::unique_ptr<ReductionOpportunity>>
RemoveUnreferencedInstructionReductionPass::GetAvailableOpportunities(
opt::IRContext* context) const {
RemoveUnreferencedInstructionReductionOpportunityFinder::
GetAvailableOpportunities(opt::IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
for (auto& function : *context->module()) {
@ -52,7 +52,8 @@ RemoveUnreferencedInstructionReductionPass::GetAvailableOpportunities(
return result;
}
std::string RemoveUnreferencedInstructionReductionPass::GetName() const {
std::string RemoveUnreferencedInstructionReductionOpportunityFinder::GetName()
const {
return "RemoveUnreferencedInstructionReductionPass";
}

View File

@ -15,29 +15,25 @@
#ifndef SOURCE_REDUCE_REMOVE_UNREFERENCED_INSTRUCTION_REDUCTION_PASS_H_
#define SOURCE_REDUCE_REMOVE_UNREFERENCED_INSTRUCTION_REDUCTION_PASS_H_
#include "reduction_pass.h"
#include "reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
// A reduction pass for removing non-control-flow instructions in blocks in
// cases where the instruction's id is not referenced. As well as making the
// A finder for opportunities to remove non-control-flow instructions in blocks
// in cases where the instruction's id is not referenced. As well as making the
// module smaller, removing an instruction that references particular ids may
// create opportunities for subsequently removing the instructions that
// generated those ids.
class RemoveUnreferencedInstructionReductionPass : public ReductionPass {
class RemoveUnreferencedInstructionReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit RemoveUnreferencedInstructionReductionPass(
const spv_target_env target_env)
: ReductionPass(target_env) {}
RemoveUnreferencedInstructionReductionOpportunityFinder() = default;
~RemoveUnreferencedInstructionReductionPass() override = default;
~RemoveUnreferencedInstructionReductionOpportunityFinder() override = default;
std::string GetName() const final;
protected:
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "structured_loop_to_selection_reduction_pass.h"
#include "structured_loop_to_selection_reduction_opportunity_finder.h"
#include "structured_loop_to_selection_reduction_opportunity.h"
namespace spvtools {
@ -26,7 +26,7 @@ const uint32_t kContinueNodeIndex = 1;
} // namespace
std::vector<std::unique_ptr<ReductionOpportunity>>
StructuredLoopToSelectionReductionPass::GetAvailableOpportunities(
StructuredLoopToSelectionReductionOpportunityFinder::GetAvailableOpportunities(
opt::IRContext* context) const {
std::vector<std::unique_ptr<ReductionOpportunity>> result;
@ -87,7 +87,8 @@ StructuredLoopToSelectionReductionPass::GetAvailableOpportunities(
return result;
}
std::string StructuredLoopToSelectionReductionPass::GetName() const {
std::string StructuredLoopToSelectionReductionOpportunityFinder::GetName()
const {
return "StructuredLoopToSelectionReductionPass";
}

View File

@ -15,13 +15,13 @@
#ifndef SOURCE_REDUCE_CUT_LOOP_REDUCTION_PASS_H_
#define SOURCE_REDUCE_CUT_LOOP_REDUCTION_PASS_H_
#include "reduction_pass.h"
#include "reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
// Turns structured loops into selections, generalizing from a human-writable
// language the idea of turning a loop:
// A finder for opportunities to turn structured loops into selections,
// generalizing from a human-writable language the idea of turning a loop:
//
// while (c) {
// body;
@ -33,22 +33,18 @@ namespace reduce {
// body;
// }
//
// The pass results in continue constructs of transformed loops becoming
// unreachable; another pass for eliminating blocks may end up being able to
// remove them.
class StructuredLoopToSelectionReductionPass : public ReductionPass {
// Applying such opportunities results in continue constructs of transformed
// loops becoming unreachable, so that it may be possible to remove them
// subsequently.
class StructuredLoopToSelectionReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit StructuredLoopToSelectionReductionPass(
const spv_target_env target_env)
: ReductionPass(target_env) {}
StructuredLoopToSelectionReductionOpportunityFinder() = default;
~StructuredLoopToSelectionReductionPass() override = default;
~StructuredLoopToSelectionReductionOpportunityFinder() override = default;
std::string GetName() const final;
protected:
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
opt::IRContext* context) const final;

View File

@ -14,7 +14,7 @@
#include "reduce_test_util.h"
#include "source/opt/build_module.h"
#include "source/reduce/operand_to_const_reduction_pass.h"
#include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
@ -97,8 +97,9 @@ TEST(OperandToConstantReductionPassTest, BasicCheck) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto pass = TestSubclass<OperandToConstReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops =
OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
context.get());
ASSERT_EQ(17, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
ops[0]->TryToApply();
@ -146,8 +147,9 @@ TEST(OperandToConstantReductionPassTest, WithCalledFunction) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, shader, kReduceAssembleOption);
const auto pass = TestSubclass<OperandToConstReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops =
OperandToConstReductionOpportunityFinder().GetAvailableOpportunities(
context.get());
ASSERT_EQ(0, ops.size());
}

View File

@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/reduce/operand_to_dominating_id_reduction_pass.h"
#include "reduce_test_util.h"
#include "source/opt/build_module.h"
#include "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
@ -53,8 +53,8 @@ TEST(OperandToDominatingIdReductionPassTest, BasicCheck) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto pass = TestSubclass<OperandToDominatingIdReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = OperandToDominatingIdReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(10, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
ops[0]->TryToApply();

View File

@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/reduce/operand_to_undef_reduction_pass.h"
#include "source/opt/build_module.h"
#include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
#include "test/reduce/reduce_test_util.h"
namespace spvtools {
@ -163,8 +163,9 @@ TEST(OperandToUndefReductionPassTest, BasicCheck) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto pass = TestSubclass<OperandToUndefReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops =
OperandToUndefReductionOpportunityFinder().GetAvailableOpportunities(
context.get());
ASSERT_EQ(10, ops.size());
@ -216,8 +217,9 @@ TEST(OperandToUndefReductionPassTest, WithCalledFunction) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, shader, kReduceAssembleOption);
const auto pass = TestSubclass<OperandToUndefReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops =
OperandToUndefReductionOpportunityFinder().GetAvailableOpportunities(
context.get());
ASSERT_EQ(0, ops.size());
}

View File

@ -24,23 +24,6 @@
namespace spvtools {
namespace reduce {
// A helper class that subclasses a given reduction pass class in order to
// provide a wrapper for its protected methods.
template <class ReductionPassT>
class TestSubclass : public ReductionPassT {
public:
// Creates an instance of the reduction pass subclass with respect to target
// environment |env|.
explicit TestSubclass(const spv_target_env env) : ReductionPassT(env) {}
~TestSubclass() = default;
// A wrapper for GetAvailableOpportunities(...)
std::vector<std::unique_ptr<ReductionOpportunity>>
WrapGetAvailableOpportunities(opt::IRContext* context) const {
return ReductionPassT::GetAvailableOpportunities(context);
}
};
// Checks whether the given binaries are bit-wise equal.
void CheckEqual(spv_target_env env,
const std::vector<uint32_t>& expected_binary,

View File

@ -14,10 +14,10 @@
#include "reduce_test_util.h"
#include "source/reduce/operand_to_const_reduction_pass.h"
#include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
#include "source/reduce/reducer.h"
#include "source/reduce/remove_opname_instruction_reduction_pass.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_pass.h"
#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
@ -217,9 +217,10 @@ TEST(ReducerTest, ExprToConstantAndRemoveUnreferenced) {
[&](const std::vector<uint32_t>& binary, uint32_t) -> bool {
return ping_pong_interesting.IsInteresting(binary);
});
reducer.AddReductionPass(MakeUnique<OperandToConstReductionPass>(env));
reducer.AddReductionPass(
MakeUnique<RemoveUnreferencedInstructionReductionPass>(env));
MakeUnique<OperandToConstReductionOpportunityFinder>());
reducer.AddReductionPass(
MakeUnique<RemoveUnreferencedInstructionReductionOpportunityFinder>());
std::vector<uint32_t> binary_in;
SpirvTools t(env);
@ -288,9 +289,9 @@ TEST(ReducerTest, RemoveOpnameAndRemoveUnreferenced) {
return ping_pong_interesting.IsInteresting(binary);
});
reducer.AddReductionPass(
MakeUnique<RemoveOpNameInstructionReductionPass>(env));
MakeUnique<RemoveOpNameInstructionReductionOpportunityFinder>());
reducer.AddReductionPass(
MakeUnique<RemoveUnreferencedInstructionReductionPass>(env));
MakeUnique<RemoveUnreferencedInstructionReductionOpportunityFinder>());
std::vector<uint32_t> binary_in;
SpirvTools t(env);

View File

@ -16,7 +16,8 @@
#include "source/opt/build_module.h"
#include "source/reduce/reduction_opportunity.h"
#include "source/reduce/remove_opname_instruction_reduction_pass.h"
#include "source/reduce/reduction_pass.h"
#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
@ -42,8 +43,8 @@ TEST(RemoveOpnameInstructionReductionPassTest, NothingToRemove) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, source, kReduceAssembleOption);
const auto pass = TestSubclass<RemoveOpNameInstructionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = RemoveOpNameInstructionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(0, ops.size());
}
@ -76,8 +77,8 @@ TEST(RemoveOpnameInstructionReductionPassTest, RemoveSingleOpName) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto pass = TestSubclass<RemoveOpNameInstructionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = RemoveOpNameInstructionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
ops[0]->TryToApply();
@ -126,14 +127,14 @@ TEST(RemoveOpnameInstructionReductionPassTest, TryApplyRemovesAllOpName) {
const std::string expected = prologue + epilogue;
const auto env = SPV_ENV_UNIVERSAL_1_3;
auto pass = TestSubclass<RemoveOpNameInstructionReductionPass>(env);
{
// Check the right number of opportunities is detected
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = RemoveOpNameInstructionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(5, ops.size());
}
@ -142,7 +143,11 @@ TEST(RemoveOpnameInstructionReductionPassTest, TryApplyRemovesAllOpName) {
std::vector<uint32_t> binary;
SpirvTools t(env);
ASSERT_TRUE(t.Assemble(original, &binary, kReduceAssembleOption));
auto reduced_binary = pass.TryApplyReduction(binary);
auto reduced_binary =
ReductionPass(env,
spvtools::MakeUnique<
RemoveOpNameInstructionReductionOpportunityFinder>())
.TryApplyReduction(binary);
CheckEqual(env, expected, reduced_binary);
}
}
@ -190,14 +195,14 @@ TEST(RemoveOpnameInstructionReductionPassTest,
const std::string expected = prologue + epilogue;
const auto env = SPV_ENV_UNIVERSAL_1_3;
auto pass = TestSubclass<RemoveOpNameInstructionReductionPass>(env);
{
// Check the right number of opportunities is detected
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = RemoveOpNameInstructionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(6, ops.size());
}
@ -206,7 +211,11 @@ TEST(RemoveOpnameInstructionReductionPassTest,
std::vector<uint32_t> binary;
SpirvTools t(env);
ASSERT_TRUE(t.Assemble(original, &binary, kReduceAssembleOption));
auto reduced_binary = pass.TryApplyReduction(binary);
auto reduced_binary =
ReductionPass(env,
spvtools::MakeUnique<
RemoveOpNameInstructionReductionOpportunityFinder>())
.TryApplyReduction(binary);
CheckEqual(env, expected, reduced_binary);
}
}

View File

@ -16,7 +16,9 @@
#include "source/opt/build_module.h"
#include "source/reduce/reduction_opportunity.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_pass.h"
#include "source/reduce/reduction_pass.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
#include "source/util/make_unique.h"
namespace spvtools {
namespace reduce {
@ -73,9 +75,8 @@ TEST(RemoveUnreferencedInstructionReductionPassTest, RemoveStores) {
const auto consumer = nullptr;
const auto context =
BuildModule(env, consumer, original, kReduceAssembleOption);
const auto pass =
TestSubclass<RemoveUnreferencedInstructionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = RemoveUnreferencedInstructionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(4, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
ops[0]->TryToApply();
@ -132,7 +133,9 @@ TEST(RemoveUnreferencedInstructionReductionPassTest, ApplyReduction) {
SpirvTools t(env);
ASSERT_TRUE(t.Assemble(original, &binary, kReduceAssembleOption));
auto pass = TestSubclass<RemoveUnreferencedInstructionReductionPass>(env);
ReductionPass pass(
env, spvtools::MakeUnique<
RemoveUnreferencedInstructionReductionOpportunityFinder>());
{
// Attempt 1 should remove everything removable.

View File

@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "source/reduce/structured_loop_to_selection_reduction_pass.h"
#include "reduce_test_util.h"
#include "source/opt/build_module.h"
#include "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h"
namespace spvtools {
namespace reduce {
@ -62,8 +62,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, LoopyShader1) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -208,8 +208,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, LoopyShader2) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(4, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -677,8 +677,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, LoopyShader3) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(0, ops.size());
}
@ -755,8 +755,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, LoopyShader4) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
// Initially there are two opportunities.
ASSERT_EQ(2, ops.size());
@ -878,8 +878,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, ConditionalBreak1) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -953,8 +953,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, ConditionalBreak2) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -1021,8 +1021,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, UnconditionalBreak) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -1221,8 +1221,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, Complex) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(2, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -1688,8 +1688,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, ComplexOptimized) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(2, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2005,8 +2005,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, DominanceIssue) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2153,8 +2153,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, AccessChainIssue) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2310,8 +2310,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, DominanceAndPhiIssue) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2418,8 +2418,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, OpLineBeforeOpPhi) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2508,8 +2508,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
// There should be no opportunities.
ASSERT_EQ(0, ops.size());
@ -2552,8 +2552,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
// There should be no opportunities.
ASSERT_EQ(0, ops.size());
@ -2592,8 +2592,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, ContinueTargetIsSwitchTarget) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2667,8 +2667,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2730,8 +2730,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, LoopBranchesStraightToMerge) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2787,8 +2787,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2871,8 +2871,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, MultipleAccessChains) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -2967,8 +2967,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(2, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -3086,8 +3086,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
const auto ops = pass.WrapGetAvailableOpportunities(context.get());
const auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(2, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());
@ -3206,8 +3206,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
auto ops = pass.WrapGetAvailableOpportunities(context.get());
auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
// We cannot transform the inner loop due to its header jumping straight to
// the outer loop merge (the inner loop's merge does not post-dominate its
@ -3251,7 +3251,8 @@ TEST(StructuredLoopToSelectionReductionPassTest,
CheckEqual(env, after_op_0, context.get());
// Now look again for more opportunities.
ops = pass.WrapGetAvailableOpportunities(context.get());
ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
// What was the inner loop should now be transformable, as the jump to the
// outer loop's merge has been redirected.
@ -3418,8 +3419,8 @@ TEST(StructuredLoopToSelectionReductionPassTest, LongAccessChains) {
const auto env = SPV_ENV_UNIVERSAL_1_3;
const auto context = BuildModule(env, nullptr, shader, kReduceAssembleOption);
const auto pass = TestSubclass<StructuredLoopToSelectionReductionPass>(env);
auto ops = pass.WrapGetAvailableOpportunities(context.get());
auto ops = StructuredLoopToSelectionReductionOpportunityFinder()
.GetAvailableOpportunities(context.get());
ASSERT_EQ(1, ops.size());
ASSERT_TRUE(ops[0]->PreconditionHolds());

View File

@ -22,24 +22,21 @@ namespace spvtools {
namespace reduce {
namespace {
// A dumb reduction pass that removes global values regardless of whether they
// are referenced. This is very likely to make the resulting module invalid. We
// use this to test the reducer's behavior in the scenario where a bad reduction
// pass leads to an invalid module.
class BlindlyRemoveGlobalValuesPass : public ReductionPass {
// A dumb reduction opportunity finder that finds opportunities to remove global
// values regardless of whether they are referenced. This is very likely to make
// the resulting module invalid. We use this to test the reducer's behavior in
// the scenario where a bad reduction pass leads to an invalid module.
class BlindlyRemoveGlobalValuesReductionOpportunityFinder
: public ReductionOpportunityFinder {
public:
// Creates the reduction pass in the context of the given target environment
// |target_env|
explicit BlindlyRemoveGlobalValuesPass(const spv_target_env target_env)
: ReductionPass(target_env) {}
BlindlyRemoveGlobalValuesReductionOpportunityFinder() = default;
~BlindlyRemoveGlobalValuesPass() override = default;
~BlindlyRemoveGlobalValuesReductionOpportunityFinder() override = default;
// The name of this pass.
std::string GetName() const final { return "BlindlyRemoveGlobalValuesPass"; };
protected:
// Adds opportunities to remove all global values. Assuming they are all
// Finds opportunities to remove all global values. Assuming they are all
// referenced (directly or indirectly) from elsewhere in the module, each such
// opportunity will make the module invalid.
std::vector<std::unique_ptr<ReductionOpportunity>> GetAvailableOpportunities(
@ -153,7 +150,8 @@ TEST(ValidationDuringReductionTest, CheckInvalidPassMakesNoProgress) {
reducer.SetInterestingnessFunction(
[](const std::vector<uint32_t>&, uint32_t) -> bool { return true; });
reducer.AddReductionPass(MakeUnique<BlindlyRemoveGlobalValuesPass>(env));
reducer.AddReductionPass(
MakeUnique<BlindlyRemoveGlobalValuesReductionOpportunityFinder>());
std::vector<uint32_t> binary_in;
SpirvTools t(env);
@ -357,7 +355,8 @@ TEST(ValidationDuringReductionTest, CheckNotAlwaysInvalidCanMakeProgress) {
reducer.SetInterestingnessFunction(
[](const std::vector<uint32_t>&, uint32_t) -> bool { return true; });
reducer.AddReductionPass(MakeUnique<BlindlyRemoveGlobalValuesPass>(env));
reducer.AddReductionPass(
MakeUnique<BlindlyRemoveGlobalValuesReductionOpportunityFinder>());
std::vector<uint32_t> binary_in;
SpirvTools t(env);

View File

@ -20,13 +20,13 @@
#include "source/opt/build_module.h"
#include "source/opt/ir_context.h"
#include "source/opt/log.h"
#include "source/reduce/operand_to_const_reduction_pass.h"
#include "source/reduce/operand_to_dominating_id_reduction_pass.h"
#include "source/reduce/operand_to_undef_reduction_pass.h"
#include "source/reduce/operand_to_const_reduction_opportunity_finder.h"
#include "source/reduce/operand_to_dominating_id_reduction_opportunity_finder.h"
#include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
#include "source/reduce/reducer.h"
#include "source/reduce/remove_opname_instruction_reduction_pass.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_pass.h"
#include "source/reduce/structured_loop_to_selection_reduction_pass.h"
#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
#include "source/reduce/structured_loop_to_selection_reduction_opportunity_finder.h"
#include "source/spirv_reducer_options.h"
#include "source/util/make_unique.h"
#include "source/util/string_utils.h"
@ -226,18 +226,20 @@ int main(int argc, const char** argv) {
});
reducer.AddReductionPass(
spvtools::MakeUnique<RemoveOpNameInstructionReductionPass>(target_env));
spvtools::MakeUnique<
RemoveOpNameInstructionReductionOpportunityFinder>());
reducer.AddReductionPass(
spvtools::MakeUnique<OperandToUndefReductionPass>(target_env));
spvtools::MakeUnique<OperandToUndefReductionOpportunityFinder>());
reducer.AddReductionPass(
spvtools::MakeUnique<OperandToConstReductionPass>(target_env));
spvtools::MakeUnique<OperandToConstReductionOpportunityFinder>());
reducer.AddReductionPass(
spvtools::MakeUnique<OperandToDominatingIdReductionPass>(target_env));
spvtools::MakeUnique<OperandToDominatingIdReductionOpportunityFinder>());
reducer.AddReductionPass(
spvtools::MakeUnique<RemoveUnreferencedInstructionReductionPass>(
target_env));
spvtools::MakeUnique<
RemoveUnreferencedInstructionReductionOpportunityFinder>());
reducer.AddReductionPass(
spvtools::MakeUnique<StructuredLoopToSelectionReductionPass>(target_env));
spvtools::MakeUnique<
StructuredLoopToSelectionReductionOpportunityFinder>());
reducer.SetMessageConsumer(spvtools::utils::CLIMessageConsumer);