From 7f047b986b5e3097ffbb0d9baba623b0b28dc73b Mon Sep 17 00:00:00 2001 From: Greg Fischer Date: Mon, 18 Apr 2022 16:00:51 -0600 Subject: [PATCH] Add EliminateDeadOutputStores to API. Also eliminates dead output variables and unused output variable components. Finally calls aggressive dead code elimination. AnalyzeDeadOutputStores also supplied to be called on the following shader to provide input for the Eliminate* function. --- SPIRV/SpvTools.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++-- SPIRV/SpvTools.h | 19 +++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/SPIRV/SpvTools.cpp b/SPIRV/SpvTools.cpp index 25299937..1b262800 100644 --- a/SPIRV/SpvTools.cpp +++ b/SPIRV/SpvTools.cpp @@ -212,8 +212,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass()); if (options->optimizeSize) { optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); - if (intermediate.getStage() == EShLanguage::EShLangVertex) - optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass()); + optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsSafePass()); } optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); @@ -224,6 +223,56 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); } +bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, + spv::SpvBuildLogger* logger) +{ + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateAnalyzeLiveInputPass(live_locs, live_builtins)); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(target_env); + spvOptOptions.set_run_validator(false); + return optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, + spv::SpvBuildLogger* logger) +{ + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputStoresPass(live_locs, live_builtins)); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true)); + optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputComponentsPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true)); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(target_env); + spvOptOptions.set_run_validator(false); + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector& spirv, + spv::SpvBuildLogger* logger) +{ + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(target_env); + spvOptOptions.set_run_validator(false); + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + // Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by // SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if // optimization is disabled. diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h index 5386048a..6fc4e40b 100644 --- a/SPIRV/SpvTools.h +++ b/SPIRV/SpvTools.h @@ -65,6 +65,9 @@ struct SpvOptions { #if ENABLE_OPT +// Translate glslang's view of target versioning to what SPIRV-Tools uses. +spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger); + // Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); @@ -80,6 +83,22 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger*, const SpvOptions*); +// Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|. +void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector& spirv, + spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|. +// Return true if the result is valid. +bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using +// |live_locs|. Put result in |spirv|. +void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, spv::SpvBuildLogger*); + // Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by // SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if // optimization is disabled.