Skip to content

Commit 93b7cbf

Browse files
authored
Merge pull request #6656 from DougGregor/remove-examplar-archetypes
2 parents c452cfa + 4062987 commit 93b7cbf

File tree

4 files changed

+31
-194
lines changed

4 files changed

+31
-194
lines changed

lib/IRGen/GenType.cpp

Lines changed: 30 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -943,181 +943,27 @@ const TypeInfo *TypeConverter::tryGetCompleteTypeInfo(CanType T) {
943943
return &ti;
944944
}
945945

946-
/// Profile the archetype constraints that may affect type layout into a
947-
/// folding set node ID.
948-
static void profileArchetypeConstraints(
949-
Type ty,
950-
llvm::FoldingSetNodeID &ID,
951-
llvm::DenseMap<ArchetypeType*, unsigned> &seen) {
952-
// Helper.
953-
class ProfileType : public CanTypeVisitor<ProfileType> {
954-
llvm::FoldingSetNodeID &ID;
955-
llvm::DenseMap<ArchetypeType *, unsigned> &seen;
956-
957-
public:
958-
ProfileType(llvm::FoldingSetNodeID &ID,
959-
llvm::DenseMap<ArchetypeType *, unsigned> &seen)
960-
: ID(ID), seen(seen) {}
961-
962-
#define TYPE_WITHOUT_ARCHETYPE(KIND) \
963-
void visit##KIND##Type(Can##KIND##Type type) { \
964-
llvm_unreachable("does not contain an archetype"); \
965-
}
966-
967-
TYPE_WITHOUT_ARCHETYPE(Builtin)
968-
969-
void visitNominalType(CanNominalType type) {
970-
if (type.getParent())
971-
profileArchetypeConstraints(type.getParent(), ID, seen);
972-
ID.AddPointer(type->getDecl());
973-
}
974-
975-
void visitTupleType(CanTupleType type) {
976-
ID.AddInteger(type->getNumElements());
977-
for (auto &elt : type->getElements()) {
978-
ID.AddInteger(elt.isVararg());
979-
profileArchetypeConstraints(elt.getType(), ID, seen);
980-
}
981-
}
982-
983-
void visitReferenceStorageType(CanReferenceStorageType type) {
984-
profileArchetypeConstraints(type.getReferentType(), ID, seen);
985-
}
986-
987-
void visitAnyMetatypeType(CanAnyMetatypeType type) {
988-
profileArchetypeConstraints(type.getInstanceType(), ID, seen);
989-
}
990-
991-
TYPE_WITHOUT_ARCHETYPE(Module)
992-
993-
void visitDynamicSelfType(CanDynamicSelfType type) {
994-
profileArchetypeConstraints(type.getSelfType(), ID, seen);
995-
}
996-
997-
void visitArchetypeType(CanArchetypeType type) {
998-
profileArchetypeConstraints(type, ID, seen);
999-
}
1000-
1001-
TYPE_WITHOUT_ARCHETYPE(GenericTypeParam)
1002-
1003-
void visitDependentMemberType(CanDependentMemberType type) {
1004-
ID.AddPointer(type->getAssocType());
1005-
profileArchetypeConstraints(type.getBase(), ID, seen);
1006-
}
1007-
1008-
void visitAnyFunctionType(CanAnyFunctionType type) {
1009-
ID.AddInteger(type->getExtInfo().getFuncAttrKey());
1010-
profileArchetypeConstraints(type.getInput(), ID, seen);
1011-
profileArchetypeConstraints(type.getResult(), ID, seen);
1012-
}
1013-
1014-
TYPE_WITHOUT_ARCHETYPE(SILFunction)
1015-
TYPE_WITHOUT_ARCHETYPE(SILBlockStorage)
1016-
TYPE_WITHOUT_ARCHETYPE(SILBox)
1017-
TYPE_WITHOUT_ARCHETYPE(ProtocolComposition)
1018-
1019-
void visitLValueType(CanLValueType type) {
1020-
profileArchetypeConstraints(type.getObjectType(), ID, seen);
1021-
}
1022-
1023-
void visitInOutType(CanInOutType type) {
1024-
profileArchetypeConstraints(type.getObjectType(), ID, seen);
1025-
}
1026-
1027-
TYPE_WITHOUT_ARCHETYPE(UnboundGeneric)
1028-
1029-
void visitBoundGenericType(CanBoundGenericType type) {
1030-
if (type.getParent())
1031-
profileArchetypeConstraints(type.getParent(), ID, seen);
1032-
ID.AddPointer(type->getDecl());
1033-
for (auto arg : type.getGenericArgs()) {
1034-
profileArchetypeConstraints(arg, ID, seen);
1035-
}
1036-
}
1037-
#undef TYPE_WITHOUT_ARCHETYPE
1038-
};
1039-
1040-
// End recursion if we found a concrete associated type.
1041-
auto arch = ty->getAs<ArchetypeType>();
1042-
if (!arch) {
1043-
auto concreteTy = ty->getCanonicalType();
1044-
if (!concreteTy->hasArchetype()) {
1045-
// Trivial case: if there are no archetypes, just use the canonical type
1046-
// pointer.
1047-
ID.AddBoolean(true);
1048-
ID.AddPointer(concreteTy.getPointer());
1049-
return;
1050-
}
1051-
1052-
// When there are archetypes, recurse to profile the type itself.
1053-
ID.AddInteger(1);
1054-
ID.AddInteger(static_cast<unsigned>(concreteTy->getKind()));
1055-
1056-
ProfileType(ID, seen).visit(concreteTy);
1057-
return;
1058-
}
1059-
1060-
auto found = seen.find(arch);
1061-
if (found != seen.end()) {
1062-
ID.AddInteger(found->second);
1063-
return;
1064-
}
1065-
seen.insert({arch, seen.size()});
1066-
1067-
// Is the archetype class-constrained?
1068-
ID.AddBoolean(arch->requiresClass());
1069-
1070-
// The archetype's superclass constraint.
1071-
auto superclass = arch->getSuperclass();
1072-
if (superclass) {
1073-
ProfileType(ID, seen).visit(superclass->getCanonicalType());
1074-
} else {
1075-
ID.AddPointer(nullptr);
1076-
}
1077-
1078-
// The archetype's protocol constraints.
1079-
for (auto proto : arch->getConformsTo()) {
1080-
ID.AddPointer(proto);
1081-
}
946+
ArchetypeType *TypeConverter::getExemplarArchetype(ArchetypeType *t) {
947+
// Retrieve the generic environment of the archetype.
948+
auto genericEnv = t->getGenericEnvironment();
1082949

1083-
// Skip nested types if this is an opened existential, since those
1084-
// won't resolve. Normally opened existentials cannot have nested
1085-
// types, but one case we missed compiled in Swift 3 so we support
1086-
// it here.
1087-
if (arch->getOpenedExistentialType()) {
1088-
return;
1089-
}
950+
// If there is no generic environment, the archetype is an exemplar.
951+
if (!genericEnv) return t;
1090952

1091-
// Recursively profile nested archetypes.
1092-
for (auto nested : arch->getAllNestedTypes()) {
1093-
profileArchetypeConstraints(nested.second, ID, seen);
1094-
}
1095-
}
953+
// Dig out the canonical generic environment.
954+
auto genericSig = genericEnv->getGenericSignature();
955+
auto canGenericSig = genericSig->getCanonicalSignature();
956+
auto module = IGM.getSwiftModule();
957+
auto canGenericEnv = canGenericSig.getGenericEnvironment(*module);
958+
if (canGenericEnv == genericEnv) return t;
1096959

