diff options
| author | Yong He <yonghe@outlook.com> | 2024-05-15 18:07:36 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-15 18:07:36 -0700 |
| commit | 3b0de8b6ea484091146f61e663c63beeac5b4798 (patch) | |
| tree | 8093bc0af8d0801435c29abf5c5f1fdd3e7cc09a /source/slang/slang-lower-to-ir.cpp | |
| parent | cc88530a722cc2ce7a09f2a39dadeeb504e2f221 (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.cpp | 133 |
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)) { |
