summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit.cpp')
-rw-r--r--source/slang/slang-emit.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index b9217de41..cd1b177b2 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -815,7 +815,18 @@ Result linkAndOptimizeIR(
bool changed = false;
dumpIRIfEnabled(codeGenContext, irModule, "BEFORE-SPECIALIZE");
if (!codeGenContext->isSpecializationDisabled())
- changed |= specializeModule(targetProgram, irModule, codeGenContext->getSink());
+ {
+ // Pre-autodiff, we will attempt to specialize as much as possible.
+ //
+ // Note: Lowered dynamic-dispatch code cannot be differentiated correctly due to
+ // missing information, so we defer that to after the auto-dff step.
+ //
+ SpecializationOptions specOptions;
+ specOptions.lowerWitnessLookups = false;
+ changed |=
+ specializeModule(targetProgram, irModule, codeGenContext->getSink(), specOptions);
+ }
+
if (codeGenContext->getSink()->getErrorCount() != 0)
return SLANG_FAIL;
dumpIRIfEnabled(codeGenContext, irModule, "AFTER-SPECIALIZE");
@@ -867,9 +878,20 @@ Result linkAndOptimizeIR(
reportCheckpointIntermediates(codeGenContext, sink, irModule);
// Finalization is always run so AD-related instructions can be removed,
- // even the AD pass itself is not run.
+ // even if the AD pass itself is not run.
//
finalizeAutoDiffPass(targetProgram, irModule);
+ eliminateDeadCode(irModule, deadCodeEliminationOptions);
+
+ // After auto-diff, we can perform more aggressive specialization with dynamic-dispatch
+ // lowering.
+ //
+ if (!codeGenContext->isSpecializationDisabled())
+ {
+ SpecializationOptions specOptions;
+ specOptions.lowerWitnessLookups = true;
+ specializeModule(targetProgram, irModule, codeGenContext->getSink(), specOptions);
+ }
finalizeSpecialization(irModule);
@@ -930,6 +952,8 @@ Result linkAndOptimizeIR(
validateIRModuleIfEnabled(codeGenContext, irModule);
+ inferAnyValueSizeWhereNecessary(targetProgram, irModule);
+
// If we have any witness tables that are marked as `KeepAlive`,
// but are not used for dynamic dispatch, unpin them so we don't
// do unnecessary work to lower them.