Skip to content

Commit 27a6f77

Browse files
authored
Merge pull request #21850 from slavapestov/default-witness-thunks-multithreaded
IRGen: Ensure that default witness thunks are emitted in the same thread as the protocol descriptor
2 parents 3b6c6cc + 5046568 commit 27a6f77

File tree

7 files changed

+48
-19
lines changed

7 files changed

+48
-19
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ static bool hasCodeCoverageInstrumentation(SILFunction &f, SILModule &m) {
984984
return f.getProfiler() && m.getOptions().EmitProfileCoverageMapping;
985985
}
986986

987-
void IRGenerator::emitGlobalTopLevel(bool emitForParallelEmission) {
987+
void IRGenerator::emitGlobalTopLevel() {
988988
// Generate order numbers for the functions in the SIL module that
989989
// correspond to definitions in the LLVM module.
990990
unsigned nextOrderNumber = 0;
@@ -994,13 +994,6 @@ void IRGenerator::emitGlobalTopLevel(bool emitForParallelEmission) {
994994
FunctionOrder.insert(std::make_pair(&silFn, nextOrderNumber++));
995995
}
996996

997-
// Ensure that relative symbols are collocated in the same LLVM module.
998-
for (SILWitnessTable &wt : PrimaryIGM->getSILModule().getWitnessTableList()) {
999-
CurrentIGMPtr IGM = getGenModule(wt.getDeclContext());
1000-
if (emitForParallelEmission)
1001-
IGM->ensureRelativeSymbolCollocation(wt);
1002-
}
1003-
1004997
for (SILGlobalVariable &v : PrimaryIGM->getSILModule().getSILGlobals()) {
1005998
Decl *decl = v.getDecl();
1006999
CurrentIGMPtr IGM = getGenModule(decl ? decl->getDeclContext() : nullptr);

lib/IRGen/GenMeta.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4046,6 +4046,9 @@ void IRGenModule::emitProtocolDecl(ProtocolDecl *protocol) {
40464046
if (isResilient(protocol, ResilienceExpansion::Minimal))
40474047
defaultWitnesses = getSILModule().lookUpDefaultWitnessTable(protocol);
40484048

4049+
if (defaultWitnesses)
4050+
IRGen.ensureRelativeSymbolCollocation(*defaultWitnesses);
4051+
40494052
{
40504053
ProtocolDescriptorBuilder builder(*this, protocol, defaultWitnesses);
40514054
builder.emit();

lib/IRGen/GenProto.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,10 @@
3838
#include "swift/ClangImporter/ClangModule.h"
3939
#include "swift/IRGen/Linking.h"
4040
#include "swift/SIL/SILDeclRef.h"
41+
#include "swift/SIL/SILDefaultWitnessTable.h"
4142
#include "swift/SIL/SILModule.h"
4243
#include "swift/SIL/SILValue.h"
44+
#include "swift/SIL/SILWitnessTable.h"
4345
#include "swift/SIL/SILWitnessVisitor.h"
4446
#include "swift/SIL/TypeLowering.h"
4547
#include "llvm/ADT/SmallString.h"
@@ -2079,7 +2081,10 @@ void IRGenModule::emitProtocolConformance(
20792081
setTrueConstGlobal(var);
20802082
}
20812083

2082-
void IRGenModule::ensureRelativeSymbolCollocation(SILWitnessTable &wt) {
2084+
void IRGenerator::ensureRelativeSymbolCollocation(SILWitnessTable &wt) {
2085+
if (!CurrentIGM)
2086+
return;
2087+
20832088
// Only resilient conformances use relative pointers for witness methods.
20842089
if (wt.isDeclaration() || isAvailableExternally(wt.getLinkage()) ||
20852090
!isResilientConformance(wt.getConformance()))
@@ -2090,7 +2095,20 @@ void IRGenModule::ensureRelativeSymbolCollocation(SILWitnessTable &wt) {
20902095
continue;
20912096
auto *witness = entry.getMethodWitness().Witness;
20922097
if (witness)
2093-
IRGen.forceLocalEmitOfLazyFunction(witness);
2098+
forceLocalEmitOfLazyFunction(witness);
2099+
}
2100+
}
2101+
2102+
void IRGenerator::ensureRelativeSymbolCollocation(SILDefaultWitnessTable &wt) {
2103+
if (!CurrentIGM)
2104+
return;
2105+
2106+
for (auto &entry : wt.getEntries()) {
2107+
if (entry.getKind() != SILWitnessTable::Method)
2108+
continue;
2109+
auto *witness = entry.getMethodWitness().Witness;
2110+
if (witness)
2111+
forceLocalEmitOfLazyFunction(witness);
20942112
}
20952113
}
20962114

@@ -2234,6 +2252,10 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
22342252
if (isAvailableExternally(wt->getLinkage()))
22352253
return;
22362254

2255+
// Ensure that relatively-referenced symbols for witness thunks are collocated
2256+
// in the same LLVM module.
2257+
IRGen.ensureRelativeSymbolCollocation(*wt);
2258+
22372259
auto conf = wt->getConformance();
22382260
PrettyStackTraceConformance _st(Context, "emitting witness table for", conf);
22392261

lib/IRGen/IRGen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,11 +964,11 @@ static void performParallelIRGeneration(
964964
}
965965

966966
// Emit the module contents.
967-
irgen.emitGlobalTopLevel(true /*emitForParallelEmission*/);
967+
irgen.emitGlobalTopLevel();
968968

969969
for (auto *File : M->getFiles()) {
970970
if (auto *SF = dyn_cast<SourceFile>(File)) {
971-
IRGenModule *IGM = irgen.getGenModule(SF);
971+
CurrentIGMPtr IGM = irgen.getGenModule(SF);
972972
IGM->emitSourceFile(*SF);
973973
} else {
974974
File->collectLinkLibraries([&](LinkLibrary LinkLib) {

lib/IRGen/IRGenModule.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ namespace swift {
9393
class ProtocolCompositionType;
9494
class RootProtocolConformance;
9595
struct SILDeclRef;
96+
class SILDefaultWitnessTable;
9697
class SILGlobalVariable;
9798
class SILModule;
9899
class SILProperty;
@@ -311,11 +312,7 @@ class IRGenerator {
311312

312313
/// Emit functions, variables and tables which are needed anyway, e.g. because
313314
/// they are externally visible.
314-
/// If \p emitForParallelEmission is true ensures that symbols that are
315-
/// expressed as relative pointers are collocated in the same output module
316-
/// with their base symbol. For example, witness methods need to be collocated
317-
/// with the witness table in the same LLVM module.
318-
void emitGlobalTopLevel(bool emitForParallelEmission = false);
315+
void emitGlobalTopLevel();
319316

320317
/// Emit references to each of the protocol descriptors defined in this
321318
/// IR module.
@@ -355,6 +352,10 @@ class IRGenerator {
355352
DefaultIGMForFunction[f] = CurrentIGM;
356353
}
357354

355+
void ensureRelativeSymbolCollocation(SILWitnessTable &wt);
356+
357+
void ensureRelativeSymbolCollocation(SILDefaultWitnessTable &wt);
358+
358359
void noteUseOfTypeMetadata(NominalTypeDecl *type) {
359360
noteUseOfTypeGlobals(type, true, RequireMetadata);
360361
}
@@ -1386,8 +1387,6 @@ private: \
13861387

13871388
void emitSharedContextDescriptor(DeclContext *dc);
13881389

1389-
void ensureRelativeSymbolCollocation(SILWitnessTable &wt);
1390-
13911390
llvm::GlobalVariable *
13921391
getGlobalForDynamicallyReplaceableThunk(LinkEntity &entity, llvm::Type *type,
13931392
ForDefinition_t forDefinition);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
extension Defaultable {
2+
public func defaulted() {}
3+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience
3+
// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience -enable-testing
4+
// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience -enable-resilience
5+
// RUN: %target-swift-frontend -c %S/Inputs/multithread_resilience_other.swift %s -num-threads 2 -o %t/1.o -o %t/2.o -module-name multithread_resilience -enable-testing -enable-resilience
6+
7+
public protocol Defaultable {
8+
func defaulted()
9+
}

0 commit comments

Comments
 (0)