diff options
| author | Yong He <yonghe@outlook.com> | 2020-07-31 18:30:10 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-31 18:30:10 -0700 |
| commit | 9ac5c51ae1f0664a9dcb31392894e4f76bdbcf98 (patch) | |
| tree | 17fb1e6989a19f93cd84f9ef45cc1744bf19450a /source/slang/slang-lower-to-ir.cpp | |
| parent | bb42514acc03a476a93ae82fa0cc9d02dce86239 (diff) | |
Add [anyValueSize] attribute to interfaces and propagate that in the IR. (#1469)
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-lower-to-ir.cpp')
| -rw-r--r-- | source/slang/slang-lower-to-ir.cpp | 101 |
1 files changed, 77 insertions, 24 deletions
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<IRType*>& supTypes, Decl* genericParamDecl) +{ + auto parent = genericParamDecl->parentDecl; + if (parent) + { + for (auto typeConstraint : parent->getMembersOfType<GenericTypeConstraintDecl>()) + { + if (auto declRefType = as<DeclRefType>(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 : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower return emitDeclRef(context, type->interfaceDeclRef, 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<Derived, LoweredValInfo> 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<DeclLoweringVisitor, LoweredValInfo> return Slang::getInterfaceRequirementKey(context, requirementDecl); } + LoweredValInfo visitAssocTypeDecl(AssocTypeDecl* decl) + { + SLANG_ASSERT(decl->parentDecl != nullptr); + ShortList<IRInterfaceType*> constraintInterfaces; + for (auto inheritanceDecl : decl->getMembersOfType<InheritanceDecl>()) + { + 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<DeclLoweringVisitor, LoweredValInfo> // 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<AssocTypeDecl>(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<DeclLoweringVisitor, LoweredValInfo> // 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<AssocTypeDecl>()) + { + ensureDecl(subContext, assocTypeDecl); + } + UInt entryIndex = 0; for (auto requirementDecl : decl->members) @@ -5891,7 +5923,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> 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<DeclLoweringVisitor, LoweredValInfo> default: entry->setRequirementVal(requirementVal); break; - } + } } irInterface->setOperand(entryIndex, entry); entryIndex++; @@ -5927,15 +5959,22 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo> 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<AnyValueSizeAttribute>()) + { + 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<DeclLoweringVisitor, LoweredValInfo> if (as<AssocTypeDecl>(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<DeclLoweringVisitor, LoweredValInfo> { // 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<DeclRefType>(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<DeclLoweringVisitor, LoweredValInfo> { return ensureDecl(context, extensionDecl); } + else if (auto interfaceDecl = as<InterfaceDecl>(genDecl->inner)) + { + return ensureDecl(context, interfaceDecl); + } SLANG_RELEASE_ASSERT(false); UNREACHABLE_RETURN(LoweredValInfo()); } |
