inline best practices?


(Erica Sadun) #1

Any best practices for `@inline(__always)`? When it's short? When has very few call sites? When the abstraction aids reading but hinders computation?

Thanks -- E


(Jordan Rose) #2

Please don’t use it ever. The underscores are there for a reason.

(I wouldn’t be surprised if some optimizer folks to come by and give a more nuanced answer later, but there are so many potential and actual pitfalls around it now that I wouldn’t say it’s ever a good idea.)

Jordan

···

On Mar 2, 2017, at 16:27, Erica Sadun via swift-users <swift-users@swift.org> wrote:

Any best practices for `@inline(__always)`? When it's short? When has very few call sites? When the abstraction aids reading but hinders computation?

Thanks -- E

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


(Slava Pestov) #3

Here’s an overview of @inline(__always):

- It is an annotation for the performance inliner, which only runs in -O builds. The performance inliner uses heuristics to figure out what to inline, so most of the time explicit annotations are not necessary, and sometimes it won’t inline something even if its @inline(__always) — for example, inlining of generics is not enabled in 3.1 yet, because of code size concerns. We might change this behavior to make @inline(__always) mandatory one day.

- Public inline always functions have the additional behavior that they can be inlined into other modules, with caveats.

- In Swift 3.0, if a public inline always function references private symbols and is referenced from another module, you’ll get linker errors or a compiler crashes. In 3.1, we added diagnostics for this as part of the resilience model, but it’s totally a work in progress.

- The compiled body (more precisely, the SIL IR) for public inline always functions are serialized into the .swiftmodule file when a module is built with WMO.

- When building a library with WMO off, serialized SIL is simply discarded, which is a bug we intend on fixing.

- The @_transparent attribute is another low-level attribute that was never officially supported but some people have used it anyway. Transparent functions are inlined during mandatory optimizations, so you get it even in -Onone, subject to the same limitations on SIL serialization, what they can reference, etc. Transparent has other quirks around debug info and other things too. There’s a chance @_transparent will go away entirely. Please do not use it.

- There’s an @_inlineable attribute in master that’s a weaker form if @inline(__always). It enables the same restrictions on symbol references as @inline(__always), without changing the behavior of the performance inliner. This is needed because most of the time it’s not inlining you care about with generics, but being able to specialize the function body.

- The work on the library evolution model and ABI is centered on filling in the gaps in these attributes, documenting their behavior precisely and getting it all through swift-evolution — but there’s still a lot of heavy lifting left before we’re ready for that.

So the best practice is basically what Jordan said. Don’t use @inline(__always), @_inlineable, or @_transparent. But if you’re interested in helping with the design and implementation of these attributes, let us know.

Slava

···

On Mar 2, 2017, at 4:27 PM, Erica Sadun via swift-users <swift-users@swift.org> wrote:

Any best practices for `@inline(__always)`? When it's short? When has very few call sites? When the abstraction aids reading but hinders computation?

Thanks -- E

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