summaryrefslogtreecommitdiff
path: root/source/slang/lower-to-ir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/lower-to-ir.cpp')
-rw-r--r--source/slang/lower-to-ir.cpp72
1 files changed, 60 insertions, 12 deletions
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index b53bb8ebb..e5d62d257 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -4793,21 +4793,23 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// A user-defined variable declaration will usually turn into
// an `alloca` operation for the variable's storage,
// plus some code to initialize it and then store to the variable.
- //
- // TODO: we may want to special-case things when the variable's
- // type, qualifiers, or context mark it as something that can't
- // be mutable (or even do some limited dataflow pass to check
- // which variables ever get assigned) so that we can directly
- // emit an SSA value in this common case.
- //
IRType* varType = lowerType(context, decl->getType());
- // TODO: If the variable is marked `static` then we need to
- // deal with it specially: we should move its allocation out
- // to the global scope, and then we have to deal with its
- // initializer expression a bit carefully (it should only
- // be initialized on-demand at its first use).
+ // As a special case, an immutable local variable with an
+ // initializer can just lower to the SSA value of its initializer.
+ //
+ if(as<LetDecl>(decl))
+ {
+ if(auto initExpr = decl->initExpr)
+ {
+ auto initVal = lowerRValueExpr(context, initExpr);
+ initVal = materialize(context, initVal);
+ setGlobalValue(context, decl, initVal);
+ return initVal;
+ }
+ }
+
LoweredValInfo varVal = createVar(context, varType, decl);
@@ -6187,6 +6189,30 @@ static void lowerProgramEntryPointToIR(
{
builder->addExportDecoration(loweredEntryPointFunc, getMangledName(entryPointFuncDeclRef).getUnownedSlice());
}
+
+ // We may have shader parameters of interface/existential type,
+ // which need us to supply concrete type information for specialization.
+ //
+ auto existentialSlotCount = entryPoint->getExistentialSlotCount();
+ if( existentialSlotCount )
+ {
+ List<IRInst*> existentialSlotArgs;
+ for( UInt ii = 0; ii < existentialSlotCount; ++ii )
+ {
+ auto arg = entryPoint->getExistentialSlotArg(ii);
+
+ auto irArgType = lowerType(context, arg.type);
+ auto irWitnessTable = lowerSimpleVal(context, arg.witness);
+
+ existentialSlotArgs.Add(irArgType);
+ existentialSlotArgs.Add(irWitnessTable);
+ }
+
+ builder->addBindExistentialSlotsDecoration(loweredEntryPointFunc, existentialSlotArgs.Count(), existentialSlotArgs.Buffer());
+ }
+
+
+
}
/// Ensure that `decl` and all relevant declarations under it get emitted.
@@ -6394,6 +6420,28 @@ RefPtr<IRModule> generateIRForProgram(
}
}
+ // We may have shader parameters of interface/existential type,
+ // which need us to supply concrete type information for specialization.
+ //
+ auto existentialSlotCount = program->getExistentialSlotCount();
+ if( existentialSlotCount )
+ {
+ List<IRInst*> existentialSlotArgs;
+ for( UInt ii = 0; ii < existentialSlotCount; ++ii )
+ {
+ auto arg = program->getExistentialSlotArg(ii);
+
+ auto irArgType = lowerType(context, arg.type);
+ auto irWitnessTable = lowerSimpleVal(context, arg.witness);
+
+ existentialSlotArgs.Add(irArgType);
+ existentialSlotArgs.Add(irWitnessTable);
+ }
+
+ builder->emitBindGlobalExistentialSlots(existentialSlotArgs.Count(), existentialSlotArgs.Buffer());
+ }
+
+
// TODO: Should we apply any of the validation or
// mandatory optimization passes here?