Skip to content

Commit

Permalink
Always generated object code for #![no_builtins]
Browse files Browse the repository at this point in the history
This commit updates the code generation for `#![no_builtins]` to always
produce object files instead of conditionally respecting
`-Clinker-plugin-lto` and sometimes producing bitcode. This is intended
to address rust-lang/cargo#8239.

The issue at hand here is that Cargo has tried to get "smarter" about
codegen in whole crate graph scenarios. When LTO is enabled it attempts
to avoid codegen on as many crates as possible, opting to pass
`-Clinker-plugin-lto` where it can to only generate bitcode. When this
is combined with `-Zbuild-std`, however, it means that
`compiler-builtins` only generates LLVM bitcode instead of object files.
Rustc's own LTO passes then explicitly skip `compiler-builtins` (because
it wouldn't work anyway) which means that LLVM bitcode gets sent to the
linker, which chokes most of the time.

The fix in this PR is to not actually respect `-Clinker-plugin-lto` for
`#![no_builtins]` crates. These crates, even if slurped up by the linker
rather than rustc, will not work with LTO. They define symbols which are
only referenced as part of codegen, so LTO's aggressive internalization
would trivially remove the symbols only to have the linker realize later
that the symbol is undefined. Since pure-bitcode never makes sense for
these libraries, the `-Clinker-plugin-lto` flag is silently ignored.
  • Loading branch information
alexcrichton committed May 18, 2020
1 parent 9e2a6a2 commit cc91041
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/librustc_codegen_ssa/back/write.rs
Expand Up @@ -142,8 +142,22 @@ impl ModuleConfig {
let emit_obj = if !should_emit_obj {
EmitObj::None
} else if sess.target.target.options.obj_is_bitcode
|| sess.opts.cg.linker_plugin_lto.enabled()
|| (sess.opts.cg.linker_plugin_lto.enabled() && !no_builtins)
{
// This case is selected if the target uses objects as bitcode, or
// if linker plugin LTO is enabled. In the linker plugin LTO case
// the assumption is that the final link-step will read the bitcode
// and convert it to object code. This may be done by either the
// native linker or rustc itself.
//
// Note, however, that the linker-plugin-lto requested here is
// explicitly ignored for `#![no_builtins]` crates. These crates are
// specifically ignored by rustc's LTO passes and wouldn't work if
// loaded into the linker. These crates define symbols that LLVM
// lowers intrinsics to, and these symbol dependencies aren't known
// until after codegen. As a result any crate marked
// `#![no_builtins]` is assumed to not participate in LTO and
// instead goes on to generate object code.
EmitObj::Bitcode
} else if need_bitcode_in_object(sess) {
EmitObj::ObjectCode(BitcodeSection::Full)
Expand Down

0 comments on commit cc91041

Please sign in to comment.