SE-0193 - Cross-module inlining and specialization

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.
The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md

Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the review manager.
When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies

What goes into a review of a proposal?
The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.
When reviewing a proposal, here are some questions to consider:

• What is your evaluation of the proposal?
• Is the problem being addressed significant enough to warrant a change to Swift?
• Does this proposal fit well with the feel and direction of Swift?
• If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
• How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

+1

Is the problem being addressed significant enough to warrant a change to Swift?

yes

Does this proposal fit well with the feel and direction of Swift?

yes, I’d suggest a name like @abiExposed.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

C++ but on briefly.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

read proposal. used _ attribute in the past but never really needed it.

¡¡¡

On Dec 20, 2017, at 4:19 PM, Ted Kremenek via swift-evolution <swift-evolution@swift.org> wrote:

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Should there be some kind of diagnostic if you have an @abiPublic definition that is never referenced by any @inlinable function? I can imagine that there might be tools to check that a new build of a module doesn’t break binary compatibility by verifying that you didn’t remove any @abiPublic symbols, but what if you never meant to and never needed to export that symbol in the first place? How do we prevent that from happening?

Perhaps a diagnostic like this would cause problems if you started with an @inlinable function that called an @abiPublic function and then in a subsequent version of your module you modified the @inlinable function such that it no longer calls the @abiPublic function. You would still need to keep that @abiPublic function to support clients that had inlined the old version, right?

Maybe this could be built into the hypothetical binary compatibility checker. If there is no previous version or if the previous version didn’t have the symbol and it’s never referenced then it’s an error. Would that work? Am I overthinking this?

¡¡¡

On Dec 20, 2017, at 4:19 PM, Ted Kremenek via swift-evolution <swift-evolution@swift.org> wrote:

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

glad to see this finally moving forward!

The review of "SE-0193 - Cross-module inlining and specialization" begins
now and runs through *January 5, 2018*.

The proposal is available here:

GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
proposals/0193-cross-module-inlining-and-specialization.md

Reviews are an important part of the Swift evolution process. All review
feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

When replying, please try to keep the proposal link at the top of the
message:

Proposal link: GitHub - apple/swift-evolution: This maintains proposals for changes and user-visible enhancements to the Swift Programming Language.
proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies

What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift.

When reviewing a proposal, here are some questions to consider:

   -

   What is your evaluation of the proposal?

this is a feature i have been waiting for for a long time so needless to

say i strongly support this proposal. one comment is that @abiPublic is a
kind of awkward thing to have around, not because of how it’s spelled but
because i think access control and abi visibility are orthogonal concepts
and i’m not a fan of overloading access control terms for abi concepts. it
makes sense to have @abiPublic on private and fileprivate declarations too
and i hope this gets added, because private and fileprivate are tools for
code organization and maintenance,, the compiler with wmo doesn’t care
about private vs internal. but @abiPublic private is bound to cause
confusion and it just reads funny.

   -
   -

   Is the problem being addressed significant enough to warrant a change
   to Swift?

Yes. this issue (along with generic specialization which is really

rendered mostly irrelevant by inlining) is the main technical barrier
preventing a swift core library ecosystem from taking root. formalizing
this feature will allow library authors like me to ship and use modules for
low level tasks, whereas previously the workaround was to copy and paste handy
.swift files <https://github.com/kelvin13/swiftlets&gt; containing
implementations of common data structures and algorithms. ultimately this
will help maintainability, code reuse, and general code base cleanliness.

   -
   -

   Does this proposal fit well with the feel and direction of Swift?

i don’t see why it wouldn’t. the proposal seems overly conservative and

leans a bit too far towards maximum resilience vs maximum optimization but
that’s fine.

   -
   -

   If you have used other languages or libraries with a similar feature,
   how do you feel that this proposal compares to those?

this is a big step up from the c++ thing where you would just distribute

giant “header-only” libraries so

   -
   -

   How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

i read the whole thing,, and i’ve been following this discussion for a

while

¡¡¡

On Wed, Dec 20, 2017 at 6:19 PM, Ted Kremenek via swift-evolution < swift-evolution@swift.org> wrote:

   -

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

I am hugely supportive of the features that these attributes enable, but I think that the spelling of this is absolutely wrong, and I’m disappointed that the extensive discussion we’ve had for months about this didn’t make it into (at least) the alternatives considered section. Here are my concerns:

