Skip to content

Commit 401a602

Browse files
committed
IRGen: support emitting specialized witness tables
1 parent 1d8f4b0 commit 401a602

File tree

3 files changed

+49
-15
lines changed

3 files changed

+49
-15
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1335,7 +1335,6 @@ void IRGenerator::emitLazyDefinitions() {
13351335
for (SILFunction *f : LazyFunctionDefinitions) {
13361336
ASSERT(hasValidSignatureForEmbedded(f));
13371337
}
1338-
assert(LazyWitnessTables.empty());
13391338
assert(LazyCanonicalSpecializedMetadataAccessors.empty());
13401339
assert(LazyMetadataAccessors.empty());
13411340
// LazyClassMetadata is allowed

lib/IRGen/GenProto.cpp

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,26 @@ class DirectConformanceInfo : public ConformanceInfo {
13631363
}
13641364
};
13651365

1366+
/// Conformance info for a witness table that can be directly generated.
1367+
class SpecializedConformanceInfo : public ConformanceInfo {
1368+
friend ProtocolInfo;
1369+
1370+
const SpecializedProtocolConformance *Conformance;
1371+
public:
1372+
SpecializedConformanceInfo(const SpecializedProtocolConformance *C)
1373+
: Conformance(C) {}
1374+
1375+
llvm::Value *getTable(IRGenFunction &IGF,
1376+
llvm::Value **conformingMetadataCache) const override {
1377+
return IGF.IGM.getAddrOfWitnessTable(Conformance);
1378+
}
1379+
1380+
llvm::Constant *tryGetConstantTable(IRGenModule &IGM,
1381+
CanType conformingType) const override {
1382+
return IGM.getAddrOfWitnessTable(Conformance);
1383+
}
1384+
};
1385+
13661386
/// Conformance info for a witness table that is (or may be) dependent.
13671387
class AccessorConformanceInfo : public ConformanceInfo {
13681388
friend ProtocolInfo;
@@ -2454,10 +2474,19 @@ IRGenModule::getConformanceInfo(const ProtocolDecl *protocol,
24542474
if (auto found = checkCache(conformance))
24552475
return *found;
24562476

2477+
const ConformanceInfo *info;
2478+
2479+
if (Context.LangOpts.hasFeature(Feature::Embedded)) {
2480+
if (auto *sc = dyn_cast<SpecializedProtocolConformance>(conformance)) {
2481+
info = new SpecializedConformanceInfo(sc);
2482+
Conformances.try_emplace(conformance, info);
2483+
return *info;
2484+
}
2485+
}
2486+
24572487
// Drill down to the root normal
24582488
auto rootConformance = conformance->getRootConformance();
24592489

2460-
const ConformanceInfo *info;
24612490
// If the conformance is dependent in any way, we need to unique it.
24622491
// Under a relative protocol witness table implementation conformances are
24632492
// always direct.
@@ -2657,22 +2686,24 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
26572686
wtableBuilder.collectResilientWitnesses(resilientWitnesses);
26582687
}
26592688

2660-
// Collect the information that will go into the protocol conformance
2661-
// descriptor.
2662-
unsigned tablePrivateSize = wt->getConditionalConformances().size();
2663-
ConformanceDescription description(rootConf, wt, global, tableSize,
2664-
tablePrivateSize, isDependent);
2689+
if (!Context.LangOpts.hasFeature(Feature::Embedded)) {
2690+
// Collect the information that will go into the protocol conformance
2691+
// descriptor.
2692+
unsigned tablePrivateSize = wt->getConditionalConformances().size();
2693+
ConformanceDescription description(rootConf, wt, global, tableSize,
2694+
tablePrivateSize, isDependent);
26652695

2666-
// Build the instantiation function, we if need one.
2667-
description.instantiationFn = instantiationFunction;
2668-
description.resilientWitnesses = std::move(resilientWitnesses);
2696+
// Build the instantiation function, we if need one.
2697+
description.instantiationFn = instantiationFunction;
2698+
description.resilientWitnesses = std::move(resilientWitnesses);
26692699

2670-
// Record this conformance descriptor.
2671-
addProtocolConformance(std::move(description));
2700+
// Record this conformance descriptor.
2701+
addProtocolConformance(std::move(description));
26722702

2673-
IRGen.noteUseOfTypeContextDescriptor(
2674-
conf->getDeclContext()->getSelfNominalTypeDecl(),
2675-
RequireMetadata);
2703+
IRGen.noteUseOfTypeContextDescriptor(
2704+
conf->getDeclContext()->getSelfNominalTypeDecl(),
2705+
RequireMetadata);
2706+
}
26762707
}
26772708

26782709
/// True if a function's signature in LLVM carries polymorphic parameters.

lib/IRGen/IRGenModule.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,6 +1381,10 @@ bool IRGenerator::canEmitWitnessTableLazily(SILWitnessTable *wt) {
13811381
if (Opts.UseJIT)
13821382
return false;
13831383

1384+
// witness tables are always emitted lazily in embedded swift.
1385+
if (SIL.getASTContext().LangOpts.hasFeature(Feature::Embedded))
1386+
return true;
1387+
13841388
// Regardless of the access level, if the witness table is shared it means
13851389
// we can safely not emit it. Every other module which needs it will generate
13861390
// its own shared copy of it.

0 commit comments

Comments
 (0)