summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp')
-rw-r--r--3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp206
1 files changed, 115 insertions, 91 deletions
diff --git a/3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp b/3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp
index ebb5d471ed2..bda41ce9459 100644
--- a/3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp
+++ b/3rdparty/bgfx/3rdparty/spirv-tools/source/reduce/reducer.cpp
@@ -24,8 +24,6 @@
#include "source/reduce/operand_to_undef_reduction_opportunity_finder.h"
#include "source/reduce/remove_block_reduction_opportunity_finder.h"
#include "source/reduce/remove_function_reduction_opportunity_finder.h"
-#include "source/reduce/remove_opname_instruction_reduction_opportunity_finder.h"
-#include "source/reduce/remove_relaxed_precision_decoration_opportunity_finder.h"
#include "source/reduce/remove_selection_reduction_opportunity_finder.h"
#include "source/reduce/remove_unreferenced_instruction_reduction_opportunity_finder.h"
#include "source/reduce/simple_conditional_branch_to_branch_opportunity_finder.h"
@@ -35,41 +33,32 @@
namespace spvtools {
namespace reduce {
-struct Reducer::Impl {
- explicit Impl(spv_target_env env) : target_env(env) {}
-
- bool ReachedStepLimit(uint32_t current_step,
- spv_const_reducer_options options);
-
- const spv_target_env target_env; // Target environment.
- MessageConsumer consumer; // Message consumer.
- InterestingnessFunction interestingness_function;
- std::vector<std::unique_ptr<ReductionPass>> passes;
-};
-
-Reducer::Reducer(spv_target_env env) : impl_(MakeUnique<Impl>(env)) {}
+Reducer::Reducer(spv_target_env target_env) : target_env_(target_env) {}
Reducer::~Reducer() = default;
void Reducer::SetMessageConsumer(MessageConsumer c) {
- for (auto& pass : impl_->passes) {
+ for (auto& pass : passes_) {
pass->SetMessageConsumer(c);
}
- impl_->consumer = std::move(c);
+ for (auto& pass : cleanup_passes_) {
+ pass->SetMessageConsumer(c);
+ }
+ consumer_ = std::move(c);
}
void Reducer::SetInterestingnessFunction(
Reducer::InterestingnessFunction interestingness_function) {
- impl_->interestingness_function = std::move(interestingness_function);
+ interestingness_function_ = std::move(interestingness_function);
}
Reducer::ReductionResultStatus Reducer::Run(
std::vector<uint32_t>&& binary_in, std::vector<uint32_t>* binary_out,
spv_const_reducer_options options,
- spv_validator_options validator_options) const {
+ spv_validator_options validator_options) {
std::vector<uint32_t> current_binary(std::move(binary_in));
- spvtools::SpirvTools tools(impl_->target_env);
+ spvtools::SpirvTools tools(target_env_);
assert(tools.IsValid() && "Failed to create SPIRV-Tools interface");
// Keeps track of how many reduction attempts have been tried. Reduction
@@ -79,32 +68,108 @@ Reducer::ReductionResultStatus Reducer::Run(
// Initial state should be valid.
if (!tools.Validate(&current_binary[0], current_binary.size(),
validator_options)) {
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- "Initial binary is invalid; stopping.");
+ consumer_(SPV_MSG_INFO, nullptr, {},
+ "Initial binary is invalid; stopping.");
return Reducer::ReductionResultStatus::kInitialStateInvalid;
}
// Initial state should be interesting.
- if (!impl_->interestingness_function(current_binary, reductions_applied)) {
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- "Initial state was not interesting; stopping.");
+ if (!interestingness_function_(current_binary, reductions_applied)) {
+ consumer_(SPV_MSG_INFO, nullptr, {},
+ "Initial state was not interesting; stopping.");
return Reducer::ReductionResultStatus::kInitialStateNotInteresting;
}
+ Reducer::ReductionResultStatus result =
+ RunPasses(&passes_, options, validator_options, tools, &current_binary,
+ &reductions_applied);
+
+ if (result == Reducer::ReductionResultStatus::kComplete) {
+ // Cleanup passes.
+ result = RunPasses(&cleanup_passes_, options, validator_options, tools,
+ &current_binary, &reductions_applied);
+ }
+
+ if (result == Reducer::ReductionResultStatus::kComplete) {
+ consumer_(SPV_MSG_INFO, nullptr, {}, "No more to reduce; stopping.");
+ }
+
+ // Even if the reduction has failed by this point (e.g. due to producing an
+ // invalid binary), we still update the output binary for better debugging.
+ *binary_out = std::move(current_binary);
+
+ return result;
+}
+
+void Reducer::AddDefaultReductionPasses() {
+ AddReductionPass(
+ spvtools::MakeUnique<
+ RemoveUnreferencedInstructionReductionOpportunityFinder>(false));
+ AddReductionPass(
+ spvtools::MakeUnique<OperandToUndefReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<OperandToConstReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<OperandToDominatingIdReductionOpportunityFinder>());
+ AddReductionPass(spvtools::MakeUnique<
+ StructuredLoopToSelectionReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<MergeBlocksReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<RemoveFunctionReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<RemoveBlockReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<RemoveSelectionReductionOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<
+ ConditionalBranchToSimpleConditionalBranchOpportunityFinder>());
+ AddReductionPass(
+ spvtools::MakeUnique<SimpleConditionalBranchToBranchOpportunityFinder>());
+
+ // Cleanup passes.
+
+ AddCleanupReductionPass(
+ spvtools::MakeUnique<
+ RemoveUnreferencedInstructionReductionOpportunityFinder>(true));
+}
+
+void Reducer::AddReductionPass(
+ std::unique_ptr<ReductionOpportunityFinder>&& finder) {
+ passes_.push_back(
+ spvtools::MakeUnique<ReductionPass>(target_env_, std::move(finder)));
+}
+
+void Reducer::AddCleanupReductionPass(
+ std::unique_ptr<ReductionOpportunityFinder>&& finder) {
+ cleanup_passes_.push_back(
+ spvtools::MakeUnique<ReductionPass>(target_env_, std::move(finder)));
+}
+
+bool Reducer::ReachedStepLimit(uint32_t current_step,
+ spv_const_reducer_options options) {
+ return current_step >= options->step_limit;
+}
+
+Reducer::ReductionResultStatus Reducer::RunPasses(
+ std::vector<std::unique_ptr<ReductionPass>>* passes,
+ spv_const_reducer_options options, spv_validator_options validator_options,
+ const SpirvTools& tools, std::vector<uint32_t>* current_binary,
+ uint32_t* const reductions_applied) {
// Determines whether, on completing one round of reduction passes, it is
// worthwhile trying a further round.
bool another_round_worthwhile = true;
// Apply round after round of reduction passes until we hit the reduction
// step limit, or deem that another round is not going to be worthwhile.
- while (!impl_->ReachedStepLimit(reductions_applied, options) &&
+ while (!ReachedStepLimit(*reductions_applied, options) &&
another_round_worthwhile) {
// At the start of a round of reduction passes, assume another round will
// not be worthwhile unless we find evidence to the contrary.
another_round_worthwhile = false;
- // Iterate through the available passes
- for (auto& pass : impl_->passes) {
+ // Iterate through the available passes.
+ for (auto& pass : *passes) {
// If this pass hasn't reached its minimum granularity then it's
// worth eventually doing another round of reductions, in order to
// try this pass at a finer granularity.
@@ -112,14 +177,14 @@ Reducer::ReductionResultStatus Reducer::Run(
// Keep applying this pass at its current granularity until it stops
// working or we hit the reduction step limit.
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- ("Trying pass " + pass->GetName() + ".").c_str());
+ consumer_(SPV_MSG_INFO, nullptr, {},
+ ("Trying pass " + pass->GetName() + ".").c_str());
do {
- auto maybe_result = pass->TryApplyReduction(current_binary);
+ auto maybe_result = pass->TryApplyReduction(*current_binary);
if (maybe_result.empty()) {
// For this round, the pass has no more opportunities (chunks) to
// apply, so move on to the next pass.
- impl_->consumer(
+ consumer_(
SPV_MSG_INFO, nullptr, {},
("Pass " + pass->GetName() + " did not make a reduction step.")
.c_str());
@@ -127,91 +192,50 @@ Reducer::ReductionResultStatus Reducer::Run(
}
bool interesting = false;
std::stringstream stringstream;
- reductions_applied++;
+ (*reductions_applied)++;
stringstream << "Pass " << pass->GetName() << " made reduction step "
- << reductions_applied << ".";
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- (stringstream.str().c_str()));
+ << *reductions_applied << ".";
+ consumer_(SPV_MSG_INFO, nullptr, {}, (stringstream.str().c_str()));
if (!tools.Validate(&maybe_result[0], maybe_result.size(),
validator_options)) {
// The reduction step went wrong and an invalid binary was produced.
// By design, this shouldn't happen; this is a safeguard to stop an
// invalid binary from being regarded as interesting.
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- "Reduction step produced an invalid binary.");
+ consumer_(SPV_MSG_INFO, nullptr, {},
+ "Reduction step produced an invalid binary.");
if (options->fail_on_validation_error) {
+ // In this mode, we fail, so we update the current binary so it is
+ // output for debugging.
+ *current_binary = std::move(maybe_result);
return Reducer::ReductionResultStatus::kStateInvalid;
}
- } else if (impl_->interestingness_function(maybe_result,
- reductions_applied)) {
+ } else if (interestingness_function_(maybe_result,
+ *reductions_applied)) {
// Success! The binary produced by this reduction step is
// interesting, so make it the binary of interest henceforth, and
// note that it's worth doing another round of reduction passes.
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- "Reduction step succeeded.");
- current_binary = std::move(maybe_result);
+ consumer_(SPV_MSG_INFO, nullptr, {}, "Reduction step succeeded.");
+ *current_binary = std::move(maybe_result);
interesting = true;
another_round_worthwhile = true;
}
// We must call this before the next call to TryApplyReduction.
pass->NotifyInteresting(interesting);
// Bail out if the reduction step limit has been reached.
- } while (!impl_->ReachedStepLimit(reductions_applied, options));
+ } while (!ReachedStepLimit(*reductions_applied, options));
}
}
- *binary_out = std::move(current_binary);
-
// Report whether reduction completed, or bailed out early due to reaching
// the step limit.
- if (impl_->ReachedStepLimit(reductions_applied, options)) {
- impl_->consumer(SPV_MSG_INFO, nullptr, {},
- "Reached reduction step limit; stopping.");
+ if (ReachedStepLimit(*reductions_applied, options)) {
+ consumer_(SPV_MSG_INFO, nullptr, {},
+ "Reached reduction step limit; stopping.");
return Reducer::ReductionResultStatus::kReachedStepLimit;
}
- impl_->consumer(SPV_MSG_INFO, nullptr, {}, "No more to reduce; stopping.");
- return Reducer::ReductionResultStatus::kComplete;
-}
-void Reducer::AddDefaultReductionPasses() {
- AddReductionPass(spvtools::MakeUnique<
- RemoveOpNameInstructionReductionOpportunityFinder>());
- AddReductionPass(spvtools::MakeUnique<
- RemoveRelaxedPrecisionDecorationOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<OperandToUndefReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<OperandToConstReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<OperandToDominatingIdReductionOpportunityFinder>());
- AddReductionPass(spvtools::MakeUnique<
- RemoveUnreferencedInstructionReductionOpportunityFinder>());
- AddReductionPass(spvtools::MakeUnique<
- StructuredLoopToSelectionReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<MergeBlocksReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<RemoveFunctionReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<RemoveBlockReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<RemoveSelectionReductionOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<
- ConditionalBranchToSimpleConditionalBranchOpportunityFinder>());
- AddReductionPass(
- spvtools::MakeUnique<SimpleConditionalBranchToBranchOpportunityFinder>());
-}
-
-void Reducer::AddReductionPass(
- 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,
- spv_const_reducer_options options) {
- return current_step >= options->step_limit;
+ // The passes completed successfully, although we may still run more passes.
+ return Reducer::ReductionResultStatus::kComplete;
}
} // namespace reduce