1097-
void ExemplarArchetype::Profile(llvm::FoldingSetNodeID &ID) const {
1098-
llvm::DenseMap<ArchetypeType*, unsigned> seen;
1099-
profileArchetypeConstraints(Archetype, ID, seen);
1100-
}
1101-
1102-
ArchetypeType *TypeConverter::getExemplarArchetype(ArchetypeType *t) {
1103-
// Check the folding set to see whether we already have an exemplar matching
1104-
// this archetype.
1105-
llvm::FoldingSetNodeID ID;
1106-
llvm::DenseMap<ArchetypeType*, unsigned> seen;
1107-
profileArchetypeConstraints(t, ID, seen);
1108-
void *insertPos;
1109-
ExemplarArchetype *existing
1110-
= Types.ExemplarArchetypes.FindNodeOrInsertPos(ID, insertPos);
1111-
if (existing) {
1112-
return existing->Archetype;
1113-
}
1114-
1115-
// Otherwise, use this archetype as the exemplar for future similar
1116-
// archetypes.
1117-
Types.ExemplarArchetypeStorage.push_back(new ExemplarArchetype(t));
1118-
Types.ExemplarArchetypes.InsertNode(&Types.ExemplarArchetypeStorage.back(),
1119-
insertPos);
1120-
return t;
960+
// Map the archetype out of its own generic environment and into the
961+
// canonical generic environment.
962+
auto interfaceType = genericEnv->mapTypeOutOfContext(t);
963+
auto exemplar = canGenericEnv->mapTypeIntoContext(module, interfaceType)
964+
->castTo<ArchetypeType>();
965+
assert(isExemplarArchetype(exemplar));
966+
return exemplar;
1121967
}
1122968

