summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-c-like.cpp6
-rw-r--r--source/slang/slang-emit.cpp3
-rw-r--r--source/slang/slang-ir-link.cpp28
-rw-r--r--source/slang/slang-ir-lower-generics.cpp2
-rw-r--r--source/slang/slang-ir-specialize.cpp5
-rw-r--r--source/slang/slang-lower-to-ir.cpp62
6 files changed, 68 insertions, 38 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index faf7b8c1d..516a8ff22 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -305,7 +305,8 @@ void CLikeSourceEmitter::emitWitnessTable(IRWitnessTable* witnessTable)
void CLikeSourceEmitter::emitInterface(IRInterfaceType* interfaceType)
{
SLANG_UNUSED(interfaceType);
- SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "Unimplemented emit: IROpInterfaceType.");
+ // By default, don't emit anything for interface types.
+ // This behavior is overloaded by concrete emitters.
}
void CLikeSourceEmitter::emitTypeImpl(IRType* type, const StringSliceLoc* nameAndLoc)
@@ -2289,7 +2290,6 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO
m_writer->emit(")");
}
break;
-
default:
diagnoseUnhandledInst(inst);
break;
@@ -3654,6 +3654,8 @@ void CLikeSourceEmitter::ensureGlobalInst(ComputeEmitActionsContext* ctx, IRInst
if (!m_compileRequest->allowDynamicCode)
return;
break;
+
+ case kIROp_InterfaceRequirementEntry:
case kIROp_Generic:
return;
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp
index f2552f95d..59b059e91 100644
--- a/source/slang/slang-emit.cpp
+++ b/source/slang/slang-emit.cpp
@@ -280,7 +280,8 @@ Result linkAndOptimizeIR(
// For targets that supports dynamic dispatch, we need to lower the
// generics / interface types to ordinary functions and types using
// function pointers.
- lowerGenerics(irModule);
+ if (compileRequest->allowDynamicCode)
+ lowerGenerics(irModule);
break;
default:
break;
diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp
index 4e6ad74a4..e556fd738 100644
--- a/source/slang/slang-ir-link.cpp
+++ b/source/slang/slang-ir-link.cpp
@@ -89,6 +89,25 @@ struct IRSpecContextBase
}
};
+enum class GlobalValueClass
+{
+ StructKey,
+ Other
+};
+
+// Get the "class" of a global value. If there are more than one value of the same class,
+// only one value in each class will be selected during linking.
+GlobalValueClass getGlobalValueClass(IRInst* value)
+{
+ switch (value->op)
+ {
+ case kIROp_StructKey:
+ return GlobalValueClass::StructKey;
+ default:
+ return GlobalValueClass::Other;
+ }
+}
+
void registerClonedValue(
IRSpecContextBase* context,
IRInst* clonedValue,
@@ -128,9 +147,11 @@ void registerClonedValue(
IROriginalValuesForClone const& originalValues)
{
registerClonedValue(context, clonedValue, originalValues.originalVal);
+ auto valueClass = getGlobalValueClass(clonedValue);
for( auto s = originalValues.sym; s; s = s->nextWithSameName )
{
- registerClonedValue(context, clonedValue, s->irGlobalValue);
+ if (getGlobalValueClass(s->irGlobalValue) == valueClass)
+ registerClonedValue(context, clonedValue, s->irGlobalValue);
}
}
@@ -1153,7 +1174,6 @@ IRInst* cloneGlobalValueImpl(
return clonedValue;
}
-
/// Clone a global value, which has the given `originalLinkage`.
///
/// The `originalVal` is a known global IR value with that linkage, if one is available.
@@ -1214,10 +1234,12 @@ IRInst* cloneGlobalValueWithLinkage(
// definitions over declarations.
//
IRInst* bestVal = nullptr;
+ auto valueClass = getGlobalValueClass(originalVal);
for(IRSpecSymbol* ss = sym; ss; ss = ss->nextWithSameName )
{
IRInst* newVal = ss->irGlobalValue;
- if(isBetterForTarget(context, newVal, bestVal))
+ if (getGlobalValueClass(newVal) == valueClass &&
+ isBetterForTarget(context, newVal, bestVal))
bestVal = newVal;
}
diff --git a/source/slang/slang-ir-lower-generics.cpp b/source/slang/slang-ir-lower-generics.cpp
index fe0fa3364..4701a3cce 100644
--- a/source/slang/slang-ir-lower-generics.cpp
+++ b/source/slang/slang-ir-lower-generics.cpp
@@ -162,7 +162,7 @@ namespace Slang
newOperands.add(paramType);
}
}
- if (!translated)
+ if (!translated && additionalParamCount == 0)
return funcType;
for (UInt i = 0; i < additionalParamCount; i++)
{
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp
index cf475f1ff..3acb34c87 100644
--- a/source/slang/slang-ir-specialize.cpp
+++ b/source/slang/slang-ir-specialize.cpp
@@ -416,6 +416,11 @@ struct SpecializationContext
case kIROp_BindExistentialsType:
break;
+ // An interface type is always fully specialized.
+ case kIROp_InterfaceType:
+ markInstAsFullySpecialized(inst);
+ break;
+
case kIROp_Specialize:
// The `specialize` instruction is a bit sepcial,
// because it is possible to have a `specialize`
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index ff356fd48..3e211e7ca 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -4466,7 +4466,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto type = lowerType(subContext, decl->type.type);
- return LoweredValInfo::simple(finishOuterGenerics(subBuilder, type));
+ return LoweredValInfo::simple(finishOuterGenerics(subBuilder, type, outerGeneric));
}
LoweredValInfo visitGenericTypeParamDecl(GenericTypeParamDecl* /*decl*/)
@@ -4536,7 +4536,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
Dictionary<WitnessTable*, IRWitnessTable*> mapASTToIRWitnessTable)
{
auto subBuilder = subContext->irBuilder;
-
+
for(auto entry : astWitnessTable->requirementDictionary)
{
auto requiredMemberDecl = entry.Key;
@@ -4676,7 +4676,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
NestedContext nested(this);
auto subBuilder = nested.getBuilder();
auto subContext = nested.getContext();
- emitOuterGenerics(subContext, inheritanceDecl, inheritanceDecl);
+ auto outerGeneric = emitOuterGenerics(subContext, inheritanceDecl, inheritanceDecl);
// Lower the super-type to force its declaration to be lowered.
//
@@ -4705,7 +4705,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
irWitnessTable->moveToEnd();
- return LoweredValInfo::simple(finishOuterGenerics(subBuilder, irWitnessTable));
+ return LoweredValInfo::simple(finishOuterGenerics(subBuilder, irWitnessTable, outerGeneric));
}
LoweredValInfo visitDeclGroup(DeclGroup* declGroup)
@@ -5106,7 +5106,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto subBuilder = nestedContext.getBuilder();
auto subContext = nestedContext.getContext();
subBuilder->setInsertInto(subBuilder->getModule()->getModuleInst());
- emitOuterGenerics(subContext, decl, decl);
+ auto outerGeneric = emitOuterGenerics(subContext, decl, decl);
IRType* subVarType = lowerType(subContext, decl->getType());
@@ -5207,7 +5207,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
}
irGlobal->moveToEnd();
- finishOuterGenerics(subBuilder, irGlobal);
+ finishOuterGenerics(subBuilder, irGlobal, outerGeneric);
return globalVal;
}
@@ -5317,7 +5317,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
}
// Emit any generics that should wrap the actual type.
- emitOuterGenerics(subContext, decl, decl);
+ auto outerGeneric = emitOuterGenerics(subContext, decl, decl);
IRInterfaceType* irInterface = subBuilder->createInterfaceType(
requirementEntries.getCount(),
@@ -5333,7 +5333,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
addTargetIntrinsicDecorations(irInterface, decl);
- return LoweredValInfo::simple(finishOuterGenerics(subBuilder, irInterface));
+ return LoweredValInfo::simple(finishOuterGenerics(subBuilder, irInterface, outerGeneric));
}
LoweredValInfo visitEnumCaseDecl(EnumCaseDecl* decl)
@@ -5367,7 +5367,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
NestedContext nestedContext(this);
auto subBuilder = nestedContext.getBuilder();
auto subContext = nestedContext.getContext();
- emitOuterGenerics(subContext, decl, decl);
+ auto outerGeneric = emitOuterGenerics(subContext, decl, decl);
// An `enum` declaration will currently lower directly to its "tag"
// type, so that any references to the `enum` become referenes to
@@ -5379,7 +5379,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
IRType* loweredTagType = lowerType(subContext, decl->tagType);
- return LoweredValInfo::simple(finishOuterGenerics(subBuilder, loweredTagType));
+ return LoweredValInfo::simple(finishOuterGenerics(subBuilder, loweredTagType, outerGeneric));
}
LoweredValInfo visitAggTypeDecl(AggTypeDecl* decl)
@@ -5406,7 +5406,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto subContext = nestedContext.getContext();
// Emit any generics that should wrap the actual type.
- emitOuterGenerics(subContext, decl, decl);
+ auto outerGeneric = emitOuterGenerics(subContext, decl, decl);
IRInst* resultType = nullptr;
if (as<AssocTypeDecl>(decl))
@@ -5490,7 +5490,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
resultType->moveToEnd();
addTargetIntrinsicDecorations(resultType, decl);
- return LoweredValInfo::simple(finishOuterGenerics(subBuilder, resultType));
+ return LoweredValInfo::simple(finishOuterGenerics(subBuilder, resultType, outerGeneric));
}
LoweredValInfo lowerMemberVarDecl(VarDecl* fieldDecl)
@@ -5819,24 +5819,25 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
//
IRInst* finishOuterGenerics(
IRBuilder* subBuilder,
- IRInst* val)
+ IRInst* val,
+ IRGeneric* parentGeneric)
{
IRInst* v = val;
- for(;;)
+ while (parentGeneric)
{
- auto parentBlock = as<IRBlock>(v->getParent());
- if (!parentBlock) break;
-
- auto parentGeneric = as<IRGeneric>(parentBlock->getParent());
- if (!parentGeneric) break;
-
- subBuilder->setInsertInto(parentBlock);
+ subBuilder->setInsertInto(parentGeneric->getFirstBlock());
subBuilder->emitReturn(v);
parentGeneric->moveToEnd();
// There might be more outer generics,
// so we need to loop until we run out.
v = parentGeneric;
+ auto parentBlock = as<IRBlock>(v->getParent());
+ if (!parentBlock) break;
+
+ parentGeneric = as<IRGeneric>(parentBlock->getParent());
+ if (!parentGeneric) break;
+
}
return v;
}
@@ -6066,10 +6067,10 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// Simple case of a by-value input parameter.
break;
- // If the parameter is declared `out` or `inout`,
- // then we will represent it with a pointer type in
- // the IR, but we will use a specialized pointer
- // type that encodes the parameter direction information.
+ // If the parameter is declared `out` or `inout`,
+ // then we will represent it with a pointer type in
+ // the IR, but we will use a specialized pointer
+ // type that encodes the parameter direction information.
case kParameterDirection_Out:
irParamType = subBuilder->getOutType(irParamType);
break;
@@ -6153,7 +6154,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto funcTypeBuilder = nestedContextFuncType.getBuilder();
auto funcTypeContext = nestedContextFuncType.getContext();
- emitOuterGenerics(funcTypeContext, decl, decl);
+ auto outerGenerics = emitOuterGenerics(funcTypeContext, decl, decl);
ParameterLists parameterLists;
List<IRType*> paramTypes;
@@ -6166,7 +6167,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
funcTypeContext,
decl);
- return finishOuterGenerics(funcTypeBuilder, irFuncType);
+ return finishOuterGenerics(funcTypeBuilder, irFuncType, outerGenerics);
}
LoweredValInfo lowerFuncDecl(FunctionDeclBase* decl)
@@ -6178,7 +6179,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
auto subBuilder = nestedContextFunc.getBuilder();
auto subContext = nestedContextFunc.getContext();
- emitOuterGenerics(subContext, decl, decl);
+ auto outerGeneric = emitOuterGenerics(subContext, decl, decl);
// need to create an IR function here
@@ -6550,12 +6551,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// If this function is defined inside an interface, add a reference to the IRFunc from
// the interface's type definition.
- auto finalVal = finishOuterGenerics(subBuilder, irFunc);
-
+ auto finalVal = finishOuterGenerics(subBuilder, irFunc, outerGeneric);
if (auto genericVal = as<IRGeneric>(finalVal))
{
auto funcType = lowerFuncType(decl);
- genericVal->typeUse.set(funcType);
+ genericVal->setFullType((IRType*)funcType);
}
maybeAssociateToInterfaceType(decl, finalVal);