Skip to content

Commit 021b9c5

Browse files
committed
Revert "IRGen: Remove special handling of fragile entities in LinkEntity"
This reverts commit 62ad8a6.
1 parent 54a411d commit 021b9c5

File tree

3 files changed

+64
-18
lines changed

3 files changed

+64
-18
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,11 +1205,33 @@ bool LinkEntity::isAvailableExternally(IRGenModule &IGM) const {
12051205
llvm_unreachable("bad link entity kind");
12061206
}
12071207

1208+
bool LinkEntity::isFragile(IRGenModule &IGM) const {
1209+
switch (getKind()) {
1210+
case Kind::SILFunction:
1211+
return getSILFunction()->isFragile();
1212+
1213+
case Kind::SILGlobalVariable:
1214+
return getSILGlobalVariable()->isFragile();
1215+
1216+
case Kind::DirectProtocolWitnessTable: {
1217+
if (auto wt = IGM.SILMod->lookUpWitnessTable(getProtocolConformance())) {
1218+
return wt->isFragile();
1219+
} else {
1220+
return false;
1221+
}
1222+
}
1223+
1224+
default:
1225+
break;
1226+
}
1227+
return false;
1228+
}
1229+
12081230

12091231
static std::pair<llvm::GlobalValue::LinkageTypes,
12101232
llvm::GlobalValue::VisibilityTypes>
12111233
getIRLinkage(IRGenModule &IGM,
1212-
SILLinkage linkage, ForDefinition_t isDefinition,
1234+
SILLinkage linkage, bool isFragile, ForDefinition_t isDefinition,
12131235
bool isWeakImported) {
12141236

12151237
#define RESULT(LINKAGE, VISIBILITY) \
@@ -1231,25 +1253,39 @@ llvm::GlobalValue::VISIBILITY##Visibility }
12311253
break;
12321254
}
12331255

1256+
if (isFragile) {
1257+
// Fragile functions/globals must be visible from outside, regardless of
1258+
// their accessibility. If a caller is also fragile and inlined into another
1259+
// module it must be able to access this (not-inlined) function/global.
1260+
switch (linkage) {
1261+
case SILLinkage::Hidden:
1262+
case SILLinkage::Private:
1263+
linkage = SILLinkage::Public;
1264+
break;
1265+
1266+
case SILLinkage::Public:
1267+
case SILLinkage::Shared:
1268+
case SILLinkage::HiddenExternal:
1269+
case SILLinkage::PrivateExternal:
1270+
case SILLinkage::PublicExternal:
1271+
case SILLinkage::SharedExternal:
1272+
break;
1273+
}
1274+
}
1275+
12341276
switch (linkage) {
12351277
case SILLinkage::Public:
12361278
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility};
1237-
12381279
case SILLinkage::Shared:
1239-
case SILLinkage::SharedExternal:
1240-
return RESULT(LinkOnceODR, Hidden);
1241-
1242-
case SILLinkage::Hidden:
1243-
return RESULT(External, Hidden);
1244-
1280+
case SILLinkage::SharedExternal: return RESULT(LinkOnceODR, Hidden);
1281+
case SILLinkage::Hidden: return RESULT(External, Hidden);
12451282
case SILLinkage::Private:
12461283
if (IGM.dispatcher.hasMultipleIGMs()) {
12471284
// In case of multiple llvm modules (in multi-threaded compilation) all
12481285
// private decls must be visible from other files.
12491286
return RESULT(External, Hidden);
12501287
}
12511288
return RESULT(Internal, Default);
1252-
12531289
case SILLinkage::PublicExternal:
12541290
if (isDefinition) {
12551291
return RESULT(AvailableExternally, Default);
@@ -1258,12 +1294,15 @@ llvm::GlobalValue::VISIBILITY##Visibility }
12581294
if (isWeakImported)
12591295
return RESULT(ExternalWeak, Default);
12601296
return RESULT(External, Default);
1261-
12621297
case SILLinkage::HiddenExternal:
1263-
case SILLinkage::PrivateExternal:
1264-
if (isDefinition)
1265-
return RESULT(AvailableExternally, Hidden);
1266-
return RESULT(External, Hidden);
1298+
case SILLinkage::PrivateExternal: {
1299+
auto visibility = isFragile ? llvm::GlobalValue::DefaultVisibility
1300+
: llvm::GlobalValue::HiddenVisibility;
1301+
if (isDefinition) {
1302+
return {llvm::GlobalValue::AvailableExternallyLinkage, visibility};
1303+
}
1304+
return {llvm::GlobalValue::ExternalLinkage, visibility};
1305+
}
12671306
}
12681307
llvm_unreachable("bad SIL linkage");
12691308
}
@@ -1278,6 +1317,7 @@ static void updateLinkageForDefinition(IRGenModule &IGM,
12781317
auto linkage = getIRLinkage(
12791318
IGM,
12801319
entity.getLinkage(IGM, ForDefinition),
1320+
entity.isFragile(IGM),
12811321
ForDefinition,
12821322
entity.isWeakImported(IGM.SILMod->getSwiftModule()));
12831323
global->setLinkage(linkage.first);
@@ -1303,6 +1343,7 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,
13031343

13041344
std::tie(result.Linkage, result.Visibility) =
13051345
getIRLinkage(IGM, entity.getLinkage(IGM, isDefinition),
1346+
entity.isFragile(IGM),
13061347
isDefinition,
13071348
entity.isWeakImported(IGM.SILMod->getSwiftModule()));
13081349

lib/IRGen/Linking.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,11 @@ class LinkEntity {
496496
///
497497
bool isAvailableExternally(IRGenModule &IGM) const;
498498

499+
/// Returns true if this function or global variable may be inlined into
500+
/// another module.
501+
///
502+
bool isFragile(IRGenModule &IGM) const;
503+
499504
ValueDecl *getDecl() const {
500505
assert(isDeclKind(getKind()));
501506
return reinterpret_cast<ValueDecl*>(Pointer);

test/IRGen/sil_linkage.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
sil_stage canonical
44

55
// CHECK: define{{( protected)?}} void @public_fragile_function_test() {{.*}} {
6-
// CHECK: define hidden void @hidden_fragile_function_test() {{.*}} {
6+
// CHECK: define{{( protected)?}} void @hidden_fragile_function_test() {{.*}} {
77
// CHECK: define linkonce_odr hidden void @shared_fragile_function_test() {{.*}} {
8-
// CHECK: define internal void @private_fragile_function_test() {{.*}} {
8+
// CHECK: define{{( protected)?}} void @private_fragile_function_test() {{.*}} {
99
// CHECK: define linkonce_odr hidden void @public_external_fragile_function_def_test() {{.*}} {
10-
// CHECK: define available_externally hidden void @hidden_external_fragile_function_def_test() {{.*}} {
10+
// CHECK: define{{( protected)?}} available_externally void @hidden_external_fragile_function_def_test() {{.*}} {
1111
// CHECK: define linkonce_odr hidden void @shared_external_fragile_function_def_test() {{.*}} {
12-
// CHECK: define available_externally hidden void @private_external_fragile_function_def_test() {{.*}} {
12+
// CHECK: define{{( protected)?}} available_externally void @private_external_fragile_function_def_test() {{.*}} {
1313
// CHECK: define{{( protected)?}} void @public_resilient_function_test() {{.*}} {
1414
// CHECK: define hidden void @hidden_resilient_function_test() {{.*}} {
1515
// CHECK: define linkonce_odr hidden void @shared_resilient_function_test() {{.*}} {

0 commit comments

Comments
 (0)