@@ -7782,6 +7782,33 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
7782
7782
return false;
7783
7783
}
7784
7784
7785
+ struct NestedContext
7786
+ {
7787
+ IRGenEnv subEnvStorage;
7788
+ IRBuilder subBuilderStorage;
7789
+ IRGenContext subContextStorage;
7790
+
7791
+ NestedContext(DeclLoweringVisitor* outer)
7792
+ : subBuilderStorage(*outer->getBuilder())
7793
+ , subContextStorage(*outer->context)
7794
+ {
7795
+ auto outerContext = outer->context;
7796
+
7797
+ subEnvStorage.outer = outerContext->env;
7798
+
7799
+ subContextStorage.irBuilder = &subBuilderStorage;
7800
+ subContextStorage.env = &subEnvStorage;
7801
+
7802
+ subContextStorage.thisType = outerContext->thisType;
7803
+ subContextStorage.thisTypeWitness = outerContext->thisTypeWitness;
7804
+
7805
+ subContextStorage.returnDestination = LoweredValInfo();
7806
+ }
7807
+
7808
+ IRBuilder* getBuilder() { return &subBuilderStorage; }
7809
+ IRGenContext* getContext() { return &subContextStorage; }
7810
+ };
7811
+
7785
7812
LoweredValInfo lowerGlobalShaderParam(VarDecl* decl)
7786
7813
{
7787
7814
IRType* paramType = lowerType(context, decl->getType());
@@ -7938,86 +7965,66 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
7938
7965
return lowerGlobalConstantDecl(decl);
7939
7966
}
7940
7967
7941
- IRType* varType = lowerType(context, decl->getType());
7968
+ NestedContext nested(this);
7969
+ auto subBuilder = nested.getBuilder();
7970
+ auto subContext = nested.getContext();
7942
7971
7943
- auto builder = getBuilder();
7972
+ IRGeneric* outerGeneric = nullptr;
7973
+
7974
+ // If we are static, then we need to insert the declaration before the parent.
7975
+ // This tries to match the behavior of previous `lowerFunctionStaticConstVarDecl` functionality
7976
+ if (isFunctionStaticVarDecl(decl))
7977
+ {
7978
+ // We need to insert the constant at a level above
7979
+ // the function being emitted. This will usually
7980
+ // be the global scope, but it might be an outer
7981
+ // generic if we are lowering a generic function.
7982
+ subBuilder->setInsertBefore(subBuilder->getFunc());
7983
+ }
7984
+ else if (!isFunctionVarDecl(decl))
7985
+ {
7986
+ outerGeneric = emitOuterGenerics(subContext, decl, decl);
7987
+ }
7988
+
7989
+ IRType* varType = lowerType(subContext, decl->getType());
7944
7990
7945
7991
// TODO(JS): Do we create something derived from IRGlobalVar? Or do we use
7946
7992
// a decoration to identify an *actual* global?
7947
7993
7948
- IRGlobalValueWithCode* irGlobal = builder->createGlobalVar(varType);
7949
- LoweredValInfo globalVal = LoweredValInfo::ptr(irGlobal);
7994
+ IRGlobalValueWithCode* irGlobal = subBuilder->createGlobalVar(varType);
7950
7995
7951
- addLinkageDecoration(context , irGlobal, decl);
7952
- addNameHint(context , irGlobal, decl);
7996
+ addLinkageDecoration(subContext , irGlobal, decl);
7997
+ addNameHint(subContext , irGlobal, decl);
7953
7998
7954
- maybeSetRate(context , irGlobal, decl);
7999
+ maybeSetRate(subContext , irGlobal, decl);
7955
8000
7956
- addVarDecorations(context , irGlobal, decl);
7957
- maybeAddDebugLocationDecoration(context , irGlobal);
8001
+ addVarDecorations(subContext , irGlobal, decl);
8002
+ maybeAddDebugLocationDecoration(subContext , irGlobal);
7958
8003
7959
8004
if (decl)
7960
8005
{
7961
- builder ->addHighLevelDeclDecoration(irGlobal, decl);
8006
+ subBuilder ->addHighLevelDeclDecoration(irGlobal, decl);
7962
8007
}
7963
8008
7964
- // A global variable's SSA value is a *pointer* to
7965
- // the underlying storage.
7966
- context->setGlobalValue(decl, globalVal);
7967
-
7968
8009
if( auto initExpr = decl->initExpr )
7969
8010
{
7970
- IRBuilder subBuilderStorage = *getBuilder();
7971
- IRBuilder* subBuilder = &subBuilderStorage;
7972
-
7973
8011
subBuilder->setInsertInto(irGlobal);
7974
8012
7975
- IRGenContext subContextStorage = *context;
7976
- IRGenContext* subContext = &subContextStorage;
7977
-
7978
- subContext->irBuilder = subBuilder;
7979
-
7980
- // TODO: set up a parent IR decl to put the instructions into
7981
-
7982
8013
IRBlock* entryBlock = subBuilder->emitBlock();
7983
8014
subBuilder->setInsertInto(entryBlock);
7984
8015
7985
8016
LoweredValInfo initVal = lowerLValueExpr(subContext, initExpr);
7986
8017
subContext->irBuilder->emitReturn(getSimpleVal(subContext, initVal));
7987
8018
}
7988
8019
7989
- irGlobal->moveToEnd();
8020
+ // A global variable's SSA value is a *pointer* to
8021
+ // the underlying storage.
8022
+ auto loweredValue = LoweredValInfo::ptr(finishOuterGenerics(subBuilder, irGlobal, outerGeneric));
8023
+ context->setGlobalValue(decl, loweredValue);
7990
8024
7991
- return globalVal ;
8025
+ return loweredValue ;
7992
8026
}
7993
8027
7994
- struct NestedContext
7995
- {
7996
- IRGenEnv subEnvStorage;
7997
- IRBuilder subBuilderStorage;
7998
- IRGenContext subContextStorage;
7999
-
8000
- NestedContext(DeclLoweringVisitor* outer)
8001
- : subBuilderStorage(*outer->getBuilder())
8002
- , subContextStorage(*outer->context)
8003
- {
8004
- auto outerContext = outer->context;
8005
-
8006
- subEnvStorage.outer = outerContext->env;
8007
-
8008
- subContextStorage.irBuilder = &subBuilderStorage;
8009
- subContextStorage.env = &subEnvStorage;
8010
-
8011
- subContextStorage.thisType = outerContext->thisType;
8012
- subContextStorage.thisTypeWitness = outerContext->thisTypeWitness;
8013
-
8014
- subContextStorage.returnDestination = LoweredValInfo();
8015
- }
8016
-
8017
- IRBuilder* getBuilder() { return &subBuilderStorage; }
8018
- IRGenContext* getContext() { return &subContextStorage; }
8019
- };
8020
-
8021
8028
LoweredValInfo lowerFunctionStaticConstVarDecl(
8022
8029
VarDeclBase* decl)
8023
8030
{
@@ -10235,10 +10242,10 @@ bool canDeclLowerToAGeneric(Decl* decl)
10235
10242
// a generic that returns a type (a simple type-level function).
10236
10243
if(as<TypeDefDecl>(decl)) return true;
10237
10244
10238
- // If we have a variable declaration that is *static* and *const* we can lower to a generic
10245
+ // A static member variable declaration can be lowered into a generic.
10239
10246
if (auto varDecl = as<VarDecl>(decl))
10240
10247
{
10241
- if (varDecl->hasModifier<HLSLStaticModifier>() && varDecl->hasModifier<ConstModifier>() )
10248
+ if (varDecl->hasModifier<HLSLStaticModifier>())
10242
10249
{
10243
10250
return !isFunctionVarDecl(varDecl);
10244
10251
}
@@ -10360,7 +10367,9 @@ LoweredValInfo emitDeclRef(
10360
10367
// We can only really specialize things that map to single values.
10361
10368
// It would be an error if we got a non-`None` value that
10362
10369
// wasn't somehow a single value.
10363
- auto irGenericVal = getSimpleVal(context, genericVal);
10370
+ genericVal = materialize(context, genericVal);
10371
+ auto irGenericVal = genericVal.val;
10372
+ SLANG_ASSERT(irGenericVal);
10364
10373
10365
10374
// We have the IR value for the generic we'd like to specialize,
10366
10375
// and now we need to get the value for the arguments.
@@ -10392,8 +10401,16 @@ LoweredValInfo emitDeclRef(
10392
10401
irGenericVal,
10393
10402
irArgs.getCount(),
10394
10403
irArgs.getBuffer());
10395
-
10396
- return LoweredValInfo::simple(irSpecializedVal);
10404
+ switch (genericVal.flavor)
10405
+ {
10406
+ case LoweredValInfo::Flavor::Simple:
10407
+ return LoweredValInfo::simple(irSpecializedVal);
10408
+ case LoweredValInfo::Flavor::Ptr:
10409
+ return LoweredValInfo::ptr(irSpecializedVal);
10410
+ default:
10411
+ SLANG_UNEXPECTED("unhandled lowered value flavor");
10412
+ UNREACHABLE_RETURN(LoweredValInfo());
10413
+ }
10397
10414
}
10398
10415
else if(auto thisTypeSubst = as<LookupDeclRef>(subst))
10399
10416
{
0 commit comments