summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-06-12 09:27:14 -0700
committerGitHub <noreply@github.com>2024-06-12 09:27:14 -0700
commitfa8c11ebe8f9b1bf2174a5a4dbe92a34c16811c8 (patch)
tree1da9ed028486e9de5a2129143ea436014a063d7c
parent3fe4a77287345c303aeb985e24ee237f272e8eca (diff)
Add option to preserve shader parameter declaration in output SPIRV. (#4344)
* Add option to preserve shader parameter declarations in output. * Add test.
-rw-r--r--docs/command-line-slangc-reference.mdbin77996 -> 80334 bytes
-rw-r--r--slang.h1
-rw-r--r--source/slang/slang-emit-spirv.cpp3
-rw-r--r--source/slang/slang-emit.cpp1
-rw-r--r--source/slang/slang-ir-dce.cpp2
-rw-r--r--source/slang/slang-ir-dce.h1
-rw-r--r--source/slang/slang-ir-link.cpp8
-rw-r--r--source/slang/slang-ir-specialize.cpp3
-rw-r--r--source/slang/slang-ir-ssa-simplification.cpp21
-rw-r--r--source/slang/slang-ir-ssa-simplification.h3
-rw-r--r--source/slang/slang-options.cpp2
-rw-r--r--tests/spirv/preserve-param.slang19
12 files changed, 49 insertions, 15 deletions
diff --git a/docs/command-line-slangc-reference.md b/docs/command-line-slangc-reference.md
index 7c2beb7e0..594e25912 100644
--- a/docs/command-line-slangc-reference.md
+++ b/docs/command-line-slangc-reference.md
Binary files differ
diff --git a/slang.h b/slang.h
index ce659b007..d807efec4 100644
--- a/slang.h
+++ b/slang.h
@@ -865,6 +865,7 @@ extern "C"
MinimumSlangOptimization, // bool
DisableNonEssentialValidations, // bool
DisableSourceMap, // bool
+ PreserveParameters, // bool: preserve all resource parameters in the output code.
// Target
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<IRDebugSource>(inst))
context.ensureInst(inst);
+ if (shouldPreserveParams && as<IRGlobalParam>(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<IRGlobalParam>(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 <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:
diff --git a/tests/spirv/preserve-param.slang b/tests/spirv/preserve-param.slang
new file mode 100644
index 000000000..e9cc82291
--- /dev/null
+++ b/tests/spirv/preserve-param.slang
@@ -0,0 +1,19 @@
+//TEST:SIMPLE(filecheck=CHECK): -target spirv -preserve-params -O0
+
+// Test that -preserve-params option preserves shader paraemter declarations in the output spirv code.
+
+// CHECK-DAG: OpDecorate %{{.*}} Binding 0
+
+// CHECK-DAG: OpDecorate %{{.*}} Binding 1
+
+RWStructuredBuffer<float> buffer;
+
+struct TT
+{
+ Texture2D tex;
+}
+[numthreads(1, 1, 1)]
+void f(ConstantBuffer<TT> t)
+{
+ return;
+} \ No newline at end of file