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-7278] -Onone should inline no-escape closures #49826

Open
atrick opened this issue Mar 26, 2018 · 3 comments
Open

[SR-7278] -Onone should inline no-escape closures #49826

atrick opened this issue Mar 26, 2018 · 3 comments
Labels
compiler The Swift compiler in itself improvement

Comments

@atrick
Copy link
Member

atrick commented Mar 26, 2018

Previous ID SR-7278
Radar rdar://35815273
Original Reporter @atrick
Type Improvement
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Improvement
Assignee None
Priority Medium

md5: 35a9d025ccabb934e12da343f595ac7d

relates to:

Issue Description:

Wrapping an always-inline (or @transparent) call in a no-escape closure should have no impact on the generated SIL at -Onone.

In particular, the stdlib should be able to rely on

defer { _fixLifetime(x) }

to have identical behavior to a direct call to _fixLifetime, even at -Onone.

When a no-escape closure is called directly, as in `defer`, inlining it reduces code size. There's no way to mark the closure itself as always-inline, but that could be inferred from simple patterns. If each captured variable is directly passed to an always-inline function like _fixLifetime, the users certainly wants the closure to be inlined.

Example:

public func testFixLifetime(obj1: AnyObject, obj2: AnyObject) \{
 defer \{ _fixLifetime(obj1); _fixLifetime(obj2) }
 let bits1 = unsafeBitCast(obj1, to: Int.self)
 let bits2 = unsafeBitCast(obj2, to: Int.self)
 checkBits(bits1 | bits2)
}
{

This could be done a couple different ways

1. Recognize certain noescape closures patterns and mark them always-inline before mandatory inlining.

2. More generally recognize noescape closure patterns for inlining during or after MandatoryInlining. For example, a closure with only fix_lifetime instructions should be recognized as zero-cost, regardless of multiple callers. Furthermore, we may just want to inline all no-escape closures with only one caller.

@belkadan
Copy link
Contributor

I don't think this is correct; it's that -Onone should inline defer. But I guess the only other noescape closures we have that you can inline at -Onone are the ones that are directly called, and that wouldn't do any harm.

@atrick
Copy link
Member Author

atrick commented Mar 27, 2018

The user (stdlib author in this case) needs a way to control Onone inlining. The non-defer case comes up if the closure is being passed through an inline-always call path. So always inlining no-escape

  • gives the user what they occasionally need without adding syntax

  • often incidentally improves Onone performance without hurting debugging

  • never does any harm

@belkadan
Copy link
Contributor

It can do harm; it can increase code size. But if I said that the rule could be "inline(always) applied to a function automatically applies to its closure arguments as well", you'd rightly point out that that has the exact same effect in practice.

Thanks for explaining the context for me.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself improvement
Projects
None yet
Development

No branches or pull requests

2 participants