Skip to content

Commit dabe8f7

Browse files
authored
Merge pull request #21346 from slavapestov/fix-lazy-metadata-5.0
IRGen: Clean up and fix lazy metadata emission for reflection [5.0]
2 parents 8263f4e + 1df1653 commit dabe8f7

File tree

4 files changed

+34
-72
lines changed

4 files changed

+34
-72
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,30 +1099,8 @@ void IRGenerator::emitLazyDefinitions() {
10991099
while (!LazyTypeMetadata.empty() ||
11001100
!LazyTypeContextDescriptors.empty() ||
11011101
!LazyFunctionDefinitions.empty() ||
1102-
!LazyFieldTypes.empty() ||
11031102
!LazyWitnessTables.empty()) {
11041103

1105-
while (!LazyFieldTypes.empty()) {
1106-
auto info = LazyFieldTypes.pop_back_val();
1107-
auto &IGM = *info.IGM;
1108-
1109-
for (auto fieldType : info.fieldTypes) {
1110-
if (fieldType->hasArchetype())
1111-
continue;
1112-
1113-
// All of the required attributes are going to be preserved
1114-
// by field reflection metadata in the mangled name, so
1115-
// there is no need to worry about ownership semantics here.
1116-
if (auto refStorTy = dyn_cast<ReferenceStorageType>(fieldType))
1117-
fieldType = refStorTy.getReferentType();
1118-
1119-
// Make sure that all of the field type metadata is forced,
1120-
// otherwise there might be a problem when fields are accessed
1121-
// through reflection.
1122-
(void)irgen::getOrCreateTypeMetadataAccessFunction(IGM, fieldType);
1123-
}
1124-
}
1125-
11261104
// Emit any lazy type metadata we require.
11271105
while (!LazyTypeMetadata.empty()) {
11281106
NominalTypeDecl *type = LazyTypeMetadata.pop_back_val();

lib/IRGen/GenMeta.cpp

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,37 +1198,6 @@ namespace {
11981198
}
11991199
return numFields;
12001200
}
1201-
1202-
/// Track the field types of a struct or class for reflection metadata
1203-
/// emission.
1204-
static void
1205-
addFieldTypes(IRGenModule &IGM, NominalTypeDecl *type,
1206-
NominalTypeDecl::StoredPropertyRange storedProperties) {
1207-
SmallVector<CanType, 4> types;
1208-
for (VarDecl *prop : storedProperties) {
1209-
auto propertyType = type->mapTypeIntoContext(prop->getInterfaceType())
1210-
->getCanonicalType();
1211-
types.push_back(propertyType);
1212-
}
1213-
1214-
IGM.addFieldTypes(types);
1215-
}
1216-
1217-
/// Track the payload types of an enum for reflection metadata
1218-
/// emission.
1219-
static void addFieldTypes(IRGenModule &IGM,
1220-
ArrayRef<EnumImplStrategy::Element> enumElements) {
1221-
SmallVector<CanType, 4> types;
1222-
1223-
for (auto &elt : enumElements) {
1224-
auto caseType = elt.decl->getParentEnum()->mapTypeIntoContext(
1225-
elt.decl->getArgumentInterfaceType())
1226-
->getCanonicalType();
1227-
types.push_back(caseType);
1228-
}
1229-
1230-
IGM.addFieldTypes(types);
1231-
}
12321201

12331202
class StructContextDescriptorBuilder
12341203
: public TypeContextDescriptorBuilderBase<StructContextDescriptorBuilder,
@@ -1264,7 +1233,9 @@ namespace {
12641233
// uint32_t FieldOffsetVectorOffset;
12651234
B.addInt32(FieldVectorOffset / IGM.getPointerSize());
12661235

1267-
addFieldTypes(IGM, getType(), properties);
1236+
// For any nominal type metadata required for reflection.
1237+
for (auto *prop : properties)
1238+
IGM.IRGen.noteUseOfTypeMetadata(prop->getValueInterfaceType());
12681239
}
12691240

12701241
uint16_t getKindSpecificFlags() {
@@ -1336,7 +1307,9 @@ namespace {
13361307
// uint32_t NumEmptyCases;
13371308
B.addInt32(Strategy.getElementsWithNoPayload().size());
13381309

1339-
addFieldTypes(IGM, Strategy.getElementsWithPayload());
1310+
// For any nominal type metadata required for reflection.
1311+
for (auto elt : Strategy.getElementsWithPayload())
1312+
IGM.IRGen.noteUseOfTypeMetadata(elt.decl->getArgumentInterfaceType());
13401313
}
13411314

13421315
uint16_t getKindSpecificFlags() {
@@ -1646,7 +1619,9 @@ namespace {
16461619
// uint32_t FieldOffsetVectorOffset;
16471620
B.addInt32(getFieldVectorOffset() / IGM.getPointerSize());
16481621

1649-
addFieldTypes(IGM, getType(), properties);
1622+
// For any nominal type metadata required for reflection.
1623+
for (auto *prop : properties)
1624+
IGM.IRGen.noteUseOfTypeMetadata(prop->getValueInterfaceType());
16501625
}
16511626
};
16521627
} // end anonymous namespace
@@ -1772,10 +1747,6 @@ IRGenModule::getAddrOfAnonymousContextDescriptor(DeclContext *DC,
17721747
[&]{ AnonymousContextDescriptorBuilder(*this, DC).emit(); });
17731748
}
17741749

1775-
void IRGenModule::addFieldTypes(ArrayRef<CanType> fieldTypes) {
1776-
IRGen.addFieldTypes(fieldTypes, this);
1777-
}
1778-
17791750
static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
17801751
SILType T,
17811752
llvm::Value *metadata,

lib/IRGen/IRGenModule.h

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -241,14 +241,6 @@ class IRGenerator {
241241

242242
llvm::SetVector<SILFunction*> DynamicReplacements;
243243

244-
struct FieldTypeMetadata {
245-
IRGenModule *IGM;
246-
std::vector<CanType> fieldTypes;
247-
};
248-
249-
/// Field types we need to verify are present.
250-
llvm::SmallVector<FieldTypeMetadata, 4> LazyFieldTypes;
251-
252244
/// SIL functions that we need to emit lazily.
253245
llvm::SmallVector<SILFunction*, 4> LazyFunctionDefinitions;
254246

@@ -367,6 +359,13 @@ class IRGenerator {
367359
noteUseOfTypeGlobals(type, true, RequireMetadata);
368360
}
369361

362+
void noteUseOfTypeMetadata(Type type) {
363+
type.visit([&](Type t) {
364+
if (auto *nominal = t->getAnyNominal())
365+
noteUseOfTypeMetadata(nominal);
366+
});
367+
}
368+
370369
void noteUseOfTypeContextDescriptor(NominalTypeDecl *type,
371370
RequireMetadata_t requireMetadata) {
372371
noteUseOfTypeGlobals(type, false, requireMetadata);
@@ -386,9 +385,6 @@ class IRGenerator {
386385
/// Adds \p Conf to LazyWitnessTables if it has not been added yet.
387386
void addLazyWitnessTable(const ProtocolConformance *Conf);
388387

389-
void addFieldTypes(ArrayRef<CanType> fieldTypes, IRGenModule *IGM) {
390-
LazyFieldTypes.push_back({IGM, {fieldTypes.begin(), fieldTypes.end()}});
391-
}
392388

393389
void addClassForEagerInitialization(ClassDecl *ClassDecl);
394390

@@ -850,7 +846,6 @@ class IRGenModule {
850846
void addUsedGlobal(llvm::GlobalValue *global);
851847
void addCompilerUsedGlobal(llvm::GlobalValue *global);
852848
void addObjCClass(llvm::Constant *addr, bool nonlazy);
853-
void addFieldTypes(ArrayRef<CanType> fieldTypes);
854849
void addProtocolConformance(ConformanceDescription &&conformance);
855850

856851
llvm::Constant *emitSwiftProtocols();

test/IRGen/lazy_field_metadata.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-swift-frontend -emit-ir -wmo -O %s | %FileCheck %s
2+
3+
// Both should be emitted:
4+
5+
// CHECK: @"$s19lazy_field_metadata011GenericWithD5FieldVMn" = hidden constant
6+
// CHECK: @"$s19lazy_field_metadata24GenericWithConcreteFieldVMn" = hidden constant
7+
8+
struct GenericWithConcreteField<T> {
9+
let z = 123
10+
}
11+
12+
struct GenericWithGenericField<T> {
13+
var field = GenericWithConcreteField<T>()
14+
}
15+
16+
public func forceMetadata() -> Any.Type {
17+
return GenericWithGenericField<Int>.self
18+
}

0 commit comments

Comments
 (0)