@@ -7768,6 +7768,33 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
7768
7768
return false;
7769
7769
}
7770
7770
7771
+ struct NestedContext
7772
+ {
7773
+ IRGenEnv subEnvStorage;
7774
+ IRBuilder subBuilderStorage;
7775
+ IRGenContext subContextStorage;
7776
+
7777
+ NestedContext(DeclLoweringVisitor* outer)
7778
+ : subBuilderStorage(*outer->getBuilder())
7779
+ , subContextStorage(*outer->context)
7780
+ {
7781
+ auto outerContext = outer->context;
7782
+
7783
+ subEnvStorage.outer = outerContext->env;
7784
+
7785
+ subContextStorage.irBuilder = &subBuilderStorage;
7786
+ subContextStorage.env = &subEnvStorage;
7787
+
7788
+ subContextStorage.thisType = outerContext->thisType;
7789
+ subContextStorage.thisTypeWitness = outerContext->thisTypeWitness;
7790
+
7791
+ subContextStorage.returnDestination = LoweredValInfo();
7792
+ }
7793
+
7794
+ IRBuilder* getBuilder() { return &subBuilderStorage; }
7795
+ IRGenContext* getContext() { return &subContextStorage; }
7796
+ };
7797
+
7771
7798
LoweredValInfo lowerGlobalShaderParam(VarDecl* decl)
7772
7799
{
7773
7800
IRType* paramType = lowerType(context, decl->getType());
@@ -7924,86 +7951,66 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
7924
7951
return lowerGlobalConstantDecl(decl);
7925
7952
}
7926
7953
7927
- IRType* varType = lowerType(context, decl->getType());
7954
+ NestedContext nested(this);
7955
+ auto subBuilder = nested.getBuilder();
7956
+ auto subContext = nested.getContext();
7928
7957
7929
- auto builder = getBuilder();
7958
+ IRGeneric* outerGeneric = nullptr;
7959
+
7960
+ // If we are static, then we need to insert the declaration before the parent.
7961
+ // This tries to match the behavior of previous `lowerFunctionStaticConstVarDecl` functionality
7962
+ if (isFunctionStaticVarDecl(decl))
7963
+ {
7964
+ // We need to insert the constant at a level above
7965
+ // the function being emitted. This will usually
7966
+ // be the global scope, but it might be an outer
7967
+ // generic if we are lowering a generic function.
7968
+ subBuilder->setInsertBefore(subBuilder->getFunc());
7969
+ }
7970
+ else if (!isFunctionVarDecl(decl))
7971
+ {
7972
+ outerGeneric = emitOuterGenerics(subContext, decl, decl);
7973
+ }
7974
+
7975
+ IRType* varType = lowerType(subContext, decl->getType());
7930
7976
7931
7977
// TODO(JS): Do we create something derived from IRGlobalVar? Or do we use
7932
7978
// a decoration to identify an *actual* global?
7933
7979
7934
- IRGlobalValueWithCode* irGlobal = builder->createGlobalVar(varType);
7935
- LoweredValInfo globalVal = LoweredValInfo::ptr(irGlobal);
7980
+ IRGlobalValueWithCode* irGlobal = subBuilder->createGlobalVar(varType);
7936
7981
7937
- addLinkageDecoration(context , irGlobal, decl);
7938
- addNameHint(context , irGlobal, decl);
7982
+ addLinkageDecoration(subContext , irGlobal, decl);
7983
+ addNameHint(subContext , irGlobal, decl);
7939
7984
7940
- maybeSetRate(context , irGlobal, decl);
7985
+ maybeSetRate(subContext , irGlobal, decl);
7941
7986
7942
- addVarDecorations(context , irGlobal, decl);
7943
- maybeAddDebugLocationDecoration(context , irGlobal);
7987
+ addVarDecorations(subContext , irGlobal, decl);
7988
+ maybeAddDebugLocationDecoration(subContext , irGlobal);
7944
7989
7945
7990
if (decl)
7946
7991
{
7947
- builder ->addHighLevelDeclDecoration(irGlobal, decl);
7992
+ subBuilder ->addHighLevelDeclDecoration(irGlobal, decl);
7948
7993
}
7949
7994
7950
- // A global variable's SSA value is a *pointer* to
7951
- // the underlying storage.
7952
- context->setGlobalValue(decl, globalVal);
7953
-
7954
7995
if( auto initExpr = decl->initExpr )
7955
7996
{
7956
- IRBuilder subBuilderStorage = *getBuilder();
7957
- IRBuilder* subBuilder = &subBuilderStorage;
7958
-
7959
7997
subBuilder->setInsertInto(irGlobal);
7960
7998
7961
- IRGenContext subContextStorage = *context;
7962
- IRGenContext* subContext = &subContextStorage;
7963
-
7964
- subContext->irBuilder = subBuilder;
7965
-
7966
- // TODO: set up a parent IR decl to put the instructions into
7967
-
7968
7999
IRBlock* entryBlock = subBuilder->emitBlock();
7969
8000
subBuilder->setInsertInto(entryBlock);
7970
8001
7971
8002
LoweredValInfo initVal = lowerLValueExpr(subContext, initExpr);
7972
8003
subContext->irBuilder->emitReturn(getSimpleVal(subContext, initVal));
7973
8004
}
7974
8005
7975
- irGlobal->moveToEnd();
8006
+ // A global variable's SSA value is a *pointer* to
8007
+ // the underlying storage.
8008
+ auto loweredValue = LoweredValInfo::ptr(finishOuterGenerics(subBuilder, irGlobal, outerGeneric));
8009
+ context->setGlobalValue(decl, loweredValue);
7976
8010
7977
- return globalVal ;
8011
+ return loweredValue ;
7978
8012
}
7979
8013
7980
- struct NestedContext
7981
- {
7982
- IRGenEnv subEnvStorage;
7983
- IRBuilder subBuilderStorage;
7984
- IRGenContext subContextStorage;
7985
-
7986
- NestedContext(DeclLoweringVisitor* outer)
7987
- : subBuilderStorage(*outer->getBuilder())
7988
- , subContextStorage(*outer->context)
7989
- {
7990
- auto outerContext = outer->context;
7991
-
7992
- subEnvStorage.outer = outerContext->env;
7993
-
7994
- subContextStorage.irBuilder = &subBuilderStorage;
7995
- subContextStorage.env = &subEnvStorage;
7996
-
7997
- subContextStorage.thisType = outerContext->thisType;
7998
- subContextStorage.thisTypeWitness = outerContext->thisTypeWitness;
7999
-
8000
- subContextStorage.returnDestination = LoweredValInfo();
8001
- }
8002
-
8003
- IRBuilder* getBuilder() { return &subBuilderStorage; }
8004
- IRGenContext* getContext() { return &subContextStorage; }
8005
- };
8006
-
8007
8014
LoweredValInfo lowerFunctionStaticConstVarDecl(
8008
8015
VarDeclBase* decl)
8009
8016
{
@@ -10221,10 +10228,10 @@ bool canDeclLowerToAGeneric(Decl* decl)
10221
10228
// a generic that returns a type (a simple type-level function).
10222
10229
if(as<TypeDefDecl>(decl)) return true;
10223
10230
10224
- // If we have a variable declaration that is *static* and *const* we can lower to a generic
10231
+ // A static member variable declaration can be lowered into a generic.
10225
10232
if (auto varDecl = as<VarDecl>(decl))
10226
10233
{
10227
- if (varDecl->hasModifier<HLSLStaticModifier>() && varDecl->hasModifier<ConstModifier>() )
10234
+ if (varDecl->hasModifier<HLSLStaticModifier>())
10228
10235
{
10229
10236
return !isFunctionVarDecl(varDecl);
10230
10237
}
@@ -10346,7 +10353,9 @@ LoweredValInfo emitDeclRef(
10346
10353
// We can only really specialize things that map to single values.
10347
10354
// It would be an error if we got a non-`None` value that
10348
10355
// wasn't somehow a single value.
10349
- auto irGenericVal = getSimpleVal(context, genericVal);
10356
+ genericVal = materialize(context, genericVal);
10357
+ auto irGenericVal = genericVal.val;
10358
+ SLANG_ASSERT(irGenericVal);
10350
10359
10351
10360
// We have the IR value for the generic we'd like to specialize,
10352
10361
// and now we need to get the value for the arguments.
@@ -10378,8 +10387,16 @@ LoweredValInfo emitDeclRef(
10378
10387
irGenericVal,
10379
10388
irArgs.getCount(),
10380
10389
irArgs.getBuffer());
10381
-
10382
- return LoweredValInfo::simple(irSpecializedVal);
10390
+ switch (genericVal.flavor)
10391
+ {
10392
+ case LoweredValInfo::Flavor::Simple:
10393
+ return LoweredValInfo::simple(irSpecializedVal);
10394
+ case LoweredValInfo::Flavor::Ptr:
10395
+ return LoweredValInfo::ptr(irSpecializedVal);
10396
+ default:
10397
+ SLANG_UNEXPECTED("unhandled lowered value flavor");
10398
+ UNREACHABLE_RETURN(LoweredValInfo());
10399
+ }
10383
10400
}
10384
10401
else if(auto thisTypeSubst = as<LookupDeclRef>(subst))
10385
10402
{
0 commit comments