Repository navigation
In JSON output, emit a directive after metadata is generated. - #60006
Conversation
|
@michaelwoerister You might be interested in this too. |
left a comment
There was a problem hiding this comment.
So I started writing a bunch of comments about the scheduling and costs and whatnot, but then I remembered that metadata files aren't object files! When rustc is producing the dylib crate type (not cdylib, "dylib") it is actually an object file which gets linked in. For --emit metadata, however, the contents don't get threaded through LLVM.
Instead the contents of foo.rmeta are available immediately after tcx.encode_metadata(), called from here (wow we have some confusing naming, nothing is written there). That metadata object returned is the raw bytes of metadata, and is threaded through all the way to the linking phase where we finally emit it to the filesystem here.
I think that we may want to move that emit_metadata function much earlier into the compilation process? Basically just after the call to write_metadata I think we can write out the rmeta file (if necessary) and not have to touch the LLVM scheduler at all.
In theory the call to encode_metadata() could be moved arbitrarily sooner in the compilation process as well and then the final metadata value is just encoded through to where we optionally create an object file for dylib crate types.
There was a problem hiding this comment.
I think we should emit a message for all artifacts, with a path to the artifact, and let Cargo pick out what it cares out of that.
Something like sccache, for example, might care more about other files.
And it's less tied to pipelining, just another general thing rustc does.
commented
Apr 17, 2019
|
☔ The latest upstream changes (presumably #60030) made this pull request unmergeable. Please resolve the merge conflicts. |
commented
Apr 17, 2019
I had a suspicion this might be true, thanks for clarifying! My next question is this: what is the metadata stuff that is happening during codegen? E.g. what are this and this for? |
commented
Apr 17, 2019
That... is a really good question! I think that may actually be legitimately dead code that can be deleted. AFAIK that just generates an empty object file which is always deleted. If a test starts failing though I could probably rationalize from the test why we need it :)
Ah so that's actually needed for the dylib crate type. For anything that doesn't produce a dylib I think it's dead code. If we're producing a dylib we compress the rmeta file, shove it into a section in the LLVM module, and then link it into the dylib itself. If we're not producing a dylib I think that's an empty LLVM module which produces an empty object file which we end up just deleting (it'd only get passed to the linker for a dylib anyway). So... I think in general those two blocks are largely dead code and/or historical artifacts! As I'm sure you've noticed, the backend here, especially the parallel part, could use with some cleanup at some point (ideally with all the new parallel query infrastructure!) |
commented
Apr 18, 2019
|
@alexcrichton: I tried removing the |
commented
Apr 18, 2019
|
Heh that'd make sense :) I suspect though that |
commented
Apr 24, 2019
AIUI, metadata generation happens at the start of code generation, which happens under Does that sound right? The complication is that there's a fair amount of complicated code under those methods, and disentangling the metadata parts is difficult. |
5c775b9 to
57d9ea0
Compare
commented
Apr 24, 2019
|
@alexcrichton: New draft code is up. It still has some |
commented
Apr 24, 2019
|
I still have to get the tests working, too. I am currently battling through |
left a comment
There was a problem hiding this comment.
Does that sound right? The complication is that there's a fair amount of complicated code under those methods, and disentangling the metadata parts is difficult.
This sounds about right yeah, but I think that a better fix might be to decouple metadata generation from all this back-end-related code. For example the dep-info output type has a check at some point (very early on) of "if enabled do it right now and maybe exit afterwards". I suspect a similar check would suffice for metadata in the sense that the only thing necessary for generating metadata contents is tcx, and after that it looks like tcx.encode_metadata() is all that's necessary.
I suspect we may even be able to practically sequence this just after tcx creation for maximal parallelism. Something like just before this line or around there (maybe inside analysis? unsure) would be fine.
In any case, separation out and detangling from everything else going on in the linking phase is probably the best bet to sequence this earlier. And this can of course always happen later, no need to finish it in this PR!
It might be better to do that in a follow-up PR, because it'll be fiddly. Landing this sooner will let you test the Cargo side.
Sounds fine by me! I'm up for whatever you find most convenient :)
57d9ea0 to
400b92f
Compare
commented
Apr 26, 2019
|
@alexcrichton: new code is up. It's now in a state that could be acceptable for landing: tests pass, and there are no
|
commented
Apr 26, 2019
|
This currently unconditionally emits the directive, I think? I think we'll probably still want to have it off by default (something required to opt-in on the CLI), and I agree that for now it's probably best to put it behind To that end I'd recommend adding a new unstable flag |
commented
Apr 26, 2019
|
Oh and for a test I think actually |
400b92f to
8515fb6
Compare
commented
Apr 26, 2019
|
@alexcrichton: I added |
20f8ac7 to
f96c964
Compare
commented
Apr 29, 2019
|
I switched to using output normalization to account for the path and filename differences on different platforms. Let's try again... @bors r=alexcrichton |
commented
Apr 29, 2019
|
📌 Commit f96c96414aef2d57107096f8055236af0c9839ba has been approved by |
commented
Apr 29, 2019
|
⌛ Testing commit f96c96414aef2d57107096f8055236af0c9839ba with merge e407efcd2f5bdbf225485e0913dc99cfdedab64b... |
commented
Apr 29, 2019
|
💔 Test failed - checks-travis |
commented
Apr 29, 2019
|
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
To implement pipelining, Cargo needs to know when metadata generation is
finished. This commit adds code to do that. Unfortunately, metadata file
writing currently occurs very late during compilation, so pipelining
won't produce a speed-up. Moving metadata file writing earlier will be a
follow-up.
The change involves splitting the existing `Emitter::emit` method in
two: `Emitter::emit_diagnostic` and `Emitter::emit_directive`.
The JSON directives look like this:
```
{"directive":"metadata file written: liba.rmeta"}
```
The functionality is behind the `-Z emit-directives` option, and also
requires `--error-format=json`.
f96c964 to
7bcb0cf
Compare
commented
Apr 29, 2019
|
Once more with feeling! @bors r=alexcrichton |
commented
Apr 29, 2019
|
📌 Commit 7bcb0cf has been approved by |
commented
Apr 29, 2019
commented
Apr 30, 2019
|
☀️ Test successful - checks-travis, status-appveyor |
To implement pipelining, Cargo needs to know when metadata generation is
finished. This is done via a new JSON "directive".
Unfortunately, metadata file writing currently occurs very late during
compilation, so pipelining won't produce a speed-up. Moving metadata
file writing earlier will be a follow-up.
r? @alexcrichton