Skip to content

[docs] LibraryEvolution: Merge @alwaysEmitIntoClient into @inlineable. #6118

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

Conversation

jrose-apple
Copy link
Contributor

@jckarter (and @gribozavr before him) pointed out a while back that having two ways to get something emitted into a client's module was really more complexity than we really needed, and created a pitfall for library authors who might choose the wrong one for their needs.

JoeG (and Dmitri before him) pointed out a while back that having
/two/ ways to get something emitted into a client's module was really
more complexity than we really needed, and created a pitfall for
library authors who might choose the wrong one for their needs.
@jrose-apple
Copy link
Contributor Author

@jckarter, @slavapestov, @milseman, @rjmccall, @drewcrawford, thoughts?

@jckarter
Copy link
Contributor

jckarter commented Dec 7, 2016

Makes sense to me. Inlinable functions ought to be small, and even if we can't inline them at a particular use site, emitting a copy into the client has performance benefits (no dyld stub) and reduces ABI liability, so that seems like the right default mode for inlinability.

@jrose-apple
Copy link
Contributor Author

I'm not sure about "inlinable functions ought to be small" when this is also the way to keep a function from being part of your ABI, but yes, that was the general thought.

@drewcrawford
Copy link
Contributor

IMO there is more than one type of inline, although the existing dichotomy does not quite capture it.

@inlineable is like C's inline, it's a performance feature. We're telling the compiler it may inline the function if it sees an optimization win

However C has another feature, __attribute__((always_inline), that we use in cases where we want to inline even if performance is poor. For example, we may want to force callers to inline our copy protection code at each callsite, we may want to ensure 2 callers in the same image to "link" (read: inline) different versions of Geometry.h, etc.

Partly hazy is whether "inline" in this context means inlining a function into calling functions or copying a function into a client module and calling the local copy from client functions. The latter is not especially useful but the former is.

Unrelated, but

Any local functions or closures within an inlineable function are themselves treated as @inlineable

would prefer to see an attribute for this, similar to @escaping

@jrose-apple
Copy link
Contributor Author

You're right that it's close to inline, but it also has the additional meaning of C's static when the availability matches up, in that in many cases it means the declaration isn't a part of the library's ABI. That's how the latter is useful (and something you were concerned about in the past).

Even without that, a client might still be able to get more optimization by the compiler looking at the body of a function and seeing what it does and doesn't do, at which point the function needs to be emitted into the client anyway.

There is an attribute @inline(__always) that we have today to force inlining, but I will continue to fight against officially supporting it. Humans are usually very bad at deciding this, and we have no "inline-but-not-always" attribute yet to see if the "always" is really necessary.

I am totally happy for this to get a different name that has nothing to do with inlining. I'd prefer if that name weren't "fragile", but we'll see.

Unrelated, but

Any local functions or closures within an inlineable function are themselves treated as @inlineable

would prefer to see an attribute for this, similar to @escaping

I'm a little confused by this. This is referring to functions and closures defined within the body of an inlineable function, not arguments.

@drewcrawford
Copy link
Contributor

in that in many cases it means the declaration isn't a part of the library's ABI. That's how the latter is useful (and something you were concerned about in the past).

I agree that having two keywords that (merely) evict the function from the ABI is redundant.

@milseman
Copy link
Member

milseman commented Dec 8, 2016

Is there a term other than @inlineable that's better here? I feel like talking about inlining carries baggage from people expecting it to be for optimizer hints rather than being about eliminating the function from the library's ABI. Unfortunately, linker terminology ("internal linkage") is easily confusable with access control. This is something nice about "alwaysEmitIntoClient", though it is very wordy.

@jrose-apple
Copy link
Contributor Author

I definitely agree we should change the name, but the primary effect is "make this available for clients". Only in some cases does it actually omit the thing from the library's ABI.

There's been no major objections so far, so I'll commit this and we can build on it.

@swift-ci Please smoke test

@jrose-apple
Copy link
Contributor Author

@airspeedswift, @dabrahams, this is relevant to our discussion today.

@jrose-apple jrose-apple merged commit d0a48c8 into swiftlang:master Dec 12, 2016
@jrose-apple jrose-apple deleted the LibraryEvolution-inlineable branch December 12, 2016 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants