Skip to content

[do not merge] Try building the compiler with ThinLTO #68879

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

Closed
wants to merge 9 commits into from
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
4 changes: 2 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
url = https://github.com/rust-lang/edition-guide.git
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/rust-lang/llvm-project.git
branch = rustc/9.0-2019-12-19
url = https://github.com/nikic/llvm-project.git
branch = rustc/10.0-2020-01-18
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git
5 changes: 5 additions & 0 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,11 @@
# rustc to execute.
#lld = false

# Indicates whether LLD will be used to link Rust crates during bootstrap on
# supported platforms. The LLD from the bootstrap distribution will be used
# and not the LLD compiled during the bootstrap.
#use-lld = false

# Indicates whether some LLVM tools, like llvm-objdump, will be made available in the
# sysroot.
#llvm-tools = false
Expand Down
5 changes: 5 additions & 0 deletions src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ fn main() {
cmd.arg(format!("-Clinker={}", host_linker));
}

// Override linker flavor if necessary.
if let Ok(host_linker_flavor) = env::var("RUSTC_HOST_LINKER_FLAVOR") {
cmd.arg(format!("-Clinker-flavor={}", host_linker_flavor));
}

if let Ok(s) = env::var("RUSTC_HOST_CRT_STATIC") {
if s == "true" {
cmd.arg("-C").arg("target-feature=+crt-static");
Expand Down
32 changes: 28 additions & 4 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ impl<'a> Builder<'a> {
cmd.env_remove("MAKEFLAGS");
cmd.env_remove("MFLAGS");

if let Some(linker) = self.linker(compiler.host) {
if let Some(linker) = self.linker(compiler.host, true) {
cmd.env("RUSTC_TARGET_LINKER", linker);
}
cmd
Expand Down Expand Up @@ -946,10 +946,31 @@ impl<'a> Builder<'a> {
}
}

if let Some(host_linker) = self.linker(compiler.host) {
// FIXME: Don't use LLD if we're compiling libtest, since it fails to link it.
// See https://github.com/rust-lang/rust/issues/68647.
let can_use_lld = mode != Mode::Std;

// FIXME: The beta compiler doesn't pick the `lld-link` flavor for `*-pc-windows-msvc`
// Remove `RUSTC_HOST_LINKER_FLAVOR` when this is fixed
let lld_linker_flavor = |linker: &Path, target: Interned<String>| {
compiler.stage == 0
&& linker.file_name() == Some(OsStr::new("rust-lld"))
&& target.contains("pc-windows-msvc")
};

if let Some(host_linker) = self.linker(compiler.host, can_use_lld) {
if lld_linker_flavor(host_linker, compiler.host) {
cargo.env("RUSTC_HOST_LINKER_FLAVOR", "lld-link");
}

cargo.env("RUSTC_HOST_LINKER", host_linker);
}
if let Some(target_linker) = self.linker(target) {

if let Some(target_linker) = self.linker(target, can_use_lld) {
if lld_linker_flavor(target_linker, target) {
rustflags.arg("-Clinker-flavor=lld-link");
}

let target = crate::envify(&target);
cargo.env(&format!("CARGO_TARGET_{}_LINKER", target), target_linker);
}
Expand Down Expand Up @@ -1047,6 +1068,9 @@ impl<'a> Builder<'a> {
}

if let Mode::Rustc | Mode::Codegen = mode {
if stage > 0 {
rustflags.arg("-Clto=thin");
}
rustflags.arg("-Zunstable-options");
rustflags.arg("-Wrustc::internal");
}
Expand Down Expand Up @@ -1189,7 +1213,7 @@ impl<'a> Builder<'a> {
// When we build Rust dylibs they're all intended for intermediate
// usage, so make sure we pass the -Cprefer-dynamic flag instead of
// linking all deps statically into the dylib.
if let Mode::Std | Mode::Rustc | Mode::Codegen = mode {
if let Mode::Std = mode {
rustflags.arg("-Cprefer-dynamic");
}

Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ pub struct Config {
pub llvm_use_linker: Option<String>,
pub llvm_allow_old_toolchain: Option<bool>,

pub use_lld: bool,
pub lld_enabled: bool,
pub lldb_enabled: bool,
pub llvm_tools_enabled: bool,
Expand Down Expand Up @@ -321,6 +322,7 @@ struct Rust {
save_toolstates: Option<String>,
codegen_backends: Option<Vec<String>>,
lld: Option<bool>,
use_lld: Option<bool>,
llvm_tools: Option<bool>,
lldb: Option<bool>,
deny_warnings: Option<bool>,
Expand Down Expand Up @@ -565,6 +567,7 @@ impl Config {
if let Some(true) = rust.incremental {
config.incremental = true;
}
set(&mut config.use_lld, rust.use_lld);
set(&mut config.lld_enabled, rust.lld);
set(&mut config.lldb_enabled, rust.lldb);
set(&mut config.llvm_tools_enabled, rust.llvm_tools);
Expand Down
16 changes: 14 additions & 2 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,10 @@ pub struct Build {
hosts: Vec<Interned<String>>,
targets: Vec<Interned<String>>,

// Stage 0 (downloaded) compiler and cargo or their local rust equivalents
// Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
initial_rustc: PathBuf,
initial_cargo: PathBuf,
initial_lld: PathBuf,

// Runtime state filled in later on
// C/C++ compilers and archiver for all targets
Expand Down Expand Up @@ -343,9 +344,18 @@ impl Build {
// we always try to use git for LLVM builds
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));

let initial_sysroot = config.initial_rustc.parent().unwrap().parent().unwrap();
let initial_lld = initial_sysroot
.join("lib")
.join("rustlib")
.join(config.build)
.join("bin")
.join("rust-lld");

let mut build = Build {
initial_rustc: config.initial_rustc.clone(),
initial_cargo: config.initial_cargo.clone(),
initial_lld,
local_rebuild: config.local_rebuild,
fail_fast: config.cmd.fail_fast(),
doc_tests: config.cmd.doc_tests(),
Expand Down Expand Up @@ -810,7 +820,7 @@ impl Build {
}

/// Returns the path to the linker for the given target if it needs to be overridden.
fn linker(&self, target: Interned<String>) -> Option<&Path> {
fn linker(&self, target: Interned<String>, can_use_lld: bool) -> Option<&Path> {
if let Some(linker) = self.config.target_config.get(&target).and_then(|c| c.linker.as_ref())
{
Some(linker)
Expand All @@ -819,6 +829,8 @@ impl Build {
&& !target.contains("msvc")
{
Some(self.cc(target))
} else if can_use_lld && self.config.use_lld && self.build == target {
Some(&self.initial_lld)
} else {
None
}
Expand Down
6 changes: 4 additions & 2 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ impl Step for RustdocTheme {
.env("RUSTDOC_REAL", builder.rustdoc(self.compiler))
.env("RUSTDOC_CRATE_VERSION", builder.rust_version())
.env("RUSTC_BOOTSTRAP", "1");
if let Some(linker) = builder.linker(self.compiler.host) {
if let Some(linker) = builder.linker(self.compiler.host, true) {
cmd.env("RUSTC_TARGET_LINKER", linker);
}
try_run(builder, &mut cmd);
Expand Down Expand Up @@ -1035,7 +1035,7 @@ impl Step for Compiletest {
flags.push("-Zunstable-options".to_string());
flags.push(builder.config.cmd.rustc_args().join(" "));

if let Some(linker) = builder.linker(target) {
if let Some(linker) = builder.linker(target, false) {
cmd.arg("--linker").arg(linker);
}

Expand Down Expand Up @@ -1139,6 +1139,8 @@ impl Step for Compiletest {
let llvm_config = builder.ensure(native::Llvm { target: builder.config.build });
if !builder.config.dry_run {
let llvm_version = output(Command::new(&llvm_config).arg("--version"));
// Remove trailing newline from llvm-config output.
let llvm_version = llvm_version.trim_end();
cmd.arg("--llvm-version").arg(llvm_version);
}
if !builder.is_rust_llvm(target) {
Expand Down
62 changes: 5 additions & 57 deletions src/ci/azure-pipelines/try.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,60 +14,8 @@ jobs:
- template: steps/run.yml
strategy:
matrix:
dist-x86_64-linux: {}
dist-x86_64-linux-alt:
IMAGE: dist-x86_64-linux

# The macOS and Windows builds here are currently disabled due to them not being
# overly necessary on `try` builds. We also don't actually have anything that
# consumes the artifacts currently. Perhaps one day we can reenable, but for now
# it helps free up capacity on Azure.
# - job: macOS
# timeoutInMinutes: 600
# pool:
# vmImage: macos-10.13
# steps:
# - template: steps/run.yml
# strategy:
# matrix:
# dist-x86_64-apple:
# SCRIPT: ./x.py dist
# RUST_CONFIGURE_ARGS: --target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc
# DEPLOY: 1
# RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
# MACOSX_DEPLOYMENT_TARGET: 10.7
# NO_LLVM_ASSERTIONS: 1
# NO_DEBUG_ASSERTIONS: 1
# DIST_REQUIRE_ALL_TOOLS: 1
#
# dist-x86_64-apple-alt:
# SCRIPT: ./x.py dist
# RUST_CONFIGURE_ARGS: --enable-extended --enable-profiler --set rust.jemalloc
# DEPLOY_ALT: 1
# RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
# MACOSX_DEPLOYMENT_TARGET: 10.7
# NO_LLVM_ASSERTIONS: 1
# NO_DEBUG_ASSERTIONS: 1
#
# - job: Windows
# timeoutInMinutes: 600
# pool:
# vmImage: 'vs2017-win2016'
# steps:
# - template: steps/run.yml
# strategy:
# matrix:
# dist-x86_64-msvc:
# RUST_CONFIGURE_ARGS: >
# --build=x86_64-pc-windows-msvc
# --target=x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
# --enable-full-tools
# --enable-profiler
# SCRIPT: python x.py dist
# DIST_REQUIRE_ALL_TOOLS: 1
# DEPLOY: 1
#
# dist-x86_64-msvc-alt:
# RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
# SCRIPT: python x.py dist
# DEPLOY_ALT: 1
dist-various-2: {}
armhf-gnu: {}
arm-android: {}
dist-s390x-linux: {}
wasm32: {}
2 changes: 1 addition & 1 deletion src/librustc_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2018"
[lib]
name = "rustc_driver"
path = "lib.rs"
crate-type = ["dylib"]
crate-type = ["rlib"]

[dependencies]
lazy_static = "1.0"
Expand Down
2 changes: 1 addition & 1 deletion src/llvm-project
Submodule llvm-project updated 27721 files
6 changes: 5 additions & 1 deletion src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ extern "C" void LLVMInitializePasses() {
}

extern "C" void LLVMTimeTraceProfilerInitialize() {
#if LLVM_VERSION_GE(9, 0)
#if LLVM_VERSION_GE(10, 0)
timeTraceProfilerInitialize(
/* TimeTraceGranularity */ 0,
/* ProcName */ "rustc");
#elif LLVM_VERSION_GE(9, 0)
timeTraceProfilerInitialize();
#endif
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/codegen/issue-45222.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// compile-flags: -O
// ignore-debug: the debug assertions get in the way
// Ignored due to a codegen regression in LLVM 10, see https://bugs.llvm.org/show_bug.cgi?id=44461.
// ignore-llvm-version: 10.0

#![crate_type = "lib"]

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
"data-layout": "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128",
"linker-flavor": "gcc",
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"pre-link-args": {"gcc": ["-m64"]},
"data-layout": "e-m:e-i64:64-f80:128-n8:16:32:64-S128",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"linker-flavor": "gcc",
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "little",
Expand Down
27 changes: 21 additions & 6 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ impl EarlyProps {
return true;
}
if let Some(ref actual_version) = config.llvm_version {
let actual_version = version_to_int(actual_version);
if line.starts_with("min-llvm-version") {
let min_version = line
.trim_end()
Expand All @@ -199,7 +200,7 @@ impl EarlyProps {
.expect("Malformed llvm version directive");
// Ignore if actual version is smaller the minimum required
// version
&actual_version[..] < min_version
actual_version < version_to_int(min_version)
} else if line.starts_with("min-system-llvm-version") {
let min_version = line
.trim_end()
Expand All @@ -208,7 +209,7 @@ impl EarlyProps {
.expect("Malformed llvm version directive");
// Ignore if using system LLVM and actual version
// is smaller the minimum required version
config.system_llvm && &actual_version[..] < min_version
config.system_llvm && actual_version < version_to_int(min_version)
} else if line.starts_with("ignore-llvm-version") {
// Syntax is: "ignore-llvm-version <version1> [- <version2>]"
let range_components = line
Expand All @@ -219,15 +220,15 @@ impl EarlyProps {
.take(3) // 3 or more = invalid, so take at most 3.
.collect::<Vec<&str>>();
match range_components.len() {
1 => &actual_version[..] == range_components[0],
1 => actual_version == version_to_int(range_components[0]),
2 => {
let v_min = range_components[0];
let v_max = range_components[1];
let v_min = version_to_int(range_components[0]);
let v_max = version_to_int(range_components[1]);
if v_max < v_min {
panic!("Malformed LLVM version range: max < min")
}
// Ignore if version lies inside of range.
&actual_version[..] >= v_min && &actual_version[..] <= v_max
actual_version >= v_min && actual_version <= v_max
}
_ => panic!("Malformed LLVM version directive"),
}
Expand All @@ -238,6 +239,20 @@ impl EarlyProps {
false
}
}

fn version_to_int(version: &str) -> u32 {
let version_without_suffix = version.split('-').next().unwrap();
let components: Vec<u32> = version_without_suffix
.split('.')
.map(|s| s.parse().expect("Malformed version component"))
.collect();
match components.len() {
1 => components[0] * 10000,
2 => components[0] * 10000 + components[1] * 100,
3 => components[0] * 10000 + components[1] * 100 + components[2],
_ => panic!("Malformed version"),
}
}
}
}

Expand Down