Skip to content
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

[SR-6209] Allow @_silgen_name to create a hidden symbol #48761

Closed
gparker42 mannequin opened this issue Oct 24, 2017 · 9 comments
Closed

[SR-6209] Allow @_silgen_name to create a hidden symbol #48761

gparker42 mannequin opened this issue Oct 24, 2017 · 9 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself SILOptimizer Area → compiler: SIL optimization passes

Comments

@gparker42
Copy link
Mannequin

gparker42 mannequin commented Oct 24, 2017

Previous ID SR-6209
Radar rdar://problem/33924873
Original Reporter @gparker42
Type Bug
Status Resolved
Resolution Done
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, SILOptimizer
Assignee @gparker42
Priority Medium

md5: 55224335b3454471952a666e403be0bd

Issue Description:

libswiftCore uses @_silgen_name to write Swift functions that can be called from C code. There should be a way to do this that creates a hidden symbol (matching clang's `__attribute__((visibility("hidden")))`).

Example of today's usage:

  @_silgen_name("swift_stdlib_getErrorCode")
  public func _stdlib_getErrorCode<T : Error>(_ x: UnsafePointer<T>) -> Int {
    return x.pointee._code
  }

This function is intended to be called by libswiftCore's C code only, but the swift_stdlib_getErrorCode symbol is eventually exported from libSwiftCore. That's bad.

Suggested change: use a hidden symbol when an internal func implementation has @_silgen_name:

  @_silgen_name("swift_stdlib_getErrorCode")
  internal func _stdlib_getErrorCode<T : Error>(_ x: UnsafePointer<T>) -> Int {
    return x.pointee._code
  }
@belkadan
Copy link
Contributor

I think this just means not to eliminate it in dead function elimination, which seems reasonable. (It works in non-WMO -O and in -Onone.) @eeckstein, who works on dead function elimination these days?

@eeckstein
Copy link
Member

It's pretty easy to add that in dead function elimination: Just add an additional check in

bool isAnchorFunction(SILFunction *F)

@gparker42
Copy link
Mannequin Author

gparker42 mannequin commented Oct 25, 2017

That turns out not to work: isAnchorFunction() is never called during the stdlib's build (at least not a debug-stdlib build), presumably because DFE is not running at all. Something else must be killing the function.

@eeckstein
Copy link
Member

There is another thing: IRGen only emits functions lazily. The check for this is done in IRGenerator::emitGlobalTopLevel().

I think the best solution is to check for @_silgen_name in SILFunction::isPossiblyUsedExternally(). Unfortunately in some places (like IRGenerator::emitGlobalTopLevel) doesn't call this SILFunction member, but instead call the global function isPossiblyUsedExternally. This has to be changed.

@gparker42
Copy link
Mannequin Author

gparker42 mannequin commented Oct 26, 2017

Original isAnchorFunction WIP is https://github.com/gparker42/swift/tree/keep-silgenname .

@gparker42
Copy link
Mannequin Author

gparker42 mannequin commented Oct 27, 2017

Changing SILFunction::isPossiblyUsedExternally() and SILFunction::isExternallyUsed() was insufficient.

Changing the global isPossiblyUsedExternally() function in SILLinkage.h to return true did work.

One conceptually correct fix would be to introduce an additional SILLinkage value between Public and Hidden which I shall call MostlyHidden.
Public: visible outside the current Swift module and/or linkage unit.
MostlyHidden: visible only to the current Swift module and to non-Swift code in the same linkage unit.
Hidden: visible only to the current Swift module.

@eeckstein
Copy link
Member

> Changing SILFunction::isPossiblyUsedExternally() and SILFunction::isExternallyUsed() was insufficient.

As I said earlier, there are some uses of the global isPossiblyUsedExternally function, which are called with the function's linkage (like in IRGen). You have to replace this with the SILFunction::isPossiblyUsedExternally.

That's the cleanest and easiest fix.

> Changing the global isPossiblyUsedExternally() function in SILLinkage.h to return true did work.

That would be bad for the optimizer.

> One conceptually correct fix would be to introduce an additional SILLinkage value between Public and Hidden

Please don't. It would make our already complicated linkage model even more not-understandable.

@gparker42
Copy link
Mannequin Author

gparker42 mannequin commented Nov 1, 2017

#12696

This uses the SILFunction::isPossiblyUsedExternally() approach. It also covers @_cdecl to fix rdar://33924873.

There is residual ugliness involving this and isKeepAsPublic() and isExternallyUsedSymbol(). Future cleanup ought to get these three special cases to share more code in common.

@bob-wilson
Copy link

This is done now.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself SILOptimizer Area → compiler: SIL optimization passes
Projects
None yet
Development

No branches or pull requests

3 participants