1123969
/// Fold archetypes to unique exemplars. Any archetype with the same
@@ -1858,9 +1704,18 @@ CanType TypeConverter::getTypeThatLoweredTo(llvm::Type *t) const {
18581704
}
18591705

18601706
bool TypeConverter::isExemplarArchetype(ArchetypeType *arch) const {
1861-
for (auto &ea : Types.ExemplarArchetypeStorage)
1862-
if (ea.Archetype == arch) return true;
1863-
return false;
1707+
auto genericEnv = arch->getGenericEnvironment();
1708+
if (!genericEnv) return true;
1709+
1710+
// Dig out the canonical generic environment.
1711+
auto genericSig = genericEnv->getGenericSignature();
1712+
auto canGenericSig = genericSig->getCanonicalSignature();
1713+
auto module = IGM.getSwiftModule();
1714+
auto canGenericEnv = canGenericSig.getGenericEnvironment(*module);
1715+
1716+
// If this archetype is in the canonical generic environment, it's an
1717+
// exemplar archetype.
1718+
return canGenericEnv == genericEnv;
18641719
}
18651720
#endif
18661721

lib/IRGen/GenType.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,6 @@ namespace irgen {
6161
/// Either a type or a forward-declaration.
6262
typedef llvm::PointerUnion<const TypeInfo*, llvm::Type*> TypeCacheEntry;
6363

64-
/// A unique archetype arbitrarily chosen as an exemplar for all archetypes with
65-
/// the same constraints.
66-
class ExemplarArchetype : public llvm::FoldingSetNode,
67-
public llvm::ilist_node<ExemplarArchetype> {
68-
public:
69-
ArchetypeType * const Archetype;
70-
71-
ExemplarArchetype() : Archetype(nullptr) {}
72-
ExemplarArchetype(ArchetypeType *t) : Archetype(t) {}
73-
74-
void Profile(llvm::FoldingSetNodeID &ID) const;
75-
};
76-
7764
/// The helper class for generating types.
7865
class TypeConverter {
7966
public:
@@ -195,9 +182,6 @@ class TypeConverter {
195182
llvm::DenseMap<TypeBase*, TypeCacheEntry> DependentCache;
196183
llvm::DenseMap<TypeBase*, TypeCacheEntry> &getCacheFor(TypeBase *t);
197184

198-
llvm::ilist<ExemplarArchetype> ExemplarArchetypeStorage;
199-
llvm::FoldingSet<ExemplarArchetype> ExemplarArchetypes;
200-
201185
friend TypeCacheEntry TypeConverter::getTypeEntry(CanType T);
202186
friend TypeCacheEntry TypeConverter::convertAnyNominalType(CanType Type,
203187
NominalTypeDecl *D);

test/DebugInfo/generic_arg2.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// RUN: %target-swift-frontend -Xllvm -new-mangling-for-tests %s -emit-ir -g -o - | %FileCheck %s
22

33
// CHECK: define hidden void @_T012generic_arg25ClassC3foo{{.*}}, %swift.type* %U
4-
// CHECK: [[Y:%.*]] = getelementptr inbounds %C12generic_arg25Class, %C12generic_arg25Class* %2, i32 0, i32 0, i32 0
5-
// store %swift.opaque* %[[Y]], %swift.opaque** %[[Y_SHADOW:.*]], align
64
// CHECK: call void @llvm.dbg.declare(metadata %swift.opaque** %y.addr, metadata ![[U:.*]], metadata !{{[0-9]+}})
75
// Make sure there is no conflicting dbg.value for this variable.x
86
// CHECK-NOT: dbg.value{{.*}}metadata ![[U]]

test/IRGen/sil_witness_methods.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ entry(%z : $*Z, %x : $*Foo):
8585
return %m : $@thick Foo.Type
8686
}
8787

88-
// CHECK-LABEL: define{{( protected)?}} %swift.type* @generic_type_generic_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %C19sil_witness_methods3Bar** noalias nocapture dereferenceable({{.*}}), %swift.type* %Self, i8** %SelfWitnessTable)
88+
// CHECK-LABEL: define{{( protected)?}} %swift.type* @generic_type_generic_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %C19sil_witness_methods3Bar{{(.1)?}}** noalias nocapture dereferenceable(8), %swift.type* %Self, i8** %SelfWitnessTable)
8989
sil @generic_type_generic_method_witness : $@convention(witness_method) <T, U, V, Z> (@in Z, @in Bar<T, U, V>) -> @thick Bar<T, U, V>.Type {
9090
entry(%z : $*Z, %x : $*Bar<T, U, V>):
9191
%t = metatype $@thick T.Type

0 commit comments

Comments
 (0)