Skip to content

[SR-1788] Add -driver-time-compilation option #4367

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

Merged
merged 1 commit into from
Aug 23, 2016

Conversation

modocache
Copy link
Contributor

What's in this pull request?

Add an option to print the time it takes each driver task to complete.

Here's an example of the output:

$ swiftc -driver-time-compilation \
         -emit-library -module-name Crispix \
         Crispix/A.swift Crispix/B.swift Crispix/C.swift
===-------------------------------------------------------------------------===
                            Driver Time Compilation
===-------------------------------------------------------------------------===
  Total Execution Time: 0.0000 seconds (0.0892 wall clock)

   ---Wall Time---  --- Name ---
   0.0242 ( 27.1%)  /path/to/bin/swift -frontend -c -primary-file /path/to/Crispix/A.swift /path/to/Crispix/B.swift /path/to/Crispix/C.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -color-diagnostics -parse-as-library -module-name Crispix -o /tmp/A-216874.o

   0.0239 ( 26.7%)  /usr/bin/clang++ -shared -fuse-ld=gold -target x86_64-unknown-linux-gnu -Xlinker -rpath -Xlinker /path/to/lib/swift/linux /path/to/lib/swift/linux/x86_64/swift_begin.o /tmp/A-216874.o /tmp/B-243ab4.o /tmp/C-5af361.o -L /path/to/lib/swift/linux --target=x86_64-unknown-linux-gnu -lswiftCore @/tmp/A-864579.autolink /path/to/lib/swift/linux/x86_64/swift_end.o -o libCrispix.so

   0.0205 ( 23.0%)  /path/to/bin/swift -frontend -c /path/to/Crispix/A.swift -primary-file /path/to/Crispix/B.swift /path/to/Crispix/C.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -color-diagnostics -parse-as-library -module-name Crispix -o /tmp/B-243ab4.o

   0.0174 ( 19.6%)  /path/to/bin/swift -frontend -c /path/to/Crispix/A.swift /path/to/Crispix/B.swift -primary-file /path/to/Crispix/C.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -color-diagnostics -parse-as-library -module-name Crispix -o /tmp/C-5af361.o

   0.0032 (  3.6%)  /path/to/bin/swift-autolink-extract /tmp/A-216874.o /tmp/B-243ab4.o /tmp/C-5af361.o -o /tmp/A-864579.autolink

   0.0892 (100.0%)  Total

I don't write C++ very often, and this is probably one of the larger changes I've made to lib/Driver, so I wouldn't be surprised if there's some wacky code in here. 😅 Any and all feedback welcome!

/cc @jrose-apple @gottesmm

Resolved bug number: (SR-1788)


Before merging this pull request to apple/swift repository:

  • Test pull request on Swift continuous integration.

Triggering Swift CI

The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:

Smoke Testing

Platform Comment
All supported platforms @swift-ci Please smoke test
All supported platforms @swift-ci Please smoke test and merge
OS X platform @swift-ci Please smoke test OS X platform
Linux platform @swift-ci Please smoke test Linux platform

A smoke test on macOS does the following:

  1. Builds the compiler incrementally.
  2. Builds the standard library only for macOS. Simulator standard libraries and
    device standard libraries are not built.
  3. lldb is not built.
  4. The test and validation-test targets are run only for macOS. The optimized
    version of these tests are not run.

A smoke test on Linux does the following:

  1. Builds the compiler incrementally.
  2. Builds the standard library incrementally.
  3. lldb is built incrementally.
  4. The swift test and validation-test targets are run. The optimized version of these
    tests are not run.
  5. lldb is tested.

Validation Testing

Platform Comment
All supported platforms @swift-ci Please test
All supported platforms @swift-ci Please test and merge
OS X platform @swift-ci Please test OS X platform
OS X platform @swift-ci Please benchmark
Linux platform @swift-ci Please test Linux platform

Lint Testing

Language Comment
Python @swift-ci Please Python lint

Note: Only members of the Apple organization can trigger swift-ci.

@modocache
Copy link
Contributor Author

@swift-ci please test

@modocache
Copy link
Contributor Author

The Linux failures are occurring when compiling swift-corelibs-foundation, and appear to be unrelated.

@gottesmm
Copy link
Contributor

@jrose-apple is really the person to review this, but taking a quick look I have some comments.

@@ -421,14 +424,26 @@ int Compilation::performJobsImpl() {
}

int Result = EXIT_SUCCESS;
llvm::TimerGroup DriverTimerGroup("Driver Time Compilation");
std::map<std::string, std::unique_ptr<llvm::Timer>> DriverTimers;
Copy link
Contributor

