Skip to content
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

Move LLVM bitcode destination #70458

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/bootstrap/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl Step for Std {
let compiler = builder.compiler(0, builder.config.build);

let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
std_cargo(builder, target, &mut cargo);
std_cargo(builder, target, compiler.stage, &mut cargo);

builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
run_cargo(
Expand Down
14 changes: 12 additions & 2 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl Step for Std {
target_deps.extend(copy_third_party_objects(builder, &compiler, target).into_iter());

let mut cargo = builder.cargo(compiler, Mode::Std, target, "build");
std_cargo(builder, target, &mut cargo);
std_cargo(builder, target, compiler.stage, &mut cargo);

builder.info(&format!(
"Building stage{} std artifacts ({} -> {})",
Expand Down Expand Up @@ -164,7 +164,7 @@ fn copy_third_party_objects(

/// Configure cargo to compile the standard library, adding appropriate env vars
/// and such.
pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, cargo: &mut Cargo) {
pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, stage: u32, cargo: &mut Cargo) {
if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") {
cargo.env("MACOSX_DEPLOYMENT_TARGET", target);
}
Expand Down Expand Up @@ -231,6 +231,16 @@ pub fn std_cargo(builder: &Builder<'_>, target: Interned<String>, cargo: &mut Ca
}
}
}

// libstd must be built with embedded bitcode so that the produced
// artifacts can be used for both LTO builds (which use bitcode) and
// non-LTO builds (which use object code).
//
// But we don't bother for the stage 0 compiler because it's never used
// with LTO.
if stage >= 1 {
cargo.rustflag("-Cembed-bitcode=yes");
}
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ impl Step for Std {

let run_cargo_rustdoc_for = |package: &str| {
let mut cargo = builder.cargo(compiler, Mode::Std, target, "rustdoc");
compile::std_cargo(builder, target, &mut cargo);
compile::std_cargo(builder, target, compiler.stage, &mut cargo);

// Keep a whitelist so we do not build internal stdlib crates, these will be
// build by the rustc step later if enabled.
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1725,7 +1725,7 @@ impl Step for Crate {
let mut cargo = builder.cargo(compiler, mode, target, test_kind.subcommand());
match mode {
Mode::Std => {
compile::std_cargo(builder, target, &mut cargo);
compile::std_cargo(builder, target, compiler.stage, &mut cargo);
}
Mode::Rustc => {
builder.ensure(compile::Rustc { compiler, target });
Expand Down
25 changes: 25 additions & 0 deletions src/doc/rustc/src/codegen-options/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,31 @@ the linker.

The default is `yes` if not specified.

## embed-bitcode

This flag controls whether or not the compiler embeds LLVM bitcode into
generated object files. It takes one of the following values:

* `y`, `yes`, `on`, or no value: enable bitcode embedding (the default).
* `n`, `no`, or `off`: disable bitcode embedding.

LLVM bitcode embedding is only needed when link-time optimization (LTO) is
nnethercote marked this conversation as resolved.
Show resolved Hide resolved
being performed, but it is enabled by default for backwards compatibility
reasons.

The use of `-C embed-bitcode=no` can significantly improve compile times and
reduce generated file sizes. For these reasons, Cargo uses `-C
embed-bitcode=no` whenever appropriate to reduce compilation costs. Likewise,
if you are building directly with `rustc` we recommend using `-C
embed-bitcode=no` whenever you are not using LTO.

If combined with `-C lto`, `-C embed-bitcode=no` will cause `rustc` to abort at
start-up, because the combination is invalid.

If combined with `-C linker-plugin-lto`, `-C embed-bitcode` (with any value)
will be ignored, because in that case generated object files contain only LLVM
bitcode, and no object code.

[option-emit]: ../command-line-arguments.md#option-emit
[option-o-optimize]: ../command-line-arguments.md#option-o-optimize
[profile-guided optimization]: ../profile-guided-optimization.md
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_codegen_llvm/back/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::str;
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind};
use rustc_codegen_ssa::back::archive::{find_library, ArchiveBuilder};
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME, RLIB_BYTECODE_EXTENSION};
use rustc_codegen_ssa::{looks_like_rust_object_file, METADATA_FILENAME};
use rustc_session::Session;
use rustc_span::symbol::Symbol;

Expand Down Expand Up @@ -129,8 +129,8 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> {
let obj_start = name.to_owned();

self.add_archive(rlib, move |fname: &str| {
// Ignore bytecode/metadata files, no matter the name.
if fname.ends_with(RLIB_BYTECODE_EXTENSION) || fname == METADATA_FILENAME {
// Ignore metadata files, no matter the name.
if fname == METADATA_FILENAME {
return true;
}

Expand Down
141 changes: 0 additions & 141 deletions src/librustc_codegen_llvm/back/bytecode.rs

This file was deleted.

46 changes: 32 additions & 14 deletions src/librustc_codegen_llvm/back/lto.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::back::bytecode::DecodedBytecode;
use crate::back::write::{
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
};
Expand All @@ -10,7 +9,7 @@ use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModul
use rustc_codegen_ssa::back::symbol_export;
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, RLIB_BYTECODE_EXTENSION};
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{FatalError, Handler};
use rustc_hir::def_id::LOCAL_CRATE;
Expand Down Expand Up @@ -111,29 +110,48 @@ fn prepare_lto(
}

let archive = ArchiveRO::open(&path).expect("wanted an rlib");
let bytecodes = archive
let obj_files = archive
.iter()
.filter_map(|child| child.ok().and_then(|c| c.name().map(|name| (name, c))))
.filter(|&(name, _)| name.ends_with(RLIB_BYTECODE_EXTENSION));
for (name, data) in bytecodes {
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, data) in obj_files {
let _timer =
cgcx.prof.generic_activity_with_arg("LLVM_lto_load_upstream_bitcode", name);
info!("adding bytecode {}", name);
let bc_encoded = data.data();

let (bc, id) = match DecodedBytecode::new(bc_encoded) {
Ok(b) => Ok((b.bytecode(), b.identifier().to_string())),
Err(e) => Err(diag_handler.fatal(&e)),
}?;
let bc = SerializedModule::FromRlib(bc);
upstream_modules.push((bc, CString::new(id).unwrap()));
info!("adding bitcode from {}", name);
match get_bitcode_slice_from_object_data(data.data()) {
Ok(bc) => {
let bc = SerializedModule::FromRlib(bc.to_vec());
upstream_modules.push((bc, CString::new(name).unwrap()));
}
Err(e) => return Err(diag_handler.fatal(&e)),
}
}
}
}

Ok((symbol_white_list, upstream_modules))
}

fn get_bitcode_slice_from_object_data(obj: &[u8]) -> Result<&[u8], String> {
let mut len = 0;
let data =
unsafe { llvm::LLVMRustGetBitcodeSliceFromObjectData(obj.as_ptr(), obj.len(), &mut len) };
if !data.is_null() {
assert!(len != 0);
let bc = unsafe { slice::from_raw_parts(data, len) };

// `bc` must be a sub-slice of `obj`.
assert!(obj.as_ptr() <= bc.as_ptr());
assert!(bc[bc.len()..bc.len()].as_ptr() < obj[obj.len()..obj.len()].as_ptr());

Ok(bc)
} else {
assert!(len == 0);
let msg = llvm::last_error().unwrap_or_else(|| "unknown LLVM error".to_string());
Err(format!("failed to get bitcode from object file for LTO ({})", msg))
}
}

/// Performs fat LTO by merging all modules into a single one and returning it
/// for further optimization.
pub(crate) fn run_fat(
Expand Down
Loading