Skip to content

Commit 8f17c43

Browse files
committed
Revert "IRGen: Remove special handling of fragile entities in LinkEntity"
This reverts commit 8e43990. See the discussion here for details: <6723560>
1 parent 3620aee commit 8f17c43

File tree

3 files changed

+65
-18
lines changed

3 files changed

+65
-18
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,11 +1189,34 @@ bool LinkEntity::isAvailableExternally(IRGenModule &IGM) const {
11891189
llvm_unreachable("bad link entity kind");
11901190
}
11911191

1192+
bool LinkEntity::isFragile(IRGenModule &IGM) const {
1193+
switch (getKind()) {
1194+
case Kind::SILFunction:
1195+
return getSILFunction()->isFragile();
1196+
1197+
case Kind::SILGlobalVariable:
1198+
return getSILGlobalVariable()->isFragile();
1199+
1200+
case Kind::DirectProtocolWitnessTable: {
1201+
if (auto wt = IGM.getSILModule().lookUpWitnessTable(
1202+
getProtocolConformance())) {
1203+
return wt->isFragile();
1204+
} else {
1205+
return false;
1206+
}
1207+
}
1208+
1209+
default:
1210+
break;
1211+
}
1212+
return false;
1213+
}
1214+
11921215

11931216
static std::pair<llvm::GlobalValue::LinkageTypes,
11941217
llvm::GlobalValue::VisibilityTypes>
11951218
getIRLinkage(IRGenModule &IGM,
1196-
SILLinkage linkage, ForDefinition_t isDefinition,
1219+
SILLinkage linkage, bool isFragile, ForDefinition_t isDefinition,
11971220
bool isWeakImported) {
11981221

11991222
#define RESULT(LINKAGE, VISIBILITY) \
@@ -1215,25 +1238,39 @@ llvm::GlobalValue::VISIBILITY##Visibility }
12151238
break;
12161239
}
12171240

1241+
if (isFragile) {
1242+
// Fragile functions/globals must be visible from outside, regardless of
1243+
// their accessibility. If a caller is also fragile and inlined into another
1244+
// module it must be able to access this (not-inlined) function/global.
1245+
switch (linkage) {
1246+
case SILLinkage::Hidden:
1247+
case SILLinkage::Private:
1248+
linkage = SILLinkage::Public;
1249+
break;
1250+
1251+
case SILLinkage::Public:
1252+
case SILLinkage::Shared:
1253+
case SILLinkage::HiddenExternal:
1254+
case SILLinkage::PrivateExternal:
1255+
case SILLinkage::PublicExternal:
1256+
case SILLinkage::SharedExternal:
1257+
break;
1258+
}
1259+
}
1260+
12181261
switch (linkage) {
12191262
case SILLinkage::Public:
12201263
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility};
1221-
12221264
case SILLinkage::Shared:
1223-
case SILLinkage::SharedExternal:
1224-
return RESULT(LinkOnceODR, Hidden);
1225-
1226-
case SILLinkage::Hidden:
1227-
return RESULT(External, Hidden);
1228-
1265+
case SILLinkage::SharedExternal: return RESULT(LinkOnceODR, Hidden);
1266+
case SILLinkage::Hidden: return RESULT(External, Hidden);
12291267
case SILLinkage::Private:
12301268
if (IGM.IRGen.hasMultipleIGMs()) {
12311269
// In case of multiple llvm modules (in multi-threaded compilation) all
12321270
// private decls must be visible from other files.
12331271
return RESULT(External, Hidden);
12341272
}
12351273
return RESULT(Internal, Default);
1236-
12371274
case SILLinkage::PublicExternal:
12381275
if (isDefinition) {
12391276
return RESULT(AvailableExternally, Default);
@@ -1242,12 +1279,15 @@ llvm::GlobalValue::VISIBILITY##Visibility }
12421279
if (isWeakImported)
12431280
return RESULT(ExternalWeak, Default);
12441281
return RESULT(External, Default);
1245-
12461282
case SILLinkage::HiddenExternal:
1247-
case SILLinkage::PrivateExternal:
1248-
if (isDefinition)
1249-
return RESULT(AvailableExternally, Hidden);
1250-
return RESULT(External, Hidden);
1283+
case SILLinkage::PrivateExternal: {
1284+
auto visibility = isFragile ? llvm::GlobalValue::DefaultVisibility
1285+
: llvm::GlobalValue::HiddenVisibility;
1286+
if (isDefinition) {
1287+
return {llvm::GlobalValue::AvailableExternallyLinkage, visibility};
1288+
}
1289+
return {llvm::GlobalValue::ExternalLinkage, visibility};
1290+
}
12511291
}
12521292
llvm_unreachable("bad SIL linkage");
12531293
}
@@ -1262,6 +1302,7 @@ static void updateLinkageForDefinition(IRGenModule &IGM,
12621302
auto linkage = getIRLinkage(
12631303
IGM,
12641304
entity.getLinkage(IGM, ForDefinition),
1305+
entity.isFragile(IGM),
12651306
ForDefinition,
12661307
entity.isWeakImported(IGM.getSwiftModule()));
12671308
global->setLinkage(linkage.first);
@@ -1287,6 +1328,7 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,
12871328

12881329
std::tie(result.Linkage, result.Visibility) =
12891330
getIRLinkage(IGM, entity.getLinkage(IGM, isDefinition),
1331+
entity.isFragile(IGM),
12901332
isDefinition,
12911333
entity.isWeakImported(IGM.getSwiftModule()));
12921334

lib/IRGen/Linking.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,11 @@ class LinkEntity {
506506
///
507507
bool isAvailableExternally(IRGenModule &IGM) const;
508508

509+
/// Returns true if this function or global variable may be inlined into
510+
/// another module.
511+
///
512+
bool isFragile(IRGenModule &IGM) const;
513+
509514
ValueDecl *getDecl() const {
510515
assert(isDeclKind(getKind()));
511516
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)