-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
msvc: Get codegen-units working #26869
Conversation
r? @pcwalton (rust_highfive has picked a reviewer for you, use r? to override) |
d084b21
to
1bfd21f
Compare
Did you test this on all the platforms? There were a lot of subtle linking bugs the first time around, and testing on the bots does not currently test codegen-units. |
This passes the test suite on 64-bit linux, but it looks like we do have a bunch of codegen-units tests? The |
It would be good to know that we can bootstrap with codegen-units=4 on Linux and OSX, I think the full bootstrap exercises a bunch of code paths the tests miss |
This commit alters the implementation of multiple codegen units slightly to be compatible with the MSVC linker. Currently the implementation will take the N object files created by each codegen unit and will run `ld -r` to create a new object file which is then passed along. The MSVC linker, however, is not able to do this operation. The compiler will now no longer attempt to assemble object files together but will instead just pass through all the object files as usual. This implies that rlibs may not contain more than one object file (if the library is compiled with more than one codegen unit) and the output of `-C save-temps` will have changed slightly as object files with the extension `0.o` will not be renamed to `o` unless requested otherwise.
1bfd21f
to
6987d50
Compare
Do you know how big an effect on compile times this will have? I'm wondering if it is worth keeping around both paths so we don't affect compile times where we don't need to. (I imagine it is not worth the extra complexity, but if the effect is enormous...) |
@bors: r+ |
📌 Commit 6987d50 has been approved by |
If you create a "hello world" dylib this commit increases the time from 200ms to 290ms, the breakdown of the timings as:
I do think that creating dylibs isn't exactly common, but this is definitely unfortunate. I'm hoping that we can stop shelling out to So this'll definitely slow us down now, but hopefully we can make it up in the future! Also unfortunately I don't think there's a case where we can avoid these extra copies on a dylib b/c they're technically needed for correctness (to ensure that all code makes it into the dylib). Another possible route in the future for improvement is to separate the notion of an intermediate dylib and a final dylib (e.g. a dylib to be used again in Rust and a dylib to be used in C). If we're creating a dylib to be used in C we don't need to do any of these alterations because we want the linker to eliminate as much as possible. Unfortunately we don't know which case is which, so we have to assume they're all intermediate libs in which case everything is needed. |
⌛ Testing commit 6987d50 with merge 0598375... |
💔 Test failed - auto-mac-32-opt |
This commit starts passing the `--whole-archive` flag (`-force_load` on OSX) to the linker when linking rlibs into dylibs. The primary purpose of this commit is to ensure that the linker doesn't strip out objects from an archive when creating a dynamic library. Information on how this can go wrong can be found in issues rust-lang#14344 and rust-lang#25185. The unfortunate part about passing this flag to the linker is that we have to preprocess the rlib to remove the metadata and compressed bytecode found within. This means that creating a dylib will now take longer to link as we've got to copy around the input rlibs to a temporary location, modify them, and then invoke the linker. This isn't done for executables, however, so the "hello world" compile time is not affected. This fix was instigated because of the previous commit where rlibs may not contain multiple object files instead of one due to codegen units being greater than one. That change prevented the main distribution from being compiled with more than one codegen-unit and this commit fixes that. Closes rust-lang#14344 Closes rust-lang#25185
6987d50
to
9bc8e6d
Compare
This commit alters the implementation of multiple codegen units slightly to be compatible with the MSVC linker. Currently the implementation will take the N object files created by each codegen unit and will run `ld -r` to create a new object file which is then passed along. The MSVC linker, however, is not able to do this operation. The compiler will now no longer attempt to assemble object files together but will instead just pass through all the object files as usual. This implies that rlibs may not contain more than one object file (if the library is compiled with more than one codegen unit) and the output of `-C save-temps` will have changed slightly as object files with the extension `0.o` will not be renamed to `o` unless requested otherwise.
NB: This was a breaking change for Servo. Please put this in a release note because we may not be the only ones to be broken because of it. |
This commit alters the implementation of multiple codegen units slightly to be
compatible with the MSVC linker. Currently the implementation will take the N
object files created by each codegen unit and will run
ld -r
to create a newobject file which is then passed along. The MSVC linker, however, is not able to
do this operation.
The compiler will now no longer attempt to assemble object files together but
will instead just pass through all the object files as usual. This implies that
rlibs may not contain more than one object file (if the library is compiled with
more than one codegen unit) and the output of
-C save-temps
will have changedslightly as object files with the extension
0.o
will not be renamed too
unless requested otherwise.