From 9ac5c51ae1f0664a9dcb31392894e4f76bdbcf98 Mon Sep 17 00:00:00 2001 From: Yong He Date: Fri, 31 Jul 2020 18:30:10 -0700 Subject: Add [anyValueSize] attribute to interfaces and propagate that in the IR. (#1469) Co-authored-by: Tim Foley --- source/slang/slang-lower-to-ir.cpp | 101 ++++++++++++++++++++++++++++--------- 1 file changed, 77 insertions(+), 24 deletions(-) (limited to 'source/slang/slang-lower-to-ir.cpp') diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index b931212fd..36825f828 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -1085,6 +1085,23 @@ IRStructKey* getInterfaceRequirementKey( return requirementKey; } +void getGenericTypeConformances(IRGenContext* context, ShortList& supTypes, Decl* genericParamDecl) +{ + auto parent = genericParamDecl->parentDecl; + if (parent) + { + for (auto typeConstraint : parent->getMembersOfType()) + { + if (auto declRefType = as(typeConstraint->sub.type)) + { + if (declRefType->declRef.decl == genericParamDecl) + { + supTypes.add(lowerType(context, typeConstraint->getSup().type)); + } + } + } + } +} SubstitutionSet lowerSubstitutions(IRGenContext* context, SubstitutionSet subst); // @@ -1668,7 +1685,6 @@ struct ValLoweringVisitor : ValVisitorinterfaceDeclRef, getBuilder()->getTypeKind()); } - // We do not expect to encounter the following types in ASTs that have // passed front-end semantic checking. #define UNEXPECTED_CASE(NAME) IRType* visit##NAME(NAME*) { SLANG_UNEXPECTED(#NAME); UNREACHABLE_RETURN(nullptr); } @@ -3465,7 +3481,8 @@ struct ExprLoweringVisitorBase : ExprVisitor LoweredValInfo visitAssocTypeDecl(AssocTypeDecl* decl) { - return LoweredValInfo::simple(context->irBuilder->getAssociatedType()); + SLANG_UNIMPLEMENTED_X("associatedtype expression during code generation"); + UNREACHABLE_RETURN(LoweredValInfo()); } LoweredValInfo visitAssignExpr(AssignExpr* expr) @@ -5829,6 +5846,22 @@ struct DeclLoweringVisitor : DeclVisitor return Slang::getInterfaceRequirementKey(context, requirementDecl); } + LoweredValInfo visitAssocTypeDecl(AssocTypeDecl* decl) + { + SLANG_ASSERT(decl->parentDecl != nullptr); + ShortList constraintInterfaces; + for (auto inheritanceDecl : decl->getMembersOfType()) + { + auto baseType = lowerType(context, inheritanceDecl->base.type); + SLANG_ASSERT(baseType && baseType->op == kIROp_InterfaceType); + constraintInterfaces.add((IRInterfaceType*)baseType); + } + auto assocType = context->irBuilder->getAssociatedType( + constraintInterfaces.getArrayView().arrayView); + setValue(context, decl, assocType); + return LoweredValInfo::simple(assocType); + } + LoweredValInfo visitInterfaceDecl(InterfaceDecl* decl) { // The members of an interface will turn into the keys that will @@ -5851,18 +5884,6 @@ struct DeclLoweringVisitor : DeclVisitor // Emit any generics that should wrap the actual type. auto outerGeneric = emitOuterGenerics(subContext, decl, decl); - // Setup subContext for proper lowering `ThisType`, associated types and - // the interface decl's self reference. - subContext->thisType = getBuilder()->getThisType(); - - for (auto member : decl->members) - { - if (as(member)) - { - subContext->env->mapDeclToValue[member] = getBuilder()->getAssociatedType(); - } - } - // First, compute the number of requirement entries that will be included in this // interface type. UInt operandCount = 0; @@ -5884,6 +5905,17 @@ struct DeclLoweringVisitor : DeclVisitor // Add `irInterface` to decl mapping now to prevent cyclic lowering. setValue(subContext, decl, LoweredValInfo::simple(irInterface)); + // Setup subContext for proper lowering `ThisType`, associated types and + // the interface decl's self reference. + auto thisType = getBuilder()->getThisType(irInterface); + subContext->thisType = thisType; + + // Lower associated types first, so they can be referred to when lowering functions. + for (auto assocTypeDecl : decl->getMembersOfType()) + { + ensureDecl(subContext, assocTypeDecl); + } + UInt entryIndex = 0; for (auto requirementDecl : decl->members) @@ -5891,7 +5923,7 @@ struct DeclLoweringVisitor : DeclVisitor auto entry = subBuilder->createInterfaceRequirementEntry( getInterfaceRequirementKey(requirementDecl), nullptr); - IRInst* requirementVal = lowerDecl(subContext, requirementDecl).val; + IRInst* requirementVal = ensureDecl(subContext, requirementDecl).val; if (requirementVal) { switch (requirementVal->op) @@ -5910,7 +5942,7 @@ struct DeclLoweringVisitor : DeclVisitor default: entry->setRequirementVal(requirementVal); break; - } + } } irInterface->setOperand(entryIndex, entry); entryIndex++; @@ -5927,15 +5959,22 @@ struct DeclLoweringVisitor : DeclVisitor entryIndex++; } } - // Add lowered requirement entry to current decl mapping to prevent - // the function requirements from being lowered again when we get to - // `ensureAllDeclsRec`. - setValue(context, requirementDecl, LoweredValInfo::simple(entry)); + else + { + // Add lowered requirement entry to current decl mapping to prevent + // the function requirements from being lowered again when we get to + // `ensureAllDeclsRec`. + setValue(context, requirementDecl, LoweredValInfo::simple(entry)); + } } - addNameHint(context, irInterface, decl); addLinkageDecoration(context, irInterface, decl); + if (auto anyValueSizeAttr = decl->findModifier()) + { + subBuilder->addAnyValueSizeDecoration(irInterface, anyValueSizeAttr->size); + } + subBuilder->setInsertInto(irInterface); // TODO: are there any interface members that should be // nested inside the interface type itself? @@ -6004,7 +6043,7 @@ struct DeclLoweringVisitor : DeclVisitor if (as(decl)) { - return LoweredValInfo::simple(getBuilder()->getAssociatedType()); + SLANG_UNREACHABLE("associatedtype should have been handled by visitAssocTypeDecl."); } // Given a declaration of a type, we need to make sure @@ -6192,10 +6231,20 @@ struct DeclLoweringVisitor : DeclVisitor { // TODO: use a `WitnessTableKind` to represent the // classifier of the parameter. - auto param = subBuilder->emitParam(subBuilder->getWitnessTableType( - lowerType(context, constraintDecl->sup.type))); + auto supType = lowerType(context, constraintDecl->sup.type); + auto param = subBuilder->emitParam(subBuilder->getWitnessTableType(supType)); addNameHint(context, param, constraintDecl); setValue(subContext, constraintDecl, LoweredValInfo::simple(param)); + + // Attach the constraint interface type as a decoration to the IRParam value + // representing the generic parameter, to provide downstream passes knowledge + // of the correspondence. + if (auto declRefType = as(constraintDecl->sub.type)) + { + auto typeParamDeclVal = subContext->findLoweredDecl(declRefType->declRef.decl); + SLANG_ASSERT(typeParamDeclVal && typeParamDeclVal->val); + subBuilder->addTypeConstraintDecoration(typeParamDeclVal->val, supType); + } } } @@ -6856,6 +6905,10 @@ struct DeclLoweringVisitor : DeclVisitor { return ensureDecl(context, extensionDecl); } + else if (auto interfaceDecl = as(genDecl->inner)) + { + return ensureDecl(context, interfaceDecl); + } SLANG_RELEASE_ASSERT(false); UNREACHABLE_RETURN(LoweredValInfo()); } -- cgit v1.2.3