-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Rdar 30961871 metrics mark 2 #8477
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
Rdar 30961871 metrics mark 2 #8477
Conversation
Summary: This changes the static method TimerGroup::printAllJSONValues from private to public, to match the static method TimerGroup::printAll. When trying to drive the reporting machinery by hand, the existing API is _almost_ flexible enough, but this entrypoint is required to intermix printing timers with other non-timer output. The underlying motive here is a Swift change to consolidate the collection of timers, LLVM statistics and other (non-assert-dependent) counters into JSON files, which requires a bit of manual intervention in LLVM's stat and timer output routines. See swiftlang/swift#8477 for details. Reviewers: MatzeB Reviewed By: MatzeB Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31566 llvm-svn=299371
Summary: This changes the static method TimerGroup::printAllJSONValues from private to public, to match the static method TimerGroup::printAll. When trying to drive the reporting machinery by hand, the existing API is _almost_ flexible enough, but this entrypoint is required to intermix printing timers with other non-timer output. The underlying motive here is a Swift change to consolidate the collection of timers, LLVM statistics and other (non-assert-dependent) counters into JSON files, which requires a bit of manual intervention in LLVM's stat and timer output routines. See swiftlang/swift#8477 for details. Reviewers: MatzeB Reviewed By: MatzeB Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31566 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299371 91177308-0d34-0410-b5e6-96231b3b80d8
Summary: This changes the static method TimerGroup::printAllJSONValues from private to public, to match the static method TimerGroup::printAll. When trying to drive the reporting machinery by hand, the existing API is _almost_ flexible enough, but this entrypoint is required to intermix printing timers with other non-timer output. The underlying motive here is a Swift change to consolidate the collection of timers, LLVM statistics and other (non-assert-dependent) counters into JSON files, which requires a bit of manual intervention in LLVM's stat and timer output routines. See swiftlang/swift#8477 for details. Reviewers: MatzeB Reviewed By: MatzeB Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31566 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299371 91177308-0d34-0410-b5e6-96231b3b80d8
@swift-ci please smoke test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. Some comments.
@@ -4525,7 +4525,7 @@ void swift::serialize(ModuleOrSourceFile DC, | |||
|
|||
bool hadError = withOutputFile(getContext(DC), options.OutputPath, | |||
[&](raw_ostream &out) { | |||
SharedTimer timer("Serialization (swiftmodule)"); | |||
SharedTimer timer("Serialization, swiftmodule"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really shouldn't be necessary. There's already an llvm::yaml::escape.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is, but LLVM has an assertion that the string is non-escape-requiring. Currently if you run plain-old swift with timers, asserts on, and LLVM's JSON output, it fails.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bizarre. Okay, I'll assume that was intentional. Is that at least in a doc comment somewhere? :-/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what the assertion is really trying to get at. It says what it's checking but provides no rationale (aside from the string in question being in quotes already, in JSON; maybe the author was trying to check that the string wasn't going to prematurely end the quote?)
Support/Timer.cpp
assert(!yaml::needsQuotes(Name) && "TimerGroup name needs no quotes");
assert(!yaml::needsQuotes(R.Name) && "Timer name needs no quotes");
Anyway, as with the rest of this patch, I'm on a deadline to get all this stuff working and wanted to keep it as non-invasive as possible. I talked to Matthias about the bit I did need to change in LLVM and his response was along the lines of "I'm going to rewrite all the stats-emitting stuff soon anyways", so I wouldn't spend time polishing it at this point.
stream << "stats" | ||
<< "-" << now.time_since_epoch().count() | ||
<< "-" << ProcessName | ||
<< "-" << Process::GetRandomNumber() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PID? It's already an invocation-specific folder, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
::getpid is unistd.h, not on windows. There's a a _getpid in process.h, but then I'd be adding these things to LLVM's Process.inc files and I wanted to keep the patch as small as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, hm, okay. I guess you have the primary file name in there (elsewhere).
include/swift/Basic/Statistic.h
Outdated
void performedSemanticAnalysis(CompilerInstance &instance) override; | ||
void performedSILGeneration(SILModule &module) override; | ||
void performedSILDiagnostics(SILModule &module) override; | ||
void performedSILOptimization(SILModule &module) override; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: const
(possibly on the CompilerInstance too)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are inherited methods from the FrontendObserver, I'm not able to change their type signature (am I?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, hm, I don't know. I missed that somehow, though, sorry.
|
||
friend class DependencyGraphImpl; | ||
protected: | ||
MarkTracerImpl(); | ||
MarkTracerImpl(UnifiedStatsReporter *Stats); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: please use explicit
for single-argument constructors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…not fixed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha I did fix it in one place (the subclass). Just not two places.
Brains. Sorry! Pushed ever-more-fixy fix.
include/swift/Basic/Statistic.h
Outdated
#include "llvm/ADT/Statistic.h" | ||
#include "swift/Basic/Timer.h" | ||
#include "swift/FrontendTool/FrontendTool.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a layering violation. Headers in Basic can't import things from FrontendTool. (Basic is actually the bottom layer, so they can't import anything except llvm/ADT and llvm/Support.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tricky. How best to make this interface accept callbacks of the appropriate type, then? Or should I move this class out of Basic and into something higher level (eg. FrontendTool itself? Is it appropriate for Driver to see that?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm. Driver and FrontendTool both import Frontend, but neither imports the other, and they certainly can't both import each other. In your case you might be able to get away with forward declarations for the reference types, but the dependency kind won't work.
Really I'm unhappy with the recording code living inside the stats mechanism at all. The end result is that the implementation file ends up with tons of references to the internal structure of several different subsystems. It's weird to see the Driver's DependencyKind mixed in with counting various SIL entities. I'd prefer if it were inverted and the various members incremented directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm including FrontendTool.h for the definition of FrontendObserver (so that I can implement it), not the forward declarations of its parameters.
If you'd prefer, I could make the Basic/Statistic.h interface expose the full definitions of the AlwaysOnFrontendCounters and AlwaysOnDriverCounters structs, and then implement the incrementing logic in each of Driver and Frontend (by implementing a special-purpose FrontendObserver subclass in FrontendTool itself, say). That would fix the layering violation, at least in the formal sense.
(Longer term I totally agree with you that I don't like all this information leakage between modules; but the LLVM global-static counters remain too expensive to be globally turned-on, and Matthias hasn't convinced LLVM folks of a suitable replacement strategy yet. We could implement our own global-static registry system for counters, it just seemed to me like that would be a bit overkill.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that better. I think it's the best way to satisfy the letter of the layering laws for now. I wouldn't want to make more global stats anyway because of SourceKit eventually having threads.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eh, you know, if I am going that way .. I didn't wind up relying on more than 2 methods in FrontendObserver and they're both called within FrontendTool.cpp I can avoid routing through it and just call two local, explicit count-the-things functions in FrontendTool.cpp.
44a816e
to
ecfcfe0
Compare
Updated to be simpler-and-smaller, let the modules do their own counting. |
@swift-ci please smoke test |
ecfcfe0
to
f82a842
Compare
@swift-ci please smoke test |
f82a842
to
c72621c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No further comments! (except the one nitpick)
@@ -229,7 +232,13 @@ namespace driver { | |||
<< ": " << LogJob(Cmd) << "\n"; | |||
} | |||
FinishedCommands.insert(Cmd); | |||
|
|||
if (Comp.Stats) { | |||
auto &D = Comp.Stats->getDriverCounters(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: funky indentation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops. Fixed.
c72621c
to
0245c83
Compare
@swift-ci please smoke test and merge |
Summary: This changes the static method TimerGroup::printAllJSONValues from private to public, to match the static method TimerGroup::printAll. When trying to drive the reporting machinery by hand, the existing API is _almost_ flexible enough, but this entrypoint is required to intermix printing timers with other non-timer output. The underlying motive here is a Swift change to consolidate the collection of timers, LLVM statistics and other (non-assert-dependent) counters into JSON files, which requires a bit of manual intervention in LLVM's stat and timer output routines. See swiftlang/swift#8477 for details. Reviewers: MatzeB Reviewed By: MatzeB Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31566 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299371 91177308-0d34-0410-b5e6-96231b3b80d8
Summary: This changes the static method TimerGroup::printAllJSONValues from private to public, to match the static method TimerGroup::printAll. When trying to drive the reporting machinery by hand, the existing API is _almost_ flexible enough, but this entrypoint is required to intermix printing timers with other non-timer output. The underlying motive here is a Swift change to consolidate the collection of timers, LLVM statistics and other (non-assert-dependent) counters into JSON files, which requires a bit of manual intervention in LLVM's stat and timer output routines. See swiftlang/swift#8477 for details. Reviewers: MatzeB Reviewed By: MatzeB Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31566 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299371 91177308-0d34-0410-b5e6-96231b3b80d8
Summary: This changes the static method TimerGroup::printAllJSONValues from private to public, to match the static method TimerGroup::printAll. When trying to drive the reporting machinery by hand, the existing API is _almost_ flexible enough, but this entrypoint is required to intermix printing timers with other non-timer output. The underlying motive here is a Swift change to consolidate the collection of timers, LLVM statistics and other (non-assert-dependent) counters into JSON files, which requires a bit of manual intervention in LLVM's stat and timer output routines. See swiftlang/swift#8477 for details. Reviewers: MatzeB Reviewed By: MatzeB Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31566 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299371 91177308-0d34-0410-b5e6-96231b3b80d8
This is a second attempt at #8178, taking a different tack by avoiding parseable-output altogether (the integration on the Xcode side was going to be more of a chore, and less diagnostically useful, than I'd hoped; and telemetry on it isn't going to work out this time around).
The goal here is to make a simple, fixed command-line flag that a user can put in a build setting like
OTHER_SWIFT_FLAGS="-stats-output-dir /tmp/stats"
and have all the driver and frontend invocations that follow on in their build write out all the useful stats and timers their compiler has available (consolidating several pre-existing options), putting the results in a bunch of unique and informatively-named JSON files in the provided dir. These can then be read-back by diagnostic or regression-testing tools, or bundled up and attached to performance bugs.The patch is also intended to be minimally invasive and relatively easy to port to other branches (including older compilers, for comparison testing). It does not remove any of the existing infrastructure, and in fact leans as much as possible on LLVM's existing statistic and timer classes.
It does depend on a (now-merged) LLVM change (https://reviews.llvm.org/D31566). I tried to make it have zero changes, but LLVM only makes the non-JSON manual entrypoint public, keeping the JSON one private.
rdar://30961871