Skip to content

Commit

Permalink
Add option to preserve shader parameter declaration in output SPIRV. (s…
Browse files Browse the repository at this point in the history
…hader-slang#4344)

* Add option to preserve shader parameter declarations in output.

* Add test.
  • Loading branch information
csyonghe committed Jun 12, 2024
1 parent 3fe4a77 commit fa8c11e
Show file tree
Hide file tree
Showing 12 changed files with 49 additions and 15 deletions.
Binary file modified docs/command-line-slangc-reference.md
Binary file not shown.
1 change: 1 addition & 0 deletions slang.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,7 @@ extern "C"
MinimumSlangOptimization, // bool
DisableNonEssentialValidations, // bool
DisableSourceMap, // bool
PreserveParameters, // bool: preserve all resource parameters in the output code.

// Target

Expand Down
3 changes: 3 additions & 0 deletions source/slang/slang-emit-spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions source/slang/slang-emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions source/slang/slang-ir-dce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,8 @@ bool shouldInstBeLiveIfParentIsLive(IRInst* inst, IRDeadCodeEliminationOptions o
case kIROp_WitnessTableEntry:
return true;

case kIROp_GlobalParam:
return options.keepGlobalParamsAlive;
default:
break;
}
Expand Down
1 change: 1 addition & 0 deletions source/slang/slang-ir-dce.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 6 additions & 2 deletions source/slang/slang-ir-link.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 1 addition & 2 deletions source/slang/slang-ir-specialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ struct SpecializationContext
IRModule* module;
DiagnosticSink* sink;
TargetProgram* targetProgram;

bool changed = false;


Expand Down Expand Up @@ -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
Expand Down
21 changes: 10 additions & 11 deletions source/slang/slang-ir-ssa-simplification.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
Expand All @@ -88,16 +92,14 @@ namespace Slang
}
iterationCounter++;
}
eliminateDeadCode(module, dceOptions);
eliminateDeadCode(module, options.deadCodeElimOptions);
}

void simplifyNonSSAIR(TargetProgram* target, IRModule* module, IRSimplificationOptions options)
{
bool changed = true;
const int kMaxIterations = 8;
int iterationCounter = 0;
IRDeadCodeEliminationOptions dceOptions = IRDeadCodeEliminationOptions();
dceOptions.useFastAnalysis = options.minimalOptimization;

while (changed && iterationCounter < kMaxIterations)
{
Expand All @@ -111,17 +113,14 @@ 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++;
}
}


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;
Expand All @@ -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);

Expand Down
3 changes: 3 additions & 0 deletions source/slang/slang-ir-ssa-simplification.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "slang-ir-simplify-cfg.h"
#include "slang-ir-peephole.h"
#include "slang-ir-dce.h"

namespace Slang
{
Expand All @@ -15,6 +16,8 @@ namespace Slang
{
CFGSimplificationOptions cfgOptions;
PeepholeOptimizationOptions peepholeOptions;
IRDeadCodeEliminationOptions deadCodeElimOptions;

bool minimalOptimization = false;

static IRSimplificationOptions getDefault(TargetProgram* targetProgram);
Expand Down
2 changes: 2 additions & 0 deletions source/slang/slang-options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down
19 changes: 19 additions & 0 deletions tests/spirv/preserve-param.slang
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit fa8c11e

Please sign in to comment.