Skip to content

Commit 6c89a4a

Browse files
Merge pull request swiftlang#5516 from aschwaighofer/irgen_fix_exemplar_generic_superclass_constraint
IRGen: Decend into superclass constraint types when building exemplar archetypes
2 parents 131e35e + 4b279d1 commit 6c89a4a

File tree

2 files changed

+88
-89
lines changed

2 files changed

+88
-89
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -456,11 +456,6 @@ OwnedAddress irgen::projectPhysicalClassMemberAddress(IRGenFunction &IGF,
456456
case FieldAccess::ConstantDirect: {
457457
Address baseAddr(base, baseClassTI.getHeapAlignment(IGF.IGM, baseType));
458458
auto &element = baseClassTI.getElements(IGF.IGM, baseType)[fieldIndex];
459-
// We might run into a case where the type of baseAddr is an opaque pointer.
460-
if (baseAddr->getType() != baseClassTI.getStorageType()) {
461-
baseAddr = IGF.Builder.CreateBitCast(baseAddr,
462-
baseClassTI.getStorageType());
463-
}
464459
Address memberAddr = element.project(IGF, baseAddr, None);
465460
// We may need to bitcast the address if the field is of a generic type.
466461
if (memberAddr.getType()->getElementType() != fieldTI.getStorageType())

lib/IRGen/GenType.cpp

Lines changed: 88 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -945,107 +945,109 @@ static void profileArchetypeConstraints(
945945
Type ty,
946946
llvm::FoldingSetNodeID &ID,
947947
llvm::DenseMap<ArchetypeType*, unsigned> &seen) {
948-
// End recursion if we found a concrete associated type.
949-
auto arch = ty->getAs<ArchetypeType>();
950-
if (!arch) {
951-
auto concreteTy = ty->getCanonicalType();
952-
if (!concreteTy->hasArchetype()) {
953-
// Trivial case: if there are no archetypes, just use the canonical type
954-
// pointer.
955-
ID.AddBoolean(true);
956-
ID.AddPointer(concreteTy.getPointer());
957-
return;
958-
}
948+
// Helper.
949+
class ProfileType : public CanTypeVisitor<ProfileType> {
950+
llvm::FoldingSetNodeID &ID;
951+
llvm::DenseMap<ArchetypeType *, unsigned> &seen;
959952

960-
// When there are archetypes, recurse to profile the type itself.
961-
ID.AddInteger(1);
962-
ID.AddInteger(static_cast<unsigned>(concreteTy->getKind()));
963-
class ProfileType : public CanTypeVisitor<ProfileType> {
964-
llvm::FoldingSetNodeID &ID;
965-
llvm::DenseMap<ArchetypeType*, unsigned> &seen;
966-
967-
public:
968-
ProfileType(llvm::FoldingSetNodeID &ID,
969-
llvm::DenseMap<ArchetypeType*, unsigned> &seen)
970-
: ID(ID), seen(seen) { }
971-
972-
#define TYPE_WITHOUT_ARCHETYPE(KIND) \
973-
void visit##KIND##Type(Can##KIND##Type type) { \
974-
llvm_unreachable("does not contain an archetype"); \
975-
}
953+
public:
954+
ProfileType(llvm::FoldingSetNodeID &ID,
955+
llvm::DenseMap<ArchetypeType *, unsigned> &seen)
956+
: ID(ID), seen(seen) {}
976957

977-
TYPE_WITHOUT_ARCHETYPE(Builtin)
958+
#define TYPE_WITHOUT_ARCHETYPE(KIND) \
959+
void visit##KIND##Type(Can##KIND##Type type) { \
960+
llvm_unreachable("does not contain an archetype"); \
961+
}
978962

979-
void visitNominalType(CanNominalType type) {
980-
if (type.getParent())
981-
profileArchetypeConstraints(type.getParent(), ID, seen);
982-
ID.AddPointer(type->getDecl());
983-
}
963+
TYPE_WITHOUT_ARCHETYPE(Builtin)
984964

985-
void visitTupleType(CanTupleType type) {
986-
ID.AddInteger(type->getNumElements());
987-
for (auto &elt : type->getElements()) {
988-
ID.AddInteger(elt.isVararg());
989-
profileArchetypeConstraints(elt.getType(), ID, seen);
990-
}
991-
}
965+
void visitNominalType(CanNominalType type) {
966+
if (type.getParent())
967+
profileArchetypeConstraints(type.getParent(), ID, seen);
968+
ID.AddPointer(type->getDecl());
969+
}
992970

993-
void visitReferenceStorageType(CanReferenceStorageType type) {
994-
profileArchetypeConstraints(type.getReferentType(), ID, seen);
971+
void visitTupleType(CanTupleType type) {
972+
ID.AddInteger(type->getNumElements());
973+
for (auto &elt : type->getElements()) {
974+
ID.AddInteger(elt.isVararg());
975+
profileArchetypeConstraints(elt.getType(), ID, seen);
995976
}
977+
}
996978

997-
void visitAnyMetatypeType(CanAnyMetatypeType type) {
998-
profileArchetypeConstraints(type.getInstanceType(), ID, seen);
999-
}
979+
void visitReferenceStorageType(CanReferenceStorageType type) {
980+
profileArchetypeConstraints(type.getReferentType(), ID, seen);
981+
}
1000982

1001-
TYPE_WITHOUT_ARCHETYPE(Module)
983+
void visitAnyMetatypeType(CanAnyMetatypeType type) {
984+
profileArchetypeConstraints(type.getInstanceType(), ID, seen);
985+
}
1002986

1003-
void visitDynamicSelfType(CanDynamicSelfType type) {
1004-
profileArchetypeConstraints(type.getSelfType(), ID, seen);
1005-
}
987+
TYPE_WITHOUT_ARCHETYPE(Module)
1006988

1007-
void visitArchetypeType(CanArchetypeType type) {
1008-
profileArchetypeConstraints(type, ID, seen);
1009-
}
989+
void visitDynamicSelfType(CanDynamicSelfType type) {
990+
profileArchetypeConstraints(type.getSelfType(), ID, seen);
991+
}
1010992

1011-
TYPE_WITHOUT_ARCHETYPE(GenericTypeParam)
993+
void visitArchetypeType(CanArchetypeType type) {
994+
profileArchetypeConstraints(type, ID, seen);
995+
}
1012996

1013-
void visitDependentMemberType(CanDependentMemberType type) {
1014-
ID.AddPointer(type->getAssocType());
1015-
profileArchetypeConstraints(type.getBase(), ID, seen);
1016-
}
997+
TYPE_WITHOUT_ARCHETYPE(GenericTypeParam)
1017998

1018-
void visitAnyFunctionType(CanAnyFunctionType type) {
1019-
ID.AddInteger(type->getExtInfo().getFuncAttrKey());
1020-
profileArchetypeConstraints(type.getInput(), ID, seen);
1021-
profileArchetypeConstraints(type.getResult(), ID, seen);
1022-
}
999+
void visitDependentMemberType(CanDependentMemberType type) {
1000+
ID.AddPointer(type->getAssocType());
1001+
profileArchetypeConstraints(type.getBase(), ID, seen);
1002+
}
10231003

1024-
TYPE_WITHOUT_ARCHETYPE(SILFunction)
1025-
TYPE_WITHOUT_ARCHETYPE(SILBlockStorage)
1026-
TYPE_WITHOUT_ARCHETYPE(SILBox)
1027-
TYPE_WITHOUT_ARCHETYPE(ProtocolComposition)
1004+
void visitAnyFunctionType(CanAnyFunctionType type) {
1005+
ID.AddInteger(type->getExtInfo().getFuncAttrKey());
1006+
profileArchetypeConstraints(type.getInput(), ID, seen);
1007+
profileArchetypeConstraints(type.getResult(), ID, seen);
1008+
}
10281009

1029-
void visitLValueType(CanLValueType type) {
1030-
profileArchetypeConstraints(type.getObjectType(), ID, seen);
1031-
}
1010+
TYPE_WITHOUT_ARCHETYPE(SILFunction)
1011+
TYPE_WITHOUT_ARCHETYPE(SILBlockStorage)
1012+
TYPE_WITHOUT_ARCHETYPE(SILBox)
1013+
TYPE_WITHOUT_ARCHETYPE(ProtocolComposition)
10321014

1033-
void visitInOutType(CanInOutType type) {
1034-
profileArchetypeConstraints(type.getObjectType(), ID, seen);
1035-
}
1015+
void visitLValueType(CanLValueType type) {
1016+
profileArchetypeConstraints(type.getObjectType(), ID, seen);
1017+
}
1018+
1019+
void visitInOutType(CanInOutType type) {
1020+
profileArchetypeConstraints(type.getObjectType(), ID, seen);
1021+
}
10361022

1037-
TYPE_WITHOUT_ARCHETYPE(UnboundGeneric)
1023+
TYPE_WITHOUT_ARCHETYPE(UnboundGeneric)
10381024

1039-
void visitBoundGenericType(CanBoundGenericType type) {
1040-
if (type.getParent())
1041-
profileArchetypeConstraints(type.getParent(), ID, seen);
1042-
ID.AddPointer(type->getDecl());
1043-
for (auto arg : type.getGenericArgs()) {
1044-
profileArchetypeConstraints(arg, ID, seen);
1045-
}
1025+
void visitBoundGenericType(CanBoundGenericType type) {
1026+
if (type.getParent())
1027+
profileArchetypeConstraints(type.getParent(), ID, seen);
1028+
ID.AddPointer(type->getDecl());
1029+
for (auto arg : type.getGenericArgs()) {
1030+
profileArchetypeConstraints(arg, ID, seen);
10461031
}
1032+
}
10471033
#undef TYPE_WITHOUT_ARCHETYPE
1048-
};
1034+
};
1035+
1036+
// End recursion if we found a concrete associated type.
1037+
auto arch = ty->getAs<ArchetypeType>();
1038+
if (!arch) {
1039+
auto concreteTy = ty->getCanonicalType();
1040+
if (!concreteTy->hasArchetype()) {
1041+
// Trivial case: if there are no archetypes, just use the canonical type
1042+
// pointer.
1043+
ID.AddBoolean(true);
1044+
ID.AddPointer(concreteTy.getPointer());
1045+
return;
1046+
}
1047+
1048+
// When there are archetypes, recurse to profile the type itself.
1049+
ID.AddInteger(1);
1050+
ID.AddInteger(static_cast<unsigned>(concreteTy->getKind()));
10491051

10501052
ProfileType(ID, seen).visit(concreteTy);
10511053
return;
@@ -1063,9 +1065,11 @@ static void profileArchetypeConstraints(
10631065

10641066
// The archetype's superclass constraint.
10651067
auto superclass = arch->getSuperclass();
1066-
auto superclassPtr = superclass ? superclass->getCanonicalType().getPointer()
1067-
: nullptr;
1068-
ID.AddPointer(superclassPtr);
1068+
if (superclass) {
1069+
ProfileType(ID, seen).visit(superclass->getCanonicalType());
1070+
} else {
1071+
ID.AddPointer(nullptr);
1072+
}
10691073

10701074
// The archetype's protocol constraints.
10711075
for (auto proto : arch->getConformsTo()) {

0 commit comments

Comments
 (0)