Availability Ranges

Both of these attributes will (perhaps not for Swift 5 given the fact that these will be new then, but certainly in 5.1 or 6) need to be qualified by deployment modifiers. We’ll need the ability to specify not just that a declaration is inlinable or abipublic, but in *which versions* of the binary package (that they are defined in) have this property.

For example, while perhaps it will be common for a decl to be “born inlinable” and just need the form of attribute as specified here, it is just as clear that this is not the *only* model we need. It is entirely reasonable (and will be important in the future) to say that something “became ABI public in iOS14, became abiPublic in iOS 15, and became inlinable in iOS16”. The use of this will be relatively rare, but it is important for the model to support this in time.

Because of this, if we accept the spelling as proposed in this proposal, these attributes will need to be generalized to have an availability range, e.g.:

  @abipublic(iOS 15, *)

The concern is that this proposal opens the door to have a family of attributes each of which have availability information on them, and this “family” of attributes will have nothing tying them together into a unified framework.

Pollution of the Attribute Namespace

Furthermore, these two attributes are the tip of the iceberg, and the core team has spent a lot of time recently discussing the fact there are potentially going to be about a dozen attributes similar to these (fixed_contents, global_var_is_directly_addressible, …) that will only be required for binary frameworks. It is possible that @inlinable will be prominent enough to be a global attribute (I personally am not sure if it will be commonly used or not, it depends a lot on how widely used binary frameworks are). That said, it is clear @abiPublic will not be commonly used, and many attributes that follow these will be even more obscure.

This is bad for three reasons:

1) we’re polluting the general attribute namespace with obscure things. Pollution of the attribute namespace may have a marginal impact today, but will start to matter if/when we ever get user defined attributes.

2) The other reason is that this provides no general framework to tie together these things that affect binary frameworks into a unified framework.

3) Furthermore, I don’t like attributes being a dumping ground for weird performance hacks required by binary frameworks. It is a practical necessity that we support these because they are extremely important for narrow cases, but we don’t need to put them into a syntactically prominent spot in the grammar.

The name “ABI”

A minor point, but the specific name “abiPublic” is not great in my opinion, because “ABI” is a term of art for compiler hackers. Most users have no idea what ABI means, and those who think they do often don’t. Very few people really understand what “stable ABI” means for example.

It would be better to go with something like “apiPublic” or “symbolPublic” or “linkableButNotAccessible” or something else long. This will not be commonly used in user code, so being long and descriptive is a good thing.

Counterproposal:

There is a simple way to address the two concerns above: we already have a framework for handling API evolution with binary frameworks, the @available attribute. We can spell these “attributes” as:

  @available(inlinable) // this symbol has been inlinable since it was introduced

which generalizes properly when we add version ranges:

  @available(iOS 14, *) // this was introduced in iOS 14
  @available(linkerSymbol: iOS 15, *) // this decl’s symbol became “abiPublic" in iOS 15
  @available(inlinable: iOS 16, *) // this decl became inlinable in iOS 16
  public func foo() {… }

and allows us to bury weird hacks like “abiPublic” and the other even more obscure things that are coming outside of the global attribute namespace:

  @available(global_var_is_directly_accessible: iOS 15, *)
  public var myDispatchOnceToken : ...

Given this unified framework for handling ABI evolution, we can then separately discuss which ones of these proposals are common and important enough to sugar into a top level attribute. For example, given the general model for inlinable above, we could then (possibly as a later proposal) introduce:

  @inlinable // this symbol has been inlinable since it was introduced
  public func foo()

as sugar for:

  @available(inlinable)
  public func foo()

… which means that the sugar forms can be separately debated, and that the sugar forms don’t have to permit the full complexity of the general case (the availability list). It still isn’t clear to me whether @inlinable meets the bar to be a global attribute, I can see both sides of that argument, and it seems valuable to be able to separate the engineering work to introduce the feature from the bikeshed discussion about whether it should be sugared or not.

In short, respectfully request that you at least add this approach to the "alternatives considered” section. I also suggest you strongly consider pursuing this direction. It solves the same problem as your proposal but:

