diff options
Diffstat (limited to 'source/slang/lower-to-ir.cpp')
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 72 |
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? |