@gottesmm gottesmm Aug 18, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given how the code is written, couldn't use an RAII type to hide all of this? I am imagining an API like:

// We want to make sure map is not allocating memory here unless we have ShowDriverTimeCompilation actually enabled. So I imagine you want something like SharedTimer has.
SimpleTimerGroup Group;

llvm::SmallString<128> CmdLine;
auto taskBegin = ... {
  if (ShowDriverTimeCompilation) {
    BeginCmd->printCommandLine(CmdLine);
    Group.startTimer(CmdLine)
  }
}

...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a perfectly good approach, except the map should be from Job * to timer instead of command-line-string to timer. (At which point I suggest using an llvm::DenseMap, which is a hash map. See the LLVM Programmer's Manual for more nifty data structures.)

@jrose-apple
Copy link
Contributor

This is looking great. I wonder how it interacts with -parseable-output, though. I do want to make sure that if someone puts this in their OTHER_SWIFT_FLAGS in Xcode that it shows up in the build log and doesn't mess up printing warnings from individual files.

(That's not something that necessarily makes sense to put in a regression test, but it's worth seeing what the behavior is before we commit. I think it'll be fine because I think I've used -driver-show-incremental in an Xcode project before.)

@modocache modocache force-pushed the driver-time-compilation branch from fbf7638 to 4375b9b Compare August 19, 2016 12:21
@modocache
Copy link
Contributor Author

When using both -parseable-output and -driver-time-compilation, the timer output appears after the parseable output: https://gist.github.com/modocache/588a47488e0c1c0d7dc793e71d1ff57c -- is that OK?

@modocache modocache force-pushed the driver-time-compilation branch from 4375b9b to 642a32f Compare August 19, 2016 14:28
@modocache
Copy link
Contributor Author

Thanks for all the great feedback! I think I addressed everything I can.

@swift-ci please test

DriverTimers.insert({
BeganCmd,
std::unique_ptr<llvm::Timer>(
new llvm::Timer(CmdLine.str(), DriverTimerGroup))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bonus tip: if you call str() on the raw_svector_ostream instead of the SmallString, you don't have to force its destructor to be called.

@gottesmm
Copy link
Contributor

@swift-ci Please test

@gottesmm
Copy link
Contributor

@modocache I don't think you actually triggered swift-ci. I pushed the button again.

@modocache modocache force-pushed the driver-time-compilation branch from 642a32f to 6639184 Compare August 19, 2016 21:59
@modocache
Copy link
Contributor Author

Thanks for the follow-ups @jrose-apple. I think I've responded to them all. Now let's see if Swift CI still listens to me...

@swift-ci Please test

@jrose-apple
Copy link
Contributor

Sort of. OS X tests here

// CHECK: ---Wall Time---
// CHECK: --- Name ---
// CHECK: driver-time-compilation.swift
// CHECK: {{[0-9]+}}.{{[0-9]+}} (100.0%) Total
Copy link
Contributor

@jrose-apple jrose-apple Aug 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I think it's worth having a multi-file test too. You could just add an extra RUN line that uses %S/../Inputs/empty.swift, a standard empty .swift file, as well as %s. (Both tests are useful.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! 👍

@modocache modocache force-pushed the driver-time-compilation branch from 6639184 to 6afc934 Compare August 20, 2016 03:37
@modocache
Copy link
Contributor Author

@swift-ci please test

@jrose-apple
Copy link
Contributor

Mostly looks good to me! I still feel weird about printing the whole command line, though—those can get pretty long with every input file appearing in the list.

@modocache modocache force-pushed the driver-time-compilation branch from 6afc934 to 1529d6e Compare August 22, 2016 16:02
@modocache
Copy link
Contributor Author

(Rebased onto #4437.)

Ah, yeah, I guess for most actual inputs these timer names would be much, much longer. I liked the idea of seeing the exactly which jobs took up what amount of time, but that information is also available by using -driver-print-jobs.

I'll look into printing a summary of the job instead. Maybe I can reuse some of the logic from -driver-print-actions here.

@modocache
Copy link
Contributor Author

The following change:

diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index beabfd5..b86706c 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -436,13 +436,11 @@ int Compilation::performJobsImpl() {
     const Job *BeganCmd = (const Job *)Context;

     if (ShowDriverTimeCompilation) {
-      llvm::SmallString<128> CmdLine;
-      llvm::raw_svector_ostream OS(CmdLine);
-      BeganCmd->printCommandLine(OS);
+      auto JobName = BeganCmd->getSource().getClassName();
       DriverTimers.insert({
         BeganCmd,
         std::unique_ptr<llvm::Timer>(
-          new llvm::Timer(OS.str(), DriverTimerGroup))
+          new llvm::Timer(JobName, DriverTimerGroup))
       });
       DriverTimers[BeganCmd]->startTimer();
     }

Results in the following output:

modocache@ubuntu:~$ swiftc -driver-time-compilation test/Driver/driver-time-compilation.swift
===-------------------------------------------------------------------------===
                            Driver Time Compilation
===-------------------------------------------------------------------------===
  Total Execution Time: 0.0000 seconds (0.0467 wall clock)

   ---Wall Time---  --- Name ---
   0.0238 ( 50.9%)  link
   0.0196 ( 42.0%)  compile
   0.0033 (  7.1%)  swift-autolink-extract
   0.0467 (100.0%)  Total

You mention above displaying something like "Compile x.swift". I think I can do that by printing a Job's InputActions when available -- although, if there are a lot of input files, the name may get pretty long.

@jrose-apple
Copy link
Contributor

Yeah, now that I think about it printing like -driver-print-actions is probably the way to go, even though in theory one Action can have multiple Jobs. (We don't use that today.) getSource is the way to jump from Job to Action.

@modocache
Copy link
Contributor Author

OK, I have something like this at the moment:

===-------------------------------------------------------------------------===
                            Driver Time Compilation
===-------------------------------------------------------------------------===
  Total Execution Time: 0.0000 seconds (0.0875 wall clock)

   ---Wall Time---  --- Name ---
   0.0245 ( 28.0%)  link /home/modocache/GitHub/tmp/Crispix/A.swift /home/modocache/GitHub/tmp/Crispix/B.swift /home/modocache/GitHub/tmp/Crispix/C.swift
   0.0211 ( 24.1%)  compile /home/modocache/GitHub/tmp/Crispix/A.swift
   0.0209 ( 23.9%)  compile /home/modocache/GitHub/tmp/Crispix/B.swift
   0.0176 ( 20.1%)  compile /home/modocache/GitHub/tmp/Crispix/C.swift
   0.0035 (  4.0%)  swift-autolink-extract /home/modocache/GitHub/tmp/Crispix/A.swift /home/modocache/GitHub/tmp/Crispix/B.swift /home/modocache/GitHub/tmp/Crispix/C.swift
   0.0875 (100.0%)  Total

Does this look good? I'll update the pull request with this soon.

@jrose-apple
Copy link
Contributor

Seems reasonable, and we can always tweak it later. Thanks, Brian!

Add an option to print the time it takes each driver task to complete.

Here's an example of the output:

```
$ swiftc -driver-time-compilation \
         -emit-library -module-name Crispix \
         Crispix/A.swift Crispix/B.swift Crispix/C.swift
===-------------------------------------------------------------------------===
                           Driver Time Compilation
===-------------------------------------------------------------------------===
  Total Execution Time: 0.0000 seconds (0.0875 wall clock)

   ---Wall Time---  --- Name ---
   0.0245 ( 28.0%)  link /path/to/Crispix/A.swift /path/to/Crispix/B.swift /path/to/Crispix/C.swift
   0.0211 ( 24.1%)  compile /path/to/Crispix/A.swift
   0.0209 ( 23.9%)  compile /path/to/Crispix/B.swift
   0.0176 ( 20.1%)  compile /path/to/Crispix/C.swift
   0.0035 (  4.0%)  swift-autolink-extract /path/to/Crispix/A.swift /path/to/Crispix/B.swift /path/to/Crispix/C.swift
   0.0875 (100.0%)  Total
```
@modocache modocache force-pushed the driver-time-compilation branch from 1529d6e to 6c92c78 Compare August 22, 2016 22:59
@modocache
Copy link
Contributor Author

I'm betting some of the C++ could be nicer, but this now produces the output I described above.

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test Linux Platform
Git Commit - 6c92c78
Test requested by - @modocache

@swift-ci
Copy link
Contributor

Build failed
Jenkins build - Swift Test OS X Platform
Git Commit - 6afc93481c4242639ad48d8f4daf050a46cc95e7
Test requested by - @modocache

@modocache
Copy link
Contributor Author

Both failures appear to be in the CI infrastructure, not the contents of the pull request.

@jrose-apple
Copy link
Contributor

Something weird happened there. Let's just try again.

@swift-ci Please test

@modocache
Copy link
Contributor Author

Looks like it's all green this time! :)

@jrose-apple jrose-apple merged commit ba8009b into swiftlang:master Aug 23, 2016
@jrose-apple
Copy link
Contributor

Thanks for the new feature, Brian!

@modocache modocache deleted the driver-time-compilation branch August 23, 2016 20:40
@modocache
Copy link
Contributor Author

You're quite welcome! I'd love to work on more of lib/Driver. Did you happen to see my email? https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20160815/002739.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants