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

Stabilize linker-plugin based LTO (aka cross-language LTO) #58057

Merged
merged 3 commits into from Feb 13, 2019

Conversation

@michaelwoerister
Copy link
Contributor

michaelwoerister commented Feb 1, 2019

This PR stabilizes linker plugin based LTO, also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making rustc emit LLVM bitcode instead of machine code, the same as clang does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various codegen and run-make tests that make sure that it keeps working.

It also works for building big projects like Firefox.

The PR makes the feature available under the -C linker-plugin-lto flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. -C linker-plugin-lto is descriptive of what it does. If someone has a better name, let me know :)

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 1, 2019

r? @estebank

(rust_highfive has picked a reviewer for you, use r? to override)

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 1, 2019

As discussed in the tracking issue, we'll ask @rust-lang/compiler to sign off on it.
@rfcbot fcp merge

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Feb 1, 2019

Team member @michaelwoerister has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and none object), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 1, 2019

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 1, 2019

Looks reasonable to me! Do you know if the way to use this is written down somewhere? I presume it's almost "just set RUSTFLAGS with this flag" but we may want to mention compatible linkers and such? (also things like LLVM version compatibility, etc)

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Feb 2, 2019

☔️ The latest upstream changes (presumably #57937) made this pull request unmergeable. Please resolve the merge conflicts.

@Centril Centril added the relnotes label Feb 3, 2019

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 5, 2019

Do you know if the way to use this is written down somewhere?

Yeah, I ran into a similar problem with path-prefix-remapping a while back. There seems to be no canonical place for documenting niche-features like these. Should I create a page on https://forge.rust-lang.org/? @rust-lang/docs might have a better suggestion.

@mark-i-m

This comment has been minimized.

Copy link
Contributor

mark-i-m commented Feb 5, 2019

The reference?

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 6, 2019

The reference looks like it's more about the language, not about the compiler.

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 6, 2019

O, I just found this: https://doc.rust-lang.org/rustc/index.html

It looks a bit unmaintained though...

@steveklabnik

This comment has been minimized.

Copy link
Member

steveklabnik commented Feb 6, 2019

It looks a bit unmaintained though...

I knocked out the basics, and we'd like to continue to expand it, but just need people to do the work, as always :)

It was created to exactly be the place for this kind of information.

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 6, 2019

OK, I'll just add a subsection for the feature. It's complicated enough to warrant its own page, I think.

@Zoxc

This comment has been minimized.

Copy link
Contributor

Zoxc commented Feb 9, 2019

@michaelwoerister Is there any mechanism to ensure matching LLVM IR versions are used?

I feel like this option should be -C lto, but that's already used for other things. It also seems to me that this doesn't have to be implemented by a plugin, so that probably shouldn't be a part of the option, unless you're actually passing a plugin path for the linker to use.

@rfcbot

This comment has been minimized.

Copy link

rfcbot commented Feb 9, 2019

🔔 This is now entering its final comment period, as per the review above. 🔔

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 11, 2019

Is there any mechanism to ensure matching LLVM IR versions are used?

What do you have in mind? Only the linker sees both versions of the LLVM IR, so don't think that rustc can do a check unfortunately.

It also seems to me that this doesn't have to be implemented by a plugin, so that probably shouldn't be a part of the option, unless you're actually passing a plugin path for the linker to use.

I'm open for suggestions regarding a different name for the command line option. I don't like -C linker-lto because that sounds weird if you know what "LTO" stands for. The name xLTO has been used for the feature by some folks but I think it's suitable for a commandline option. -C defer-lto would be kind of OK, but -C linker-plugin-lto has more useful information in it. As even LLD uses -plugin for its CLI here, I think it's fine.

@jamesmunns

This comment has been minimized.

Copy link
Member

jamesmunns commented Feb 12, 2019

Are there any plans to integrate this as a cargo flag? Or is this intended to stay as a RUSTFLAG?

This would be great to have on in most cases for embedded, especially if this would inline external assembly files as well.

Edit: specifically as a profile flag that could be set in a Cargo.toml, not a cargo CLI flag

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Feb 12, 2019

It also works for building big projects like Firefox.

Is Firefox using it to compile its jemalloc-sys fork somewhere ?

@michaelwoerister

This comment has been minimized.

Copy link
Contributor Author

michaelwoerister commented Feb 12, 2019

Are there any plans to integrate this as a cargo flag?

Not that I'm aware of. @rust-lang/cargo would have to decide about this.

Is Firefox using it to compile its jemalloc-sys fork somewhere ?

Mabye Ted knows something about this? cc @luser

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 12, 2019

@jamesmunns FWIW this unfortunately wouldn't work for external assembly files, linker-based LTO only works for code compiled by the same compiler to the same IR, such as C and Rust compiled both to LLVM IR. External assembly files are compiled directly to object files and skip the LLVM IR step, so they can't be optimized/inlined together.

I think we'll probably want to stabilize this first and then see how it plays out to figure out how to best add it to Cargo

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Feb 12, 2019

I think we'll probably want to stabilize this first and then see how it plays out to figure out how to best add it to Cargo

It might be best to add it to the cc crate first. A lot of crates use cc in their build.rs to either compile C/C++ directly, or to obtain "Makefile" options that are then passed to autoconf/automake, make, cmake, and friends.

That is, we probably want cc to detect whether the C compiler that will / should be used is the clang binary shipped with Rust, and if that's the case, then detect whether the linker is the appropriate one. If all stars align, then the cc crate should automatically use this. We probably want to be able to enforce it through some configuration option, which could then be enabled also externally e.g. via an environment variable that users and cargo could set.

@michaelwoerister michaelwoerister force-pushed the michaelwoerister:stabilize-xlto branch from 17244ab to 384f269 Feb 12, 2019


In order for this kind of LTO to work, the LLVM linker plugin must be able to
handle the LLVM bitcode produced by `rustc` and `clang`. The following table
shows known good combinations of toolchain versions.

This comment has been minimized.

@alexcrichton

alexcrichton Feb 12, 2019

Member

Could this be expanded a bit with our current defacto version policy? The general points would be:

  • For best results with this LTO, users should ensure the version of LLVM used by rustc matches the version of LLVM used by clang.
  • The compiler's version of LLVM can be reported via rustc -vV
  • The output of rustc -vV may lie slightly as we don't always use a release branch of LLVM
  • At this time we may pin to arbitrary LLVM commits in which case clang would have to be compiled manually
  • Future policy developments can happen in the future!

It may actually be best to remove the table below for now as we're pretty unlikely to add to it each release

This comment has been minimized.

@michaelwoerister

michaelwoerister Feb 12, 2019

Author Contributor

Sure, will do.

It may actually be best to remove the table below for now as we're pretty unlikely to add to it each release.

I don't know. It would be pretty good to have a table like this but I agree that it can easily go unmaintained ...

This comment has been minimized.

@alexcrichton

alexcrichton Feb 12, 2019

Member

Eh, either way's fine by me!

This comment has been minimized.

@michaelwoerister

michaelwoerister Feb 12, 2019

Author Contributor

I left the table in there for now. We can always remove it.

@jamesmunns

This comment has been minimized.

Copy link
Member

jamesmunns commented Feb 12, 2019

@alexcrichton I had some IRC discussion with @nagisa and @oli-obk, and they were of the opinion that we might be able to make this work, if instead of using external ASM files, we use external C files with inline assembly, and run that through Clang. However, none of this really matters to this PR, and once core::arch::arm or stable inline assembly (discussed at the all hands) lands, this matters much less anyway :)

The addition to Cargo at a later date SGTM, I plan to add info about this flag to the Embedded Book/Embedonomicon once this lands, as it is fairly common to rely on some external C code there as well.

Thanks all for the responses!

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 12, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:01d33016:start=1549980741696992857,finish=1549980743804666333,duration=2107673476
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
[00:19:26]    Compiling rustc_passes v0.0.0 (/checkout/src/librustc_passes)
[00:19:26]    Compiling rustc_borrowck v0.0.0 (/checkout/src/librustc_borrowck)
[00:20:19]    Compiling rustc_save_analysis v0.0.0 (/checkout/src/librustc_save_analysis)
[00:20:19]    Compiling rustc_codegen_ssa v0.0.0 (/checkout/src/librustc_codegen_ssa)
[00:20:19] error[E0407]: method `cross_lang_lto` is not a member of trait `Linker`
[00:20:19]     --> src/librustc_codegen_ssa/back/linker.rs:1210:5
[00:20:19]      |
[00:20:19] 1210 | /     fn cross_lang_lto(&mut self) {
[00:20:19]      | |_____^ not a member of trait `Linker`
[00:20:19] 
[00:20:19] 
[00:20:20] error[E0046]: not all trait items implemented, missing: `linker_plugin_lto`
[00:20:20]     --> src/librustc_codegen_ssa/back/linker.rs:1095:1
[00:20:20]      |
[00:20:20] 130  |     fn linker_plugin_lto(&mut self);
[00:20:20]      |     -------------------------------- `linker_plugin_lto` from trait
[00:20:20] ...
[00:20:20] 1095 | impl<'a> Linker for PtxLinker<'a> {
[00:20:20]      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `linker_plugin_lto` in implementation
[00:20:20] error: aborting due to 2 previous errors
[00:20:20] 
[00:20:20] Some errors occurred: E0046, E0407.
[00:20:20] For more information about an error, try `rustc --explain E0046`.
[00:20:20] For more information about an error, try `rustc --explain E0046`.
[00:20:20] error: Could not compile `rustc_codegen_ssa`.
[00:20:20] warning: build failed, waiting for other jobs to finish...
[00:20:42] error: build failed
[00:20:42] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "" "--manifest-path" "/checkout/src/rustc/Cargo.toml" "--message-format" "json"
[00:20:42] expected success, got: exit code: 101
[00:20:42] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap build
[00:20:42] Build completed unsuccessfully in 0:16:54
[00:20:42] Makefile:18: recipe for target 'all' failed
[00:20:42] make: *** [all] Error 1
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0648cb58
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 14:33:16 UTC 2019
---
travis_time:end:26a7903e:start=1549981996940294554,finish=1549981997526385583,duration=586091029
travis_fold:end:after_failure.1
travis_fold:start:after_failure.2
travis_time:start:0050f738
$ ls -lat $HOME/Library/Logs/Diagnosti/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:2502eff9
$ dmesg | grep -i kill

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 @TimNN. (Feature Requests)

@michaelwoerister michaelwoerister force-pushed the michaelwoerister:stabilize-xlto branch from 384f269 to 3733b32 Feb 12, 2019

@rust-highfive

This comment has been minimized.

Copy link
Collaborator

rust-highfive commented Feb 12, 2019

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:20685ab8:start=1549982594154840062,finish=1549982596561081686,duration=2406241624
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
[00:26:50]    Compiling rustc_passes v0.0.0 (/checkout/src/librustc_passes)
[00:27:24]    Compiling rustc_privacy v0.0.0 (/checkout/src/librustc_privacy)
[00:27:25]    Compiling rustc_save_analysis v0.0.0 (/checkout/src/librustc_save_analysis)
[00:27:25]    Compiling rustc_codegen_ssa v0.0.0 (/checkout/src/librustc_codegen_ssa)
[00:27:26] error[E0407]: method `cross_lang_lto` is not a member of trait `Linker`
[00:27:26]     --> src/librustc_codegen_ssa/back/linker.rs:1210:5
[00:27:26]      |
[00:27:26] 1210 | /     fn cross_lang_lto(&mut self) {
[00:27:26]      | |_____^ not a member of trait `Linker`
[00:27:26] 
[00:27:26] 
[00:27:26] error[E0046]: not all trait items implemented, missing: `linker_plugin_lto`
[00:27:26]     --> src/librustc_codegen_ssa/back/linker.rs:1095:1
[00:27:26]      |
[00:27:26] 130  |     fn linker_plugin_lto(&mut self);
[00:27:26]      |     -------------------------------- `linker_plugin_lto` from trait
[00:27:26] ...
[00:27:26] 1095 | impl<'a> Linker for PtxLinker<'a> {
[00:27:26]      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `linker_plugin_lto` in implementation
[00:27:26] error: aborting due to 2 previous errors
[00:27:26] 
[00:27:26] Some errors occurred: E0046, E0407.
[00:27:26] For more information about an error, try `rustc --explain E0046`.
[00:27:26] For more information about an error, try `rustc --explain E0046`.
[00:27:26] error: Could not compile `rustc_codegen_ssa`.
[00:27:26] warning: build failed, waiting for other jobs to finish...
[00:28:02] error: build failed
[00:28:02] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "" "--manifest-path" "/checkout/src/rustc/Cargo.toml" "--message-format" "json"
[00:28:02] expected success, got: exit code: 101
[00:28:02] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap build
[00:28:02] Build completed unsuccessfully in 0:17:45
[00:28:02] make: *** [all] Error 1
[00:28:02] Makefile:18: recipe for target 'all' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:209f1b34
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 15:11:30 UTC 2019

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 @TimNN. (Feature Requests)

@luser

This comment has been minimized.

Copy link
Contributor

luser commented Feb 12, 2019

It also works for building big projects like Firefox.

Is Firefox using it to compile its jemalloc-sys fork somewhere ?

I'm not 100% sure that I understand your question, but Firefox builds its own copy of jemalloc from C++ sources using our build system:
https://searchfox.org/mozilla-central/rev/00c0d068ece99717bea7475f7dc07e61f7f35984/memory/build/moz.build#23

We build a shared library (mozglue) including the jemalloc code that exports all the usual memory allocation functions as described here:
https://searchfox.org/mozilla-central/rev/00c0d068ece99717bea7475f7dc07e61f7f35984/memory/build/mozmemory_wrap.h#10

We have a GlobalAlloc impl that points Rust's allocator at those functions:
https://searchfox.org/mozilla-central/rev/00c0d068ece99717bea7475f7dc07e61f7f35984/toolkit/library/rust/shared/lib.rs#269

And we compile all of our Rust code into a static library and link it into a shared library that links against mozglue so that all allocations go through our copy of jemalloc.

So given @michaelwoerister's changes to use this feature to build Firefox everything will be LTOed, but since our jemalloc is linked into a separate shared library it won't be LTOed with our Rust code.

@gnzlbg

This comment has been minimized.

Copy link
Contributor

gnzlbg commented Feb 12, 2019

but since our jemalloc is linked into a separate shared library

My question was whether you where building all of this statically, such that jemalloc gets LTOed into Rust code, but that is not the case.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 12, 2019

r=me when this is green on CI

@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Feb 12, 2019

@bors r=alexcrichton

@bors

This comment has been minimized.

Copy link
Contributor

bors commented Feb 12, 2019

📌 Commit 3a9d171 has been approved by alexcrichton

@joshtriplett

This comment has been minimized.

Copy link
Member

joshtriplett commented Feb 12, 2019

First of all, this is awesome, and I'd love to see it happen.

Second, while I wouldn't want to block this on it, we need to take this change into account in any future designs for better ways of handling builds of hybrid C/Rust projects.

Centril added a commit to Centril/rust that referenced this pull request Feb 13, 2019

Rollup merge of rust-lang#58057 - michaelwoerister:stabilize-xlto, r=…
…alexcrichton

Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](rust-lang#49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`

Centril added a commit to Centril/rust that referenced this pull request Feb 13, 2019

Rollup merge of rust-lang#58057 - michaelwoerister:stabilize-xlto, r=…
…alexcrichton

Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](rust-lang#49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`

bors added a commit that referenced this pull request Feb 13, 2019

Auto merge of #58413 - Centril:rollup, r=Centril
Rollup of 13 pull requests

Successful merges:

 - #57693 (Doc rewording)
 - #57815 (Speed up the fast path for assert_eq! and assert_ne!)
 - #58034 (Stabilize the time_checked_add feature)
 - #58057 (Stabilize linker-plugin based LTO (aka cross-language LTO))
 - #58137 (Cleanup: rename node_id_to_type(_opt))
 - #58166 (allow shorthand syntax for deprecation reason)
 - #58196 (Add specific feature gate error for const-unstable features)
 - #58200 (fix str mutating through a ptr derived from &self)
 - #58273 (Rename rustc_errors dependency in rust 2018 crates)
 - #58289 (impl iter() for dyn Error)
 - #58387 (Disallow `auto` trait alias syntax)
 - #58404 (use Ubuntu keyserver for CloudABI ports)
 - #58405 (Remove some dead code from libcore)

Failed merges:

r? @ghost

Centril added a commit to Centril/rust that referenced this pull request Feb 13, 2019

Rollup merge of rust-lang#58057 - michaelwoerister:stabilize-xlto, r=…
…alexcrichton

Stabilize linker-plugin based LTO (aka cross-language LTO)

This PR stabilizes [linker plugin based LTO](rust-lang#49879), also known as "cross-language LTO" because it allows for doing inlining and other optimizations across language boundaries in mixed Rust/C/C++ projects.

As described in the tracking issue, it works by making `rustc` emit LLVM bitcode instead of machine code, the same as `clang` does. A linker with the proper plugin (like LLD) can then run (Thin)LTO across all modules.

The feature has been implemented over a number of pull requests and there are various [codegen](https://github.com/rust-lang/rust/blob/master/src/test/codegen/no-dllimport-w-cross-lang-lto.rs) and [run](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-clang)-[make](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto-upstream-rlibs) [tests](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/cross-lang-lto) that make sure that it keeps working.

It also works for building big projects like [Firefox](https://treeherder.mozilla.org/#/jobs?repo=try&revision=2ce2d5ddcea6fbff790503eac406954e469b2f5d).

The PR makes the feature available under the `-C linker-plugin-lto` flag. As discussed in the tracking issue it is not cross-language specific and also not LLD specific. `-C linker-plugin-lto` is descriptive of what it does. If someone has a better name, let me know `:)`

bors added a commit that referenced this pull request Feb 13, 2019

Auto merge of #58415 - Centril:rollup, r=Centril
Rollup of 12 pull requests

Successful merges:

 - #57693 (Doc rewording)
 - #57815 (Speed up the fast path for assert_eq! and assert_ne!)
 - #58034 (Stabilize the time_checked_add feature)
 - #58057 (Stabilize linker-plugin based LTO (aka cross-language LTO))
 - #58137 (Cleanup: rename node_id_to_type(_opt))
 - #58166 (allow shorthand syntax for deprecation reason)
 - #58200 (fix str mutating through a ptr derived from &self)
 - #58273 (Rename rustc_errors dependency in rust 2018 crates)
 - #58289 (impl iter() for dyn Error)
 - #58387 (Disallow `auto` trait alias syntax)
 - #58404 (use Ubuntu keyserver for CloudABI ports)
 - #58405 (Remove some dead code from libcore)

Failed merges:

r? @ghost

@bors bors merged commit 3a9d171 into rust-lang:master Feb 13, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment