使用 rustc_codegen_cranelift 进行调试构建

2020年11月15日 · Jynn Nelson 代表 编译器团队

什么是 rustc_codegen_cranelift

rustc_codegen_cranelift,或者简称 cg_clif,是 Rust 编译器的一个新的实验性代码生成后端。现有的后端是 LLVM,它非常擅长生成快速、高度优化的代码,但在快速编译代码方面表现不佳。 cg_clif 使用 Cranelift 项目,将提供一个快速后端,可以大大缩短编译时间,但代价是执行的优化非常少。这非常适合调试构建,并且希望 cg_clif 最终成为调试模式下的默认后端。

使用 rustc_codegen_cranelift 进行调试构建的进展如何?

有一个 重大变更提案 已经开放了一段时间,旨在将 cg_clif 作为 Rust 主仓库的一部分。最近,MCP 已被接受,编译器团队 合并rustc_cranelift_codegen 到 Rust 主 git 仓库中cg_clif 尚未与 rustup 一起分发,但这表示您现在可以在树内从源代码构建它!

如何使用 rustc_codegen_cranelift

在本节中,我将逐步介绍如何从源代码构建新的后端,然后将其用于您自己的项目。所有代码都可以复制/粘贴,并且每一步都有解释。

首先,让我们从源代码构建 cg_clif

$ git clone https://github.com/bjorn3/rustc_codegen_cranelift.git
$ ./prepare.sh
$ ./build.sh

现在,我们可以开始使用它来编译一个项目。为了演示目的,我将使用 cargo,但您可以使用 cg_clif 支持的任何 Rust 项目。

$ cd ..
$ git clone https://github.com/rust-lang/cargo/
$ cd cargo
$ ../rustc_codegen_cranelift/build/cargo.sh build
...
    Finished dev [unoptimized + debuginfo] target(s) in 49.93s

它工作了!为了比较,让我们看看等效的 LLVM 后端需要多长时间。

$ rustup install nightly-2020-10-31
$ cargo +nightly-2020-10-31 build
...
    Finished dev [unoptimized + debuginfo] target(s) in 54.64s

LLVM 的完整构建时间要长 5 秒。接下来,让我们尝试增量构建。

$ git apply <<EOF
diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs
index bccb41121..703afa754 100644
--- a/src/cargo/lib.rs
+++ b/src/cargo/lib.rs
@@ -36,8 +36,8 @@ use anyhow::Error;
 use log::debug;
 use std::fmt;
 
-pub use crate::util::errors::{InternalError, VerboseError};
 pub use crate::util::{CargoResult, CliError, CliResult, Config};
+pub use crate::util::errors::{InternalError, VerboseError};
 
 pub const CARGO_ENV: &str = "CARGO";
EOF
$ ../rustc_codegen_cranelift/build/cargo.sh build
    Finished dev [unoptimized + debuginfo] target(s) in 7.98s
$ cargo +nightly-2020-10-31 build
   Compiling cargo v0.50.0 (/home/jyn/cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 5.48s

LLVM 实际上在这里更快serde_derive 在 cranelift 下运行的时间更长,因为它没有被优化。在 cranelift 下,它花费的时间约为 14%,而在 LLVM 下花费的时间不到 3%。

树内构建

本节主要针对编译器黑客,但即使您只是感兴趣,也可以随意跟随!不建议这样构建 cg_clif 的原因是 Rust 编译器需要很长时间才能构建。

首先,下载 Rust 仓库。

$ git clone https://github.com/rust-lang/rust

现在,让我们设置构建系统以使用 cg_clif

$ cat > config.toml <<EOF
[rust]
codegen-backends = ["cranelift"]
EOF

最后,让我们运行构建。这可能需要很长时间,在某些情况下超过半小时。

$ ./x.py build

我如何提供帮助?

您不需要成为编译器开发人员即可帮助改进 cg_clif!您可以提供的最佳帮助方式是在整个生态系统中不同的 Rust crate 上测试 cg_clif。就在写这篇文章时,我发现了 两个 错误,因此还有很多工作要做。请将您发现的任何错误报告给 rustc_codegen_cranelift git 仓库

未来,我们希望将 cg_clif 与 Rustup 一起分发,如果它足够成熟,最终使其成为调试构建的默认后端。