- scales better as we add more “attributes" in the future - which will be of increasingly narrow applicability.
- provides a unifying model for all of the binary framework hints
- puts all the availability markup into the feature we already have for this.
- provides a better naming framework for things like abiPublic, because you can say "@available(linkerSymbol)” to say that this is making the linker symbol available from the binary framework.

-Chris

¡¡¡

On Dec 20, 2017, at 4:19 PM, Ted Kremenek <kremenek@apple.com> wrote:

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution-announce mailing list
swift-evolution-announce@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution-announce

1 Like

This seems like a problem worth solving — or rather worth making the solution public, since this is already in use as an undocumented feature!

A concern: how would a library author reason about, and check for bugs in, the combinatorial explosion of old and new implementations that could exist simultaneously with this feature in use?

The proposal touches on this in the “Effect on API resilience” section:

Any changes to the body of a declaration annotated as @inlinable should be considered very carefully. As a general guideline, we feel that @inlinable makes the most sense with "obviously correct" algorithms which manipulate other data types abstractly through protocols, so that any future changes to an @inlinable declaration are optimizations that do not change observed behavior.

Also, an @inlinable function implementation must be prepared to interact with multiple versions of the same function linked into a single binary. For example, if a hashing function is @inlinable, the hash algorithm must not be changed to avoid introducing inconsistency.

That last paragraph gives a relatively trivial example, but the implications are daunting! If I understand correctly, anything in a library that uses any @inlinable or @abiPublic code must be prepared to deal with every possible combination of every past published implementation of that code. And that “every possible combination” is not per function, but per…call site?

Suppose we have this:

    // Module A

    @inlineable func bar() { ... }

    // Module B

    @inlineable func foo() {
        if whatever {
            bar(0) // compiler decides to inline this...
        } else {
            bar(1) // ...but not this, for whatever reason
        }
    }

    // Module C

    func baz() {
        foo()
    }

…and suppose B was compiled against A v1.0 but C was compiled against A v2.0. Then, if I’m following, it’s possible for bar(0) to use the 1.0 implementation but bar(1) to use the 2.0 impl. Do I have that right? It seems to be what the hash value example is getting at.

The potential for undetected bugs seems enormous. I wonder if there’s a need for extra assistance for library authors, e.g.:

• A tool that allows one to take binaries for multiple versions of a lib with inlinables, and repeatedly runs a test suite using a randomly selected version of each inlinable func every time it’s used

• Static sanity checks (but what would they be?)

• Strict module version match conditions on @inlineable (but then dependency hell takes up residence in the compiler?)

• Bail on compilation and JIT everything (ha)

Or is this not as dangerous as I’m imagining it to be?

Cheers, P

¡¡¡

On Dec 20, 2017, at 6:19 PM, Ted Kremenek via swift-evolution <swift-evolution@swift.org> wrote:

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The review of "SE-0193 - Cross-module inlining and specialization" begins
now and runs through *January 5, 2018*.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md

Reviews are an important part of the Swift evolution process. All review
feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

When replying, please try to keep the proposal link at the top of the
message:

Proposal link:
https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies

What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift.

When reviewing a proposal, here are some questions to consider:

   -

   What is your evaluation of the proposal?

I have been doing the unkosher thing of using these underscored attributes
and would very much like to see these formalized.

My one bikeshedding issue here is the name @abiPublic, which smells too
much like fileprivate in my subjective opinion. A more concrete objection
here is the very much non-ideal juxtaposition of two different access
modifier terms in the "@abiPublic internal" spelling. It would seem to me
that "@abi" would suffice instead. Indeed, the fact that it's an
"interface" implies a certain level of visibility, which in my view is more
precise than coopting the term "public"--that term in turn has an
established meaning in Swift that, by construction, an "@abiPublic
internal" method does not fulfill.

   - Is the problem being addressed significant enough to warrant a
   change to Swift?

Yes, we need this.

   - Does this proposal fit well with the feel and direction of Swift?

Yes, with a caveat. It seems a little unfortunate that @inline(never) is
spelled so differently from @inlinable. Probably too late to rename the
former @noninlinable though. It'd be lovely though.

   - If you have used other languages or libraries with a similar
   feature, how do you feel that this proposal compares to those?

Not really, no.

   - How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

I have used the underscored feature already, and I have read the document.

Thanks,

¡¡¡

On Wed, Dec 20, 2017 at 18:19 Ted Kremenek via swift-evolution < swift-evolution@swift.org> wrote:

Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The review of "SE-0193 - Cross-module inlining and specialization" begins
now and runs through *January 5, 2018*.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md

Reviews are an important part of the Swift evolution process. All review
feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager.

When replying, please try to keep the proposal link at the top of the
message:

Proposal link:
https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies

What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift.

When reviewing a proposal, here are some questions to consider:

   -

   What is your evaluation of the proposal?

+1. I've worked on a performance-sensitive codebase (Swift protocol

buffers) where being able to optimize across module boundaries (using
documented features!) would be a huge win.

   -
   -

   Is the problem being addressed significant enough to warrant a change
   to Swift?

Yes.

   -
   -

   Does this proposal fit well with the feel and direction of Swift?

Yes, aside from the inevitable name bikeshedding. :)

I share Xiaodi's view that "@abiPublic" feels like it's coĂśpting "public"
in an odd way, especially when that attribute specifically only applies to
internal decls. I could get behind "@abi", but that doesn't quite feel like
"enough". "@abiVisible" comes to mind as a possibility—the declaration
isn't "public", but it's "visible" in the ABI.

A related question (with some background): My assumption is that
conditional compilation directives (e.g., if DEBUG) are resolved *before*
an @inlinable function is serialized to the module. Is that correct? In
other words, if I have this:

¡¡¡

On Wed, Dec 20, 2017 at 4:19 PM Ted Kremenek via swift-evolution < swift-evolution@swift.org> wrote:

-----
// Logger
@inlinable func log(_ msg: String) {
if DEBUG
  print(msg)
#endif
}

// Client
import Logger
log("hello")
-----

Then when Logger is compiled, the call to print() is *not serialized at
all* if DEBUG is undefined, right? (As opposed to serializing the
conditional and the body and then using the value of DEBUG in *Client's*
compilation to decide whether the code is present when inlined.)

The reason I ask is because I've been looking at how to tackle logging in
Swift—specifically the ability to have debug logging statements completely
stripped (including the strings passed to them) in release binaries. This
can be achieved today if the logging function is in the same module as the
caller and you do an optimized build (and you trust the optimizer to do
this reliably); the entire function call and its strings are dropped.

But if Logger is a separate module, this is no longer possible. @inlinable
is one of the ways that I thought this problem could be resolved, but only
if the conditionals are also serialized and reapplied against the client's
-D flags, and only if the attribute is a *guarantee* from the compiler and
not just a *suggestion* to it.

My hunch is that this is out of scope for this particular proposal (and
would be a "side effect" at best rather than a "feature" even if it did
work), but I'd love to hear your thoughts on that!

   -
   -

   If you have used other languages or libraries with a similar feature,
   how do you feel that this proposal compares to those?

Just C++, as described in the proposal. It's unfortunate that C++'s

separate header/source structure makes this more elegant in a sense than
the Swift solution using attributes, by virtue of just deciding where you
place the code. That being said, I can't think of a more elegant approach.

   -
   -

   How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

Followed earlier discussions and read the proposal.

   -

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

  â€˘ What is your evaluation of the proposal?

I'm working on a performance sensitive library and we're sometimes bitten quite hard by not being able to cross-module inline & specialise. Therefore, it's thrilling to see that you're working in this area.

However, I have to admit that I believe this language feature will most likely be grossly abused. The library I'm working on will presumably never have stable ABI as you'd naturally build it with your application. However we also don't want to miss on the cross-module optimisation & specialisation and I suspect there are quite a few (mostly open-source) libraries in the same space. I'm pretty sure everybody would just end up littering their code with @abiPublic/@inlinable (or the @available(...) syntax Chris Lattner proposed) without actually meaning that.

Summing up: I think this feature is crucial but shouldn't come without a compiler "where all declarations become implicitly @inlinable, and all private and internal declarations become @abiPublic". I really don't want to litter the code with attributes that aren't what I mean. (basically `swift build --global-resilience-domain`) Having this compiler mode also makes these attributes IMHO really niche and therefore I can only sympathise with's Chris' sentiment to not litter the global attribute namespace.

  â€˘ Is the problem being addressed significant enough to warrant a change to Swift?

