Responding on swift-dev to what turned into an interesting discussion…
We definitely want an inline-at-Onone, but I assumed we were treating "@inline(__always)" as a normal heuristic because:
- @transparent already does inline-at-Onone.
- @inline(__always) without @transparent negatively affects the debug experience.
- @inline(__always) isn't useful if no optimizations are run after inlining.
That said, if the common expectation is for @inline(__always) to kick in independent of optimization, then we should honor that.
It's easy for me to add an inlining pass to runSILPassesForOnone. I'm just not sure that will have the effect people are looking for. It's unlikely to help performance since nothing is going to run after the inlining (no capture promotion or alloc box-to-stack). The only optimization we currently run at Onone after diagnostics is prespecialization.
Actually, the inliner specializes as it goes, so inlining after mandatory SIL passes would still be quite useful.
My concern is really that the user may expect inline(__always) to be as effective a performance tool as @transparent, while preserving debug line locations.
If it runs late, it doesn’t expose capture promotion, box-to-stack, guaranteed ARC optimization, etc.
If someone is using inline(__always) for -Onone performance reasons, I think they really need to use @transparent.
An alternative is to have @inline(__always) be another way to spell @transparent. People would need to implicitly know that this would affect diagnostics of the inlined method.
`@transparent` doesn't just mean "inline-at-Onone", it also allows diagnostic passes to constant-fold through the implementation and actively eliminates debug information. It was never intended to be used for performance, but only for the limited set of things that need it. I imagine that the specialization you get by inlining some things is pretty important by itself. I suspect closure inlining would also be helpful for a lot of low-level "with*" combinators; doesn't transparent inlining do that, and could inline-always-inlining do the same?
The only remaining question: is it ok for a non-transparent function to be inlined prior to running some dataflow diagnostics?
Doing so changes the set of programs that are accepted, since it may expose more code to diagnostic passes. We don't want diagnostics to depend on optimizations.
Perhaps we could avoid this by changing the diagnostic passes to intentionally ignore instructions with inlined source locations, though that seems brittle.
Well, inline(__always) would be mandatory, not an optimization. But I think your point is that the user does not expect that attribute to affect program legality. Having data-flow diagnostics “ignore” certain instructions sounds horrible. Is there an obvious problem, or is this hypothetical? i.e. is there some diagnostic that is currently enforced at the function boundary but would be considered legal code after inlining?
On Dec 1, 2016, at 11:19 AM, Joe Groff <firstname.lastname@example.org> wrote:
On Dec 1, 2016, at 11:18 AM, Joe Groff <email@example.com> wrote:
On Dec 1, 2016, at 11:16 AM, Andrew Trick <firstname.lastname@example.org> wrote:
On Dec 1, 2016, at 10:34 AM, Jordan Rose <email@example.com> wrote:
On Nov 30, 2016, at 18:16, Joe Groff <firstname.lastname@example.org> wrote:
On Nov 30, 2016, at 6:10 PM, Andrew Trick <email@example.com> wrote: