[swift-dev] Potential contributions to compilation time reporting?

Brian Gesiak modocache at gmail.com
Sun Nov 12 10:29:54 CST 2017


Hello all!

I'm looking for a body of work to do on the Swift compiler for an upcoming
programmer retreat I'm attending in January [1]. I've read a lot of blog
posts with tips for diagnosing slow Swift compile times [2], and I was
wondering if I could contribute to tooling in this area.

(Just to make it clear: I'm talking about improving and expanding the set
of tools developers have to figure out why their projects take a long time
to compile. I'm *not* talking about working on speeding Swift compile times
-- although the tools may indirectly help with that.)

# Current state: many options, but few "supported" ones

Most of the blog posts I've been reading talk about using the
`-driver-time-compilation`, `-debug-time-compilation`,
`-debug-time-function-bodies`, `-warn-long-function-bodies=`, and
`-warn-long-expression-type-checking=` options. I saved some sample output
from each of these options here
<https://gist.github.com/modocache/3fb21f5dc7fec6f300cacbe6c74c59d2>.

Using these options, developers can find function bodies and expressions
that took longer to compile than others.

However, it should be noted that, of these options, only the first is a
user-facing "supported" option. The others are `swift -frontend` options,
and as such the Swift team has been clear that this means the options may
be changed or removed at any point in the future [3].

What's more, several contributors have noted the behavior of the options
themselves could also be improved. Here's what I gathered from reading
several JIRA bugs, commit messages, and mailing list discussions:

- SR-2910 <https://bugs.swift.org/browse/SR-2910> points out that
`-debug-time-function-bodies` prints just `get {}` and `set {}` for struct
getters and setters, and that this could be improved by printing the
variable name as well.
- The commit that added `-warn-long-function-message=` notes in its commit
message
<https://github.com/apple/swift/commit/18c75928639acf0ccf0e1fb6729eea75bc09cbd5>
that
the option only measures some aspects of type-checking, that it doesn't
provide any information on how checking a function for the first time will
take longer, doesn't report on other phases of compilation, and doesn't
catch anything being type-checked multiple times.

In part because the options don't provide the functionality described in
the commit message above, the impression I've received has been that the
Swift team is not enthusiastic about exposing these options outside of
`-frontend`. From the comments on SR-2741
<https://bugs.swift.org/browse/SR-2741>, Jordan Rose writes:

> I'm leery of "productizing" `-debug-time-function-bodies` in any way
because it's already not a true story. Import and decl-checking costs that
come up for the first time during a particular function get ascribed to
that function. SILGen, optimization, and LLVM costs are ignored entirely.
Decl-checking costs that are *not* within a particular function are also
ignored. The only useful purpose of `-debug-time-function-bodies` is to see
if the type checker is spinning on a particular function.

# The question of whether to "productize" these options

Further, other contributors have expressed misgivings about "productizing"
these as well. In an email thread named "Reporting/Debugging Slow Swift
Compile Time"
<https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20161003/003099.html>,
Ben Asher writes:

> I understand Jordan's response (in SR-2741) of being "leery of
'productizing'" these flags. Developing with Swift shouldn't involve
fighting the compiler to get the best compile time, so making this more
than a debug flag does seem odd/worrisome.

I sympathize with this viewpoint, but I am concerned by three things:

1. The Swift team has been very clear that these options are "unsupported",
so my impression is that they're not quite the same as "debug flags".
`-driver-print-jobs` or `-###`, for example, are handy debugging options
that are, I think, "supported". They're not hidden behind the `-frontend`
option.
2. It seems like the reality is that many professional Swift developers use
these *unsupported* options (again, not simply "debugging options", but
unsupported `-frontend` options) every day in order to measure their
compilation times and keep them under control.
3. One argument for keeping these options "unsupported" is that these
professional developers won't need these `-frontend` options once the Swift
compiler becomes fast enough, at which point they could potentially be
removed without any room for complaint. But some large mobile application
teams work on codebases that take over an hour to compile, and are compiled
and hundreds of times each day. For teams such as these, the Swift compiler
will never be "fast enough". In environments where shaving 1% or 2% off of
compilation time results in large CPU and energy consumption savings, I
think engineers will always want to narrow down compilation time
bottlenecks, and those engineers would probably want a "supported" set of
options in order to do so -- that is, they'd rather not use options that
"may be removed without notice at any future date."

So, it's my opinion that work should be done to provide a "supported" set
of options to help diagnose why a Swift compilation is taking a long time,
and I'd like to work on that in January.

# Ideas for "supported" options, and other future work?

I'm 100% in agreement that options like `-debug-time-function-bodies`
should not be brought out from behind the `-frontend` option in their
current form. As I noted above, members of the Swift team consider these
options to provide inaccurate data. Even if the data was accurate, its
output is in an ad-hoc textual format, which is more difficult to
machine-parse than other formats.

I'd like to solicit ideas for future work here:

- At the very least, I could fix SR-2910
<https://bugs.swift.org/browse/SR-2910>.
- I'd also like to address some of the issues mentioned in this commit
message
<https://github.com/apple/swift/commit/18c75928639acf0ccf0e1fb6729eea75bc09cbd5>,
but I would like to confirm they're still something the Swift team would
like work to be done on. Jordan, are these still relevant?
- I'm wondering if anyone else has some work in-flight here, or if they
have ideas. If you've been longing for a "killer feature", please reply
here and let me know!

- Brian Gesiak

[1] See the blog post
<https://www.recurse.com/blog/121-come-to-rc-for-a-one-week-retreat> for
more details. Please let me know if you're also applying to go, especially
if you're thinking of working on Swift! It would be great to have a buddy :)
[2] Examples: 1 <https://github.com/fastred/Optimizing-Swift-Build-Times>, 2
<https://www.swiftbysundell.com/posts/improving-swift-compile-times>, and 3
<http://irace.me/swift-profiling>.
[3] This commit message
<https://github.com/apple/swift/commit/18c75928639acf0ccf0e1fb6729eea75bc09cbd5>
states
“As a frontend option, this is UNSUPPORTED and may be removed
without notice at any future date.”
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-dev/attachments/20171112/e195c4b7/attachment.html>


More information about the swift-dev mailing list