see above.

  â€˘ Does this proposal fit well with the feel and direction of Swift?

to back up the 'swift' claim, cross-module inlining & specialisation is absolutely necessary. However this should also be achievable with a 'I don't need a stable ABI for this product' mode in the compiler :).

  â€˘ If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

C(++) as described in the proposal and Haskell (https://wiki.haskell.org/Inlining_and_Specialisation\), where {-# INLINABLE myFunction #-} (quoting the docs) causes exactly two things to happens.

  â€˘ The function's (exact) definition is included in the interface file for the module.
  â€˘ The function will be specialised at use sites -- even across modules.
Note that [the Haskell compiler] GHC is no more keen to inline an INLINABLE function than any other.

  â€˘ How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

read the proposal (and believe to understand it).

-- Johannes

¡¡¡

On 21 Dec 2017, at 12:19 am, Ted Kremenek via swift-evolution <swift-evolution@swift.org> wrote:

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
What is your evaluation of the proposal?

-1

The proposal puts all the emphasis on the programmer. It is better for the compiler to decide if something is to be inclined both across modules and within modules.

If something is made public then it should be fixed for a given major version number. No need for extra annotation.

A module system that allows versioning is a better solution.

Is the problem being addressed significant enough to warrant a change to Swift?

Yes significant but wrong solution

Does this proposal fit well with the feel and direction of Swift?

No, cluttering up declarations is completely against the clarity of Swift. For example who other than people on this group will understand @inline(never) @inlinable.

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

Yes C and C++ and found the equivalent of these annotations problematic. In Java they eliminated all this and let the compiler do the work. In practice this works much better.

Perhaps the compiler should publish the SIL or LLVM for all public functions. Analogous to Java’s class files. This sort of system works really will, much better than C and C++.

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Followed the discussions and read the proposal. The proposal doesn’t seem to encompass all the discussions. It would be nice if the proposal had a much more extensive summary of alternatives suggested.
-- Howard.

¡¡¡

On 20 Dec 2017, at 7:19 pm, Ted Kremenek via swift-evolution <swift-evolution@swift.org> wrote:

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I agree with the common theme that `@abiPublic` is weird. I imagine that not a lot of `@abiPublic` symbols actually want to be internal: they'll almost all be implementation details that really want to be `private` or `fileprivate` but that have to be `internal` to satisfy what (I believe) most people would consider to be a leaky abstraction provided by the Swift language. So why not go all the way and force @inlinable code to only reference public declarations?

What do we get in exchange of subverting the thus-far clear meaning of `internal`? Why is it better to have a special kind of internal that is not internal, instead of a special kind of public that is not listed, or even just no special kind of public?

That detail aside, having the ability to do cross-module inlining and specializing is valuable and exciting.

FĂŠlix

¡¡¡

Le 20 dĂŠc. 2017 Ă  19:19, Ted Kremenek via swift-evolution <swift-evolution@swift.org> a ĂŠcrit :

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Hi Xiaodi,

Thanks for taking the time to look over the proposal.

¡¡¡

On Dec 20, 2017, at 7:01 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Does this proposal fit well with the feel and direction of Swift?

Yes, with a caveat. It seems a little unfortunate that @inline(never) is spelled so differently from @inlinable. Probably too late to rename the former @noninlinable though. It'd be lovely though.

So @inline(never) is not the opposite of @inlinable, it is something completely different:

- @inline(never) impacts the optimizer’s behavior inside the module, where as @inlinable has no effect on callees inside a module.
- You can in fact define a function that is @inline(never) and @inlinable. This would allow the function to be specialized or otherwise emitted inside a client module, but neither the specialization nor the original function would ever be inlined.

I’d like the swift-evolution community to discuss @inline(never) and @inline(__always) at some point, but I think they’re sufficiently unrelated to this proposal that we should probably not try to fit them in.

Slava

Hi Nevin,

Thanks for taking the time to review the proposal!

Alternatively, since the “@abiPublic” attribute allows objects to be used by inlined code, why not spell it “@inlinable”?

Because both @abiPublic and @inlinable can be applied to functions, and we really do need to distinguish the two cases — they’re definitely not the same:

private func pf() {}

@abiPublic func af() {
  pf() // OK — we can reference a private function here
  // framework author can change the body of af() and clients see the new body
}

@inlinable public func if() {
  pf() // error!

  af() // OK

  // changes made here don’t necessarily get picked up by clients until recompiled
}

Slava

¡¡¡

On Dec 20, 2017, at 7:08 PM, Nevin Brackett-Rozinsky via swift-evolution <swift-evolution@swift.org> wrote:

Hi Tony,

Thanks for the review!

¡¡¡

On Dec 20, 2017, at 8:09 PM, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

A related question (with some background): My assumption is that conditional compilation directives (e.g., if DEBUG) are resolved *before* an @inlinable function is serialized to the module. Is that correct?

That is correct. Conditional compilation directives are always resolved in the context of the defining module.

Slava

I concur. If we don't care about its ungainly size, the blindingly obvious solution would be `@inlineCallable`. Another solution might be to declare the symbol with a combination like `@hidden public`, which I assume is a closer representation of how this feature is actually implemented.

(Incidentally, the proposal doesn't mention `open`; I suspect that it probably should.)

¡¡¡

On Dec 20, 2017, at 7:01 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

My one bikeshedding issue here is the name @abiPublic, which smells too much like fileprivate in my subjective opinion. A more concrete objection here is the very much non-ideal juxtaposition of two different access modifier terms in the "@abiPublic internal" spelling. It would seem to me that "@abi" would suffice instead. Indeed, the fact that it's an "interface" implies a certain level of visibility, which in my view is more precise than coopting the term "public"--that term in turn has an established meaning in Swift that, by construction, an "@abiPublic internal" method does not fulfill.

--
Brent Royal-Gordon
Architechies

Alternatively, since the “@abiPublic” attribute allows objects to be used
by inlined code, why not spell it “@inlinable”?

Nevin

¡¡¡

On Wed, Dec 20, 2017 at 10:01 PM, Xiaodi Wu via swift-evolution < swift-evolution@swift.org> wrote:

I have been doing the unkosher thing of using these underscored attributes
and would very much like to see these formalized.

My one bikeshedding issue here is the name @abiPublic, which smells too
much like fileprivate in my subjective opinion. A more concrete objection
here is the very much non-ideal juxtaposition of two different access
modifier terms in the "@abiPublic internal" spelling. It would seem to me
that "@abi" would suffice instead. Indeed, the fact that it's an
"interface" implies a certain level of visibility, which in my view is more
precise than coopting the term "public"--that term in turn has an
established meaning in Swift that, by construction, an "@abiPublic
internal" method does not fulfill.

Thanks for the review, Kelvin.

¡¡¡

On Dec 20, 2017, at 8:52 PM, Kelvin Ma via swift-evolution <swift-evolution@swift.org> wrote:

it makes sense to have @abiPublic on private and fileprivate declarations too and i hope this gets added, because private and fileprivate are tools for code organization and maintenance,, the compiler with wmo doesn’t care about private vs internal. but @abiPublic private is bound to cause confusion and it just reads funny.

From an implementation standpoint, it would be a simple change to allow @abiPublic on private and fileprivate declarations. However, I think that introduce some confusion. Recall that the mangling of private symbols includes the source file name. This would now be part of your framework’s ABI. If you moved the @abiPublic function to another source file, or rename the source file, you will break ABI.

Another approach would be to change the mangling so that @abiPublic private symbols are mangled like internal symbols, with a module name and no source file name. This makes for a simpler ABI. However this also has a downside, because now if you define two @abiPublic private functions in different files that have the same mangling, you will get a linker error and not a nice compiler diagnostic.

Note that nothing in this proposal precludes @abiPublic from being applied to private and fileprivate symbols though. If we figure out a nice solution to the above problems, we could generalize @abiPublic without any issues.

Slava

Hi Paul,

Thanks for reviewing the proposal!

A concern: how would a library author reason about, and check for bugs in, the combinatorial explosion of old and new implementations that could exist simultaneously with this feature in use?

I don’t have a simple answer to this unfortunately, other than the author being really careful, perhaps keeping around build artifacts that were compiled against older versions of the library and testing those.

That last paragraph gives a relatively trivial example, but the implications are daunting! If I understand correctly, anything in a library that uses any @inlinable or @abiPublic code must be prepared to deal with every possible combination of every past published implementation of that code. And that “every possible combination” is not per function, but per…call site?

Suppose we have this:

    // Module A

    @inlineable func bar() { ... }

    // Module B

    @inlineable func foo() {
        if whatever {
            bar(0) // compiler decides to inline this...
        } else {
            bar(1) // ...but not this, for whatever reason
        }
    }

    // Module C

    func baz() {
        foo()
    }

…and suppose B was compiled against A v1.0 but C was compiled against A v2.0. Then, if I’m following, it’s possible for bar(0) to use the 1.0 implementation but bar(1) to use the 2.0 impl. Do I have that right? It seems to be what the hash value example is getting at.

That is correct. Another example is if module A publishes an inlinable function, and module B and C depend on A, but B and C were compiled with different versions of A. Then a fourth module D that depends on B and C might see two different published versions of this function.

Or is this not as dangerous as I’m imagining it to be?

It *is* pretty dangerous, which is why I hope this feature is used judiciously by third-party binary frameworks. With source frameworks that are built together with an app and always recompiled, this is less of a concern.

Also we are using this feature extensively in the standard library, so as the standard library evolves we will learn and develop best practices, hopefully without too many hiccups :)

Slava

¡¡¡

On Dec 20, 2017, at 9:21 PM, Paul Cantrell <cantrell@pobox.com> wrote:

Cheers, P

On Dec 20, 2017, at 6:19 PM, Ted Kremenek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

Hi Brent,

I concur. If we don't care about its ungainly size, the blindingly obvious solution would be `@inlineCallable`. Another solution might be to declare the symbol with a combination like `@hidden public`, which I assume is a closer representation of how this feature is actually implemented.

@hidden public seems more confusing to me, because the symbol is not public to name lookup. @abiPublic has no effect on source compatibility, only binary compatibility.

(Incidentally, the proposal doesn't mention `open`; I suspect that it probably should.)

I can revise the proposal to add a brief mention of ‘open’ if you’d like. As you may have guessed already there is no distinction between ‘open’ and ‘public’ here.

Slava

¡¡¡

On Dec 20, 2017, at 9:35 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

Should there be some kind of diagnostic if you have an @abiPublic definition that is never referenced by any @inlinable function? I can imagine that there might be tools to check that a new build of a module doesn’t break binary compatibility by verifying that you didn’t remove any @abiPublic symbols, but what if you never meant to and never needed to export that symbol in the first place? How do we prevent that from happening?

From a technical standpoint it would be possible to implement such a diagnostic, with the caveat that it would probably only work in whole module optimization mode. However, you’re right that there’s a complication here:

Perhaps a diagnostic like this would cause problems if you started with an @inlinable function that called an @abiPublic function and then in a subsequent version of your module you modified the @inlinable function such that it no longer calls the @abiPublic function. You would still need to keep that @abiPublic function to support clients that had inlined the old version, right?

This is correct; you may well end up with newer versions of a library that carry @abiPublic symbols only for compatibility reasons.

Maybe this could be built into the hypothetical binary compatibility checker. If there is no previous version or if the previous version didn’t have the symbol and it’s never referenced then it’s an error. Would that work? Am I overthinking this?

Yes, that would certainly be possible. We’ve discussed having an “ABI differ” tool as something we would really like to have, but so far no concrete design has been proposed. I expect this discussion will take on a greater urgency once we get close to shipping the second version of an “ABI stable” standard library. It’s obviously not needed the first time around.

Slava

¡¡¡

On Dec 20, 2017, at 10:17 PM, Adam Kemp via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 20, 2017, at 4:19 PM, Ted Kremenek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The review of "SE-0193 - Cross-module inlining and specialization" begins now and runs through January 5, 2018.

The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
Reviews are an important part of the Swift evolution process. All review feedback should be sent to the swift-evolution mailing list at:

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager.

When replying, please try to keep the proposal link at the top of the message:

Proposal link: https://github.com/apple/swift-evolution/blob/master/proposals/0193-cross-module-inlining-and-specialization.md
...
Reply text
...
Other replies
What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

What is your evaluation of the proposal?

Is the problem being addressed significant enough to warrant a change to Swift?

Does this proposal fit well with the feel and direction of Swift?

If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,
Ted Kremenek
Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution