Skip to content

Revert public fragile hack #2857

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 56 additions & 14 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,11 +1189,34 @@ bool LinkEntity::isAvailableExternally(IRGenModule &IGM) const {
llvm_unreachable("bad link entity kind");
}

bool LinkEntity::isFragile(IRGenModule &IGM) const {
switch (getKind()) {
case Kind::SILFunction:
return getSILFunction()->isFragile();

case Kind::SILGlobalVariable:
return getSILGlobalVariable()->isFragile();

case Kind::DirectProtocolWitnessTable: {
if (auto wt = IGM.getSILModule().lookUpWitnessTable(
getProtocolConformance())) {
return wt->isFragile();
} else {
return false;
}
}

default:
break;
}
return false;
}


static std::pair<llvm::GlobalValue::LinkageTypes,
llvm::GlobalValue::VisibilityTypes>
getIRLinkage(IRGenModule &IGM,
SILLinkage linkage, ForDefinition_t isDefinition,
SILLinkage linkage, bool isFragile, ForDefinition_t isDefinition,
bool isWeakImported) {

#define RESULT(LINKAGE, VISIBILITY) \
Expand All @@ -1215,25 +1238,39 @@ llvm::GlobalValue::VISIBILITY##Visibility }
break;
}

if (isFragile) {
// Fragile functions/globals must be visible from outside, regardless of
// their accessibility. If a caller is also fragile and inlined into another
// module it must be able to access this (not-inlined) function/global.
switch (linkage) {
case SILLinkage::Hidden:
case SILLinkage::Private:
linkage = SILLinkage::Public;
break;

case SILLinkage::Public:
case SILLinkage::Shared:
case SILLinkage::HiddenExternal:
case SILLinkage::PrivateExternal:
case SILLinkage::PublicExternal:
case SILLinkage::SharedExternal:
break;
}
}

switch (linkage) {
case SILLinkage::Public:
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility};

case SILLinkage::Shared:
case SILLinkage::SharedExternal:
return RESULT(LinkOnceODR, Hidden);

case SILLinkage::Hidden:
return RESULT(External, Hidden);

case SILLinkage::SharedExternal: return RESULT(LinkOnceODR, Hidden);
case SILLinkage::Hidden: return RESULT(External, Hidden);
case SILLinkage::Private:
if (IGM.IRGen.hasMultipleIGMs()) {
// In case of multiple llvm modules (in multi-threaded compilation) all
// private decls must be visible from other files.
return RESULT(External, Hidden);
}
return RESULT(Internal, Default);

case SILLinkage::PublicExternal:
if (isDefinition) {
return RESULT(AvailableExternally, Default);
Expand All @@ -1242,12 +1279,15 @@ llvm::GlobalValue::VISIBILITY##Visibility }
if (isWeakImported)
return RESULT(ExternalWeak, Default);
return RESULT(External, Default);

case SILLinkage::HiddenExternal:
case SILLinkage::PrivateExternal:
if (isDefinition)
return RESULT(AvailableExternally, Hidden);
return RESULT(External, Hidden);
case SILLinkage::PrivateExternal: {
auto visibility = isFragile ? llvm::GlobalValue::DefaultVisibility
: llvm::GlobalValue::HiddenVisibility;
if (isDefinition) {
return {llvm::GlobalValue::AvailableExternallyLinkage, visibility};
}
return {llvm::GlobalValue::ExternalLinkage, visibility};
}
}
llvm_unreachable("bad SIL linkage");
}
Expand All @@ -1262,6 +1302,7 @@ static void updateLinkageForDefinition(IRGenModule &IGM,
auto linkage = getIRLinkage(
IGM,
entity.getLinkage(IGM, ForDefinition),
entity.isFragile(IGM),
ForDefinition,
entity.isWeakImported(IGM.getSwiftModule()));
global->setLinkage(linkage.first);
Expand All @@ -1287,6 +1328,7 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,

std::tie(result.Linkage, result.Visibility) =
getIRLinkage(IGM, entity.getLinkage(IGM, isDefinition),
entity.isFragile(IGM),
isDefinition,
entity.isWeakImported(IGM.getSwiftModule()));

Expand Down
5 changes: 5 additions & 0 deletions lib/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,11 @@ class LinkEntity {
///
bool isAvailableExternally(IRGenModule &IGM) const;

/// Returns true if this function or global variable may be inlined into
/// another module.
///
bool isFragile(IRGenModule &IGM) const;

ValueDecl *getDecl() const {
assert(isDeclKind(getKind()));
return reinterpret_cast<ValueDecl*>(Pointer);
Expand Down
11 changes: 2 additions & 9 deletions lib/SIL/SILDeclRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,15 +332,8 @@ SILLinkage SILDeclRef::getLinkage(ForDefinition_t forDefinition) const {
if (isa<ClangModuleUnit>(derivedFor->getModuleScopeContext()))
return ClangLinkage;
}

// If the module is being built with -sil-serialize-all, everything has
// to have public linkage.
if (moduleContext->getParentModule()->getResilienceStrategy()
== ResilienceStrategy::Fragile) {
return (forDefinition ? SILLinkage::Public : SILLinkage::PublicExternal);
}

// Otherwise, linkage is determined by accessibility at the AST level.

// Otherwise, we have external linkage.
switch (d->getEffectiveAccess()) {
case Accessibility::Private:
return (forDefinition ? SILLinkage::Private : SILLinkage::PrivateExternal);
Expand Down
4 changes: 1 addition & 3 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -875,9 +875,7 @@ SILFunction *SILGenModule::emitLazyGlobalInitializer(StringRef funcName,
auto initSILType = getLoweredType(initType).castTo<SILFunctionType>();

auto *f =
M.createFunction(makeModuleFragile
? SILLinkage::Public
: SILLinkage::Private,
M.createFunction(SILLinkage::Private,
funcName, initSILType, nullptr,
SILLocation(binding), IsNotBare, IsNotTransparent,
makeModuleFragile
Expand Down
5 changes: 1 addition & 4 deletions lib/SILGen/SILGenGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,7 @@ void SILGenModule::emitGlobalInitialization(PatternBindingDecl *pd,

// TODO: include the module in the onceToken's name mangling.
// Then we can make it fragile.
auto onceToken = SILGlobalVariable::create(M,
makeModuleFragile
? SILLinkage::Public
: SILLinkage::Private,
auto onceToken = SILGlobalVariable::create(M, SILLinkage::Private,
makeModuleFragile,
onceTokenBuffer, onceSILTy);
onceToken->setDeclaration(false);
Expand Down
9 changes: 4 additions & 5 deletions lib/SILGen/SILGenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ SILGenModule::emitVTableMethod(SILDeclRef derived, SILDeclRef base) {
auto *derivedDecl = cast<AbstractFunctionDecl>(derived.getDecl());
SILLocation loc(derivedDecl);
auto thunk =
M.createFunction(makeModuleFragile
? SILLinkage::Public
: SILLinkage::Private,
M.createFunction(SILLinkage::Private,
name, overrideInfo.SILFnType,
derivedDecl->getGenericParams(), loc, IsBare,
IsNotTransparent, IsNotFragile);
Expand Down Expand Up @@ -243,8 +241,9 @@ class SILGenVTable : public Lowering::ASTVisitor<SILGenVTable> {
}

void visitConstructorDecl(ConstructorDecl *cd) {
// Stub constructors don't get an entry.
if (cd->hasStubImplementation())
// Stub constructors don't get an entry, unless they were synthesized to
// override a non-required designated initializer in the superclass.
if (cd->hasStubImplementation() && !cd->getOverriddenDecl())
return;

// Required constructors (or overrides thereof) have their allocating entry
Expand Down
2 changes: 1 addition & 1 deletion lib/Sema/CodeSynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2155,7 +2155,7 @@ swift::createDesignatedInitOverride(TypeChecker &tc,

// Wire up the overrides.
ctor->getAttrs().add(new (tc.Context) OverrideAttr(/*Implicit=*/true));
checkOverrides(tc, ctor);
ctor->setOverriddenDecl(superclassCtor);

if (kind == DesignatedInitKind::Stub) {
// Make this a stub implementation.
Expand Down
24 changes: 19 additions & 5 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7547,7 +7547,10 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
}

auto superclassTy = classDecl->getSuperclass();
for (auto memberResult : lookupConstructors(classDecl, superclassTy)) {
auto ctors = lookupConstructors(classDecl, superclassTy,
NameLookupFlags::IgnoreAccessibility);

for (auto memberResult : ctors) {
auto member = memberResult.Decl;

// Skip unavailable superclass initializers.
Expand Down Expand Up @@ -7595,12 +7598,23 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
getInitializerParamType(superclassCtor)).second)
continue;

// If we're inheriting initializers, create an override delegating
// to 'super.init'. Otherwise, create a stub which traps at runtime.
auto kind = canInheritInitializers
? DesignatedInitKind::Chaining
: DesignatedInitKind::Stub;

// If the superclass initializer is not accessible from the derived
// class, we cannot chain to 'super.init' either -- create a stub.
if (!superclassCtor->isAccessibleFrom(classDecl)) {
assert(!superclassCtor->isRequired() &&
"required initializer less visible than the class?");
kind = DesignatedInitKind::Stub;
}

// We have a designated initializer. Create an override of it.
if (auto ctor = createDesignatedInitOverride(
*this, classDecl, superclassCtor,
canInheritInitializers
? DesignatedInitKind::Chaining
: DesignatedInitKind::Stub)) {
*this, classDecl, superclassCtor, kind)) {
classDecl->addMember(ctor);
}
}
Expand Down
8 changes: 4 additions & 4 deletions test/IRGen/sil_linkage.sil
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
sil_stage canonical

// CHECK: define{{( protected)?}} void @public_fragile_function_test() {{.*}} {
// CHECK: define hidden void @hidden_fragile_function_test() {{.*}} {
// CHECK: define{{( protected)?}} void @hidden_fragile_function_test() {{.*}} {
// CHECK: define linkonce_odr hidden void @shared_fragile_function_test() {{.*}} {
// CHECK: define internal void @private_fragile_function_test() {{.*}} {
// CHECK: define{{( protected)?}} void @private_fragile_function_test() {{.*}} {
// CHECK: define linkonce_odr hidden void @public_external_fragile_function_def_test() {{.*}} {
// CHECK: define available_externally hidden void @hidden_external_fragile_function_def_test() {{.*}} {
// CHECK: define{{( protected)?}} available_externally void @hidden_external_fragile_function_def_test() {{.*}} {
// CHECK: define linkonce_odr hidden void @shared_external_fragile_function_def_test() {{.*}} {
// CHECK: define available_externally hidden void @private_external_fragile_function_def_test() {{.*}} {
// CHECK: define{{( protected)?}} available_externally void @private_external_fragile_function_def_test() {{.*}} {
// CHECK: define{{( protected)?}} void @public_resilient_function_test() {{.*}} {
// CHECK: define hidden void @hidden_resilient_function_test() {{.*}} {
// CHECK: define linkonce_odr hidden void @shared_resilient_function_test() {{.*}} {
Expand Down
6 changes: 5 additions & 1 deletion test/SILGen/accessibility_vtables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ class Sub : Base {
}
}

// CHECK-LABEL: sil hidden @_TFC21accessibility_vtables3SubcfT_S0_ : $@convention(method) (@owned Sub) -> @owned Sub
// CHECK: bb0(%0 : $Sub):
// CHECK: function_ref @_TFs26_unimplemented_initializerFT9classNameVs12StaticString8initNameS_4fileS_4lineSu6columnSu_T_

// CHECK-LABEL: sil_vtable Sub {
// CHECK-NEXT: #Base.internalMethod!1: _TFC28accessibility_vtables_helper4Base14internalMethod
// CHECK-NEXT: #Base.prop!getter.1: _TFC21accessibility_vtables3Subg4propSi // accessibility_vtables.Sub.prop.getter : Swift.Int
// CHECK-NEXT: #Base.prop!setter.1: _TFC28accessibility_vtables_helper4Bases4propSi // accessibility_vtables_helper.Base.prop.setter : Swift.Int
// CHECK-NEXT: #Base.prop!materializeForSet.1: _TFC28accessibility_vtables_helper4Basem4propSi // accessibility_vtables_helper.Base.prop.materializeForSet : Swift.Int
// CHECK-NEXT: #Base.init!initializer.1: _TFC28accessibility_vtables_helper4Basec
// CHECK-NEXT: #Base.init!initializer.1: _TFC21accessibility_vtables3SubcfT_S0_ // accessibility_vtables.Sub.init () -> accessibility_vtables.Sub
// CHECK-NEXT: #Sub.internalMethod!1: _TFC21accessibility_vtables3Sub14internalMethod
// CHECK-NEXT: #Sub.prop!setter.1: _TFC21accessibility_vtables3Subs4propSi // accessibility_vtables.Sub.prop.setter : Swift.Int
// CHECK-NEXT: #Sub.prop!materializeForSet.1: _TFC21accessibility_vtables3Subm4propSi // accessibility_vtables.Sub.prop.materializeForSet : Swift.Int
Expand Down
6 changes: 3 additions & 3 deletions test/SILGen/fragile_globals.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ var mygg = 29

// Check if we have three tokens: 2 from the imported modules, one from mygg.

// CHECK: sil_global private @globalinit_[[T1:.*]]_token0
// CHECK: sil_global [fragile] @globalinit_[[T2:.*]]_token0
// CHECK: sil_global [fragile] @globalinit_[[T3:.*]]_token0
// CHECK: sil_global private{{.*}} @globalinit_[[T1:.*]]_token0
// CHECK: sil_global private{{.*}} @globalinit_[[T2:.*]]_token0
// CHECK: sil_global private{{.*}} @globalinit_[[T3:.*]]_token0

public func sum() -> Int {
return mygg + get_gg_a() + get_gg_b()
Expand Down
2 changes: 1 addition & 1 deletion test/SILOptimizer/dead_inlined_func.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %target-swift-frontend -O -g %s -emit-sil | FileCheck %s -check-prefix=CHECK-SIL
// RUN: %target-swift-frontend -O -g %s -emit-ir | FileCheck %s -check-prefix=CHECK-IR
// RUN: %target-swift-frontend -O -g %s -sil-serialize-all -emit-ir | FileCheck %s -check-prefix=CHECK-IR

// The dead inlined function should not be in the SIL
// CHECK-SIL-NOT: sil {{.*}}to_be_inlined
Expand Down
4 changes: 2 additions & 2 deletions test/Serialization/global_init.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ var MyVar = 3
// CHECK: let MyConst: Int
// CHECK: var MyVar: Int

// CHECK-DAG: sil [fragile] [global_init] @_TF11global_initau7MyConstSi : $@convention(thin) () -> Builtin.RawPointer
// CHECK-DAG: sil [fragile] [global_init] @_TF11global_initau5MyVarSi : $@convention(thin) () -> Builtin.RawPointer
// CHECK-DAG: sil hidden [fragile] [global_init] @_TF11global_initau7MyConstSi : $@convention(thin) () -> Builtin.RawPointer
// CHECK-DAG: sil hidden [fragile] [global_init] @_TF11global_initau5MyVarSi : $@convention(thin) () -> Builtin.RawPointer

func getGlobals() -> Int {
return MyVar + MyConst
Expand Down
4 changes: 2 additions & 2 deletions test/Serialization/serialize_attr.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ class CC<T : PP> {
}
}

// CHECK-DAG: sil [fragile] [_specialize <Int, Float>] @_TF14serialize_attr14specializeThisu0_rFTx1uq__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {
// CHECK-DAG: sil hidden [fragile] [_specialize <Int, Float>] @_TF14serialize_attr14specializeThisu0_rFTx1uq__T_ : $@convention(thin) <T, U> (@in T, @in U) -> () {

// CHECK-DAG: sil [fragile] [noinline] [_specialize <RR, Float, SS, Int>] @_TFC14serialize_attr2CC3foouRd__S_2QQrfTqd__1gGVS_2GGx__Tqd__GS2_x__ : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
// CHECK-DAG: sil hidden [fragile] [noinline] [_specialize <RR, Float, SS, Int>] @_TFC14serialize_attr2CC3foouRd__S_2QQrfTqd__1gGVS_2GGx__Tqd__GS2_x__ : $@convention(method) <T where T : PP><U where U : QQ> (@in U, GG<T>, @guaranteed CC<T>) -> (@out U, GG<T>) {
2 changes: 1 addition & 1 deletion test/sil-extract/load-serialized-sil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@



// CHECK-LABEL: sil [fragile] @_TFVs1X4testfT_T_ : $@convention(method) (X) -> ()
// CHECK-LABEL: sil hidden [fragile] @_TFVs1X4testfT_T_ : $@convention(method) (X) -> ()
// CHECK: bb0
// CHECK-NEXT: function_ref
// CHECK-NEXT: function_ref @unknown : $@convention(thin) () -> ()
Expand Down
4 changes: 2 additions & 2 deletions test/sil-opt/sil-opt.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// CHECK: func unknown()
// SIB-CHECK: func unknown()

// CHECK-LABEL: sil [fragile] @_TFVs1X4testfT_T_ : $@convention(method) (X) -> ()
// CHECK-LABEL: sil hidden [fragile] @_TFVs1X4testfT_T_ : $@convention(method) (X) -> ()
// CHECK: bb0
// CHECK-NEXT: function_ref
// CHECK-NEXT: function_ref @unknown : $@convention(thin) () -> ()
Expand All @@ -36,7 +36,7 @@
// CHECK: sil @unknown : $@convention(thin) () -> ()
// SIB-CHECK: sil @unknown : $@convention(thin) () -> ()

// CHECK: sil [fragile] @_TFVs1XCfT_S_ : $@convention(method) (@thin X.Type) -> X
// CHECK: sil hidden [fragile] @_TFVs1XCfT_S_ : $@convention(method) (@thin X.Type) -> X
// CHECK: bb0
// CHECK-NEXT: struct $X ()
// CHECK-NEXT: return
Expand Down