From fa8c11ebe8f9b1bf2174a5a4dbe92a34c16811c8 Mon Sep 17 00:00:00 2001 From: Yong He Date: Wed, 12 Jun 2024 09:27:14 -0700 Subject: Add option to preserve shader parameter declaration in output SPIRV. (#4344) * Add option to preserve shader parameter declarations in output. * Add test. --- source/slang/slang-emit-spirv.cpp | 3 +++ source/slang/slang-emit.cpp | 1 + source/slang/slang-ir-dce.cpp | 2 ++ source/slang/slang-ir-dce.h | 1 + source/slang/slang-ir-link.cpp | 8 ++++++-- source/slang/slang-ir-specialize.cpp | 3 +-- source/slang/slang-ir-ssa-simplification.cpp | 21 ++++++++++----------- source/slang/slang-ir-ssa-simplification.h | 3 +++ source/slang/slang-options.cpp | 2 ++ 9 files changed, 29 insertions(+), 15 deletions(-) (limited to 'source') diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index fd4b1d491..10c263793 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -6431,10 +6431,13 @@ SlangResult emitSPIRVFromIR( } #endif + auto shouldPreserveParams = codeGenContext->getTargetProgram()->getOptionSet().getBoolOption(CompilerOptionName::PreserveParameters); for (auto inst : irModule->getGlobalInsts()) { if (as(inst)) context.ensureInst(inst); + if (shouldPreserveParams && as(inst)) + context.ensureInst(inst); } // Emit source language info. diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 6d0ab1daa..38f066c6c 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -585,6 +585,7 @@ Result linkAndOptimizeIR( IRDeadCodeEliminationOptions deadCodeEliminationOptions = IRDeadCodeEliminationOptions(); fastIRSimplificationOptions.minimalOptimization = defaultIRSimplificationOptions.minimalOptimization; deadCodeEliminationOptions.useFastAnalysis = fastIRSimplificationOptions.minimalOptimization; + deadCodeEliminationOptions.keepGlobalParamsAlive = targetProgram->getOptionSet().getBoolOption(CompilerOptionName::PreserveParameters); simplifyIR(targetProgram, irModule, defaultIRSimplificationOptions, sink); diff --git a/source/slang/slang-ir-dce.cpp b/source/slang/slang-ir-dce.cpp index 4eefeabd5..f414f7266 100644 --- a/source/slang/slang-ir-dce.cpp +++ b/source/slang/slang-ir-dce.cpp @@ -423,6 +423,8 @@ bool shouldInstBeLiveIfParentIsLive(IRInst* inst, IRDeadCodeEliminationOptions o case kIROp_WitnessTableEntry: return true; + case kIROp_GlobalParam: + return options.keepGlobalParamsAlive; default: break; } diff --git a/source/slang/slang-ir-dce.h b/source/slang/slang-ir-dce.h index d52ec817e..55eed1c92 100644 --- a/source/slang/slang-ir-dce.h +++ b/source/slang/slang-ir-dce.h @@ -12,6 +12,7 @@ namespace Slang bool keepExportsAlive = false; bool keepLayoutsAlive = false; bool useFastAnalysis = false; + bool keepGlobalParamsAlive = true; }; /// Eliminate "dead" code from the given IR module. diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index eb660c8a7..5bb485b22 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -1830,12 +1830,16 @@ LinkedIR linkIR( } } + bool shouldCopyGlobalParams = linkage->m_optionSet.getBoolOption(CompilerOptionName::PreserveParameters); + for (IRModule* irModule : irModules) { for (auto inst : irModule->getGlobalInsts()) { - // Is it (HLSL) `export` clone - if (_isHLSLExported(inst)) + // We need to copy over exported symbols, + // and any global parameters if preserve-params option is set. + if (_isHLSLExported(inst) || + shouldCopyGlobalParams && as(inst)) { auto cloned = cloneValue(context, inst); if (!cloned->findDecorationImpl(kIROp_KeepAliveDecoration)) diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index 8fac31a2b..5713b9639 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -49,7 +49,6 @@ struct SpecializationContext IRModule* module; DiagnosticSink* sink; TargetProgram* targetProgram; - bool changed = false; @@ -861,7 +860,7 @@ struct SpecializationContext if (iterChanged) { this->changed = true; - eliminateDeadCode(module->getModuleInst(), IRDeadCodeEliminationOptions()); + eliminateDeadCode(module->getModuleInst()); } // Once the work list has gone dry, we should have the invariant diff --git a/source/slang/slang-ir-ssa-simplification.cpp b/source/slang/slang-ir-ssa-simplification.cpp index 2a9c0da43..b8d6360ad 100644 --- a/source/slang/slang-ir-ssa-simplification.cpp +++ b/source/slang/slang-ir-ssa-simplification.cpp @@ -24,6 +24,9 @@ namespace Slang else result.cfgOptions = CFGSimplificationOptions::getDefault(); result.peepholeOptions = PeepholeOptimizationOptions(); + if (targetProgram) + result.deadCodeElimOptions.keepGlobalParamsAlive = targetProgram->getOptionSet().getBoolOption(CompilerOptionName::PreserveParameters); + result.deadCodeElimOptions.useFastAnalysis = result.minimalOptimization; return result; } @@ -33,6 +36,9 @@ namespace Slang result.minimalOptimization = targetProgram ? targetProgram->getOptionSet().shouldPerformMinimumOptimizations() : false; result.cfgOptions = CFGSimplificationOptions::getFast(); result.peepholeOptions = PeepholeOptimizationOptions(); + if (targetProgram) + result.deadCodeElimOptions.keepGlobalParamsAlive = targetProgram->getOptionSet().getBoolOption(CompilerOptionName::PreserveParameters); + result.deadCodeElimOptions.useFastAnalysis = result.minimalOptimization; return result; } @@ -45,8 +51,6 @@ namespace Slang const int kMaxIterations = 8; const int kMaxFuncIterations = 16; int iterationCounter = 0; - IRDeadCodeEliminationOptions dceOptions = IRDeadCodeEliminationOptions(); - dceOptions.useFastAnalysis = options.minimalOptimization; while (changed && iterationCounter < kMaxIterations) { @@ -79,7 +83,7 @@ namespace Slang // Note: we disregard the `changed` state from dead code elimination pass since // SCCP pass could be generating temporarily evaluated constant values and never actually use them. // DCE will always remove those nearly generated consts and always returns true here. - eliminateDeadCode(func, dceOptions); + eliminateDeadCode(func, options.deadCodeElimOptions); if (funcIterationCount == 0) funcChanged |= constructSSA(func); changed |= funcChanged; @@ -88,7 +92,7 @@ namespace Slang } iterationCounter++; } - eliminateDeadCode(module, dceOptions); + eliminateDeadCode(module, options.deadCodeElimOptions); } void simplifyNonSSAIR(TargetProgram* target, IRModule* module, IRSimplificationOptions options) @@ -96,8 +100,6 @@ namespace Slang bool changed = true; const int kMaxIterations = 8; int iterationCounter = 0; - IRDeadCodeEliminationOptions dceOptions = IRDeadCodeEliminationOptions(); - dceOptions.useFastAnalysis = options.minimalOptimization; while (changed && iterationCounter < kMaxIterations) { @@ -111,7 +113,7 @@ namespace Slang // Note: we disregard the `changed` state from dead code elimination pass since // SCCP pass could be generating temporarily evaluated constant values and never actually use them. // DCE will always remove those nearly generated consts and always returns true here. - eliminateDeadCode(module, dceOptions); + eliminateDeadCode(module, options.deadCodeElimOptions); iterationCounter++; } } @@ -119,9 +121,6 @@ namespace Slang void simplifyFunc(TargetProgram* target, IRGlobalValueWithCode* func, IRSimplificationOptions options, DiagnosticSink* sink) { - IRDeadCodeEliminationOptions dceOptions = IRDeadCodeEliminationOptions(); - dceOptions.useFastAnalysis = options.minimalOptimization; - bool changed = true; const int kMaxIterations = 8; int iterationCounter = 0; @@ -140,7 +139,7 @@ namespace Slang // Note: we disregard the `changed` state from dead code elimination pass since // SCCP pass could be generating temporarily evaluated constant values and never actually use them. // DCE will always remove those nearly generated consts and always returns true here. - eliminateDeadCode(func, dceOptions); + eliminateDeadCode(func, options.deadCodeElimOptions); changed |= constructSSA(func); diff --git a/source/slang/slang-ir-ssa-simplification.h b/source/slang/slang-ir-ssa-simplification.h index 166f5a5f3..d524241ae 100644 --- a/source/slang/slang-ir-ssa-simplification.h +++ b/source/slang/slang-ir-ssa-simplification.h @@ -3,6 +3,7 @@ #include "slang-ir-simplify-cfg.h" #include "slang-ir-peephole.h" +#include "slang-ir-dce.h" namespace Slang { @@ -15,6 +16,8 @@ namespace Slang { CFGSimplificationOptions cfgOptions; PeepholeOptimizationOptions peepholeOptions; + IRDeadCodeEliminationOptions deadCodeElimOptions; + bool minimalOptimization = false; static IRSimplificationOptions getDefault(TargetProgram* targetProgram); diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 4bbd0dcaf..aefb14deb 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -347,6 +347,7 @@ void initCommandOptions(CommandOptions& options) { OptionKind::SourceEmbedLanguage, "-source-embed-language", "-source-embed-language ", "The language to be used for source embedding. Defaults to C/C++. Currently only C/C++ are supported"}, { OptionKind::DisableShortCircuit, "-disable-short-circuit", nullptr, "Disable short-circuiting for \"&&\" and \"||\" operations" }, + { OptionKind::PreserveParameters, "-preserve-params", nullptr, "Preserve all resource parameters in the output code, even if they are not used by the shader."} }; _addOptions(makeConstArrayView(generalOpts), options); @@ -1704,6 +1705,7 @@ SlangResult OptionsParser::_parse( case OptionKind::NoHLSLBinding: case OptionKind::NoHLSLPackConstantBufferElements: case OptionKind::LoopInversion: + case OptionKind::PreserveParameters: linkage->m_optionSet.set(optionKind, true); break; break; case OptionKind::MatrixLayoutRow: -- cgit v1.2.3