mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-10-18 11:10:05 +00:00
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:
parent
b1be6763f6
commit
86d0d9be25
@ -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)
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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|.
|
||||
|
43
source/reduce/reduction_opportunity_finder.h
Normal file
43
source/reduce/reduction_opportunity_finder.h
Normal 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_
|
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user