summaryrefslogtreecommitdiff
path: root/source/slang/slang-lower-to-ir.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-05-15 18:07:36 -0700
committerGitHub <noreply@github.com>2024-05-15 18:07:36 -0700
commit3b0de8b6ea484091146f61e663c63beeac5b4798 (patch)
tree8093bc0af8d0801435c29abf5c5f1fdd3e7cc09a /source/slang/slang-lower-to-ir.cpp
parentcc88530a722cc2ce7a09f2a39dadeeb504e2f221 (diff)
Add diagnostic to prevent defining unsized variables. (#4168)
* Add diagnostic to prevent defining unsized static variables. * Fix tests. * Add more tests. * Fix to allow defining variables of link-time size. * update diagnostic message. * Fix tests. * Simplify code.
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
-rw-r--r--source/slang/slang-lower-to-ir.cpp133
1 files changed, 75 insertions, 58 deletions
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index debe5078d..f2a31a8da 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -7782,6 +7782,33 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return false;
}
+ struct NestedContext
+ {
+ IRGenEnv subEnvStorage;
+ IRBuilder subBuilderStorage;
+ IRGenContext subContextStorage;
+
+ NestedContext(DeclLoweringVisitor* outer)
+ : subBuilderStorage(*outer->getBuilder())
+ , subContextStorage(*outer->context)
+ {
+ auto outerContext = outer->context;
+
+ subEnvStorage.outer = outerContext->env;
+
+ subContextStorage.irBuilder = &subBuilderStorage;
+ subContextStorage.env = &subEnvStorage;
+
+ subContextStorage.thisType = outerContext->thisType;
+ subContextStorage.thisTypeWitness = outerContext->thisTypeWitness;
+
+ subContextStorage.returnDestination = LoweredValInfo();
+ }
+
+ IRBuilder* getBuilder() { return &subBuilderStorage; }
+ IRGenContext* getContext() { return &subContextStorage; }
+ };
+
LoweredValInfo lowerGlobalShaderParam(VarDecl* decl)
{
IRType* paramType = lowerType(context, decl->getType());
@@ -7938,47 +7965,51 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return lowerGlobalConstantDecl(decl);
}
- IRType* varType = lowerType(context, decl->getType());
+ NestedContext nested(this);
+ auto subBuilder = nested.getBuilder();
+ auto subContext = nested.getContext();
- auto builder = getBuilder();
+ IRGeneric* outerGeneric = nullptr;
+
+ // If we are static, then we need to insert the declaration before the parent.
+ // This tries to match the behavior of previous `lowerFunctionStaticConstVarDecl` functionality
+ if (isFunctionStaticVarDecl(decl))
+ {
+ // We need to insert the constant at a level above
+ // the function being emitted. This will usually
+ // be the global scope, but it might be an outer
+ // generic if we are lowering a generic function.
+ subBuilder->setInsertBefore(subBuilder->getFunc());
+ }
+ else if (!isFunctionVarDecl(decl))
+ {
+ outerGeneric = emitOuterGenerics(subContext, decl, decl);
+ }
+
+ IRType* varType = lowerType(subContext, decl->getType());
// TODO(JS): Do we create something derived from IRGlobalVar? Or do we use
// a decoration to identify an *actual* global?
- IRGlobalValueWithCode* irGlobal = builder->createGlobalVar(varType);
- LoweredValInfo globalVal = LoweredValInfo::ptr(irGlobal);
+ IRGlobalValueWithCode* irGlobal = subBuilder->createGlobalVar(varType);
- addLinkageDecoration(context, irGlobal, decl);
- addNameHint(context, irGlobal, decl);
+ addLinkageDecoration(subContext, irGlobal, decl);
+ addNameHint(subContext, irGlobal, decl);
- maybeSetRate(context, irGlobal, decl);
+ maybeSetRate(subContext, irGlobal, decl);
- addVarDecorations(context, irGlobal, decl);
- maybeAddDebugLocationDecoration(context, irGlobal);
+ addVarDecorations(subContext, irGlobal, decl);
+ maybeAddDebugLocationDecoration(subContext, irGlobal);
if (decl)
{
- builder->addHighLevelDeclDecoration(irGlobal, decl);
+ subBuilder->addHighLevelDeclDecoration(irGlobal, decl);
}
- // A global variable's SSA value is a *pointer* to
- // the underlying storage.
- context->setGlobalValue(decl, globalVal);
-
if( auto initExpr = decl->initExpr )
{
- IRBuilder subBuilderStorage = *getBuilder();
- IRBuilder* subBuilder = &subBuilderStorage;
-
subBuilder->setInsertInto(irGlobal);
- IRGenContext subContextStorage = *context;
- IRGenContext* subContext = &subContextStorage;
-
- subContext->irBuilder = subBuilder;
-
- // TODO: set up a parent IR decl to put the instructions into
-
IRBlock* entryBlock = subBuilder->emitBlock();
subBuilder->setInsertInto(entryBlock);
@@ -7986,38 +8017,14 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
subContext->irBuilder->emitReturn(getSimpleVal(subContext, initVal));
}
- irGlobal->moveToEnd();
+ // A global variable's SSA value is a *pointer* to
+ // the underlying storage.
+ auto loweredValue = LoweredValInfo::ptr(finishOuterGenerics(subBuilder, irGlobal, outerGeneric));
+ context->setGlobalValue(decl, loweredValue);
- return globalVal;
+ return loweredValue;
}
- struct NestedContext
- {
- IRGenEnv subEnvStorage;
- IRBuilder subBuilderStorage;
- IRGenContext subContextStorage;
-
- NestedContext(DeclLoweringVisitor* outer)
- : subBuilderStorage(*outer->getBuilder())
- , subContextStorage(*outer->context)
- {
- auto outerContext = outer->context;
-
- subEnvStorage.outer = outerContext->env;
-
- subContextStorage.irBuilder = &subBuilderStorage;
- subContextStorage.env = &subEnvStorage;
-
- subContextStorage.thisType = outerContext->thisType;
- subContextStorage.thisTypeWitness = outerContext->thisTypeWitness;
-
- subContextStorage.returnDestination = LoweredValInfo();
- }
-
- IRBuilder* getBuilder() { return &subBuilderStorage; }
- IRGenContext* getContext() { return &subContextStorage; }
- };
-
LoweredValInfo lowerFunctionStaticConstVarDecl(
VarDeclBase* decl)
{
@@ -10235,10 +10242,10 @@ bool canDeclLowerToAGeneric(Decl* decl)
// a generic that returns a type (a simple type-level function).
if(as<TypeDefDecl>(decl)) return true;
- // If we have a variable declaration that is *static* and *const* we can lower to a generic
+ // A static member variable declaration can be lowered into a generic.
if (auto varDecl = as<VarDecl>(decl))
{
- if (varDecl->hasModifier<HLSLStaticModifier>() && varDecl->hasModifier<ConstModifier>())
+ if (varDecl->hasModifier<HLSLStaticModifier>())
{
return !isFunctionVarDecl(varDecl);
}
@@ -10360,7 +10367,9 @@ LoweredValInfo emitDeclRef(
// We can only really specialize things that map to single values.
// It would be an error if we got a non-`None` value that
// wasn't somehow a single value.
- auto irGenericVal = getSimpleVal(context, genericVal);
+ genericVal = materialize(context, genericVal);
+ auto irGenericVal = genericVal.val;
+ SLANG_ASSERT(irGenericVal);
// We have the IR value for the generic we'd like to specialize,
// and now we need to get the value for the arguments.
@@ -10392,8 +10401,16 @@ LoweredValInfo emitDeclRef(
irGenericVal,
irArgs.getCount(),
irArgs.getBuffer());
-
- return LoweredValInfo::simple(irSpecializedVal);
+ switch (genericVal.flavor)
+ {
+ case LoweredValInfo::Flavor::Simple:
+ return LoweredValInfo::simple(irSpecializedVal);
+ case LoweredValInfo::Flavor::Ptr:
+ return LoweredValInfo::ptr(irSpecializedVal);
+ default:
+ SLANG_UNEXPECTED("unhandled lowered value flavor");
+ UNREACHABLE_RETURN(LoweredValInfo());
+ }
}
else if(auto thisTypeSubst = as<LookupDeclRef>(subst))
{