Skip to content

Commit 2a4098c

Browse files
committed
Auto merge of #151063 - sgasho:aarch64-dist-enzyme, r=<try>
Add dist step for enzyme, including aarch64-apple-darwin try-job: dist-aarch64-apple
2 parents defdb83 + 5871afb commit 2a4098c

12 files changed

Lines changed: 117 additions & 27 deletions

File tree

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
shallow = true
4242
[submodule "src/tools/enzyme"]
4343
path = src/tools/enzyme
44-
url = https://github.com/rust-lang/enzyme.git
44+
url = https://github.com/sgasho/enzyme.git
4545
shallow = true
4646
[submodule "src/gcc"]
4747
path = src/gcc

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,14 @@ impl<'a> Linker for GccLinker<'a> {
796796
}
797797
}
798798

799+
if crate_type == CrateType::Dylib
800+
&& self.sess.target.is_like_darwin
801+
&& self.sess.opts.unstable_opts.export_llvm_symbols
802+
&& self.sess.opts.crate_name.as_deref() == Some("rustc_driver")
803+
{
804+
return;
805+
}
806+
799807
// We manually create a list of exported symbols to ensure we don't expose any more.
800808
// The object files have far more public symbols than we actually want to export,
801809
// so we hide them all here.

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2367,6 +2367,8 @@ options! {
23672367
"enable default bounds for experimental group of auto traits"),
23682368
export_executable_symbols: bool = (false, parse_bool, [TRACKED],
23692369
"export symbols from executables, as if they were dynamic libraries"),
2370+
export_llvm_symbols: bool = (false, parse_bool, [TRACKED],
2371+
"export LLVM symbols from rustc_driver on darwin"),
23702372
external_clangrt: bool = (false, parse_bool, [UNTRACKED],
23712373
"rely on user specified linker commands to find clangrt"),
23722374
extra_const_ub_checks: bool = (false, parse_bool, [TRACKED],

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,6 +1261,10 @@ pub fn rustc_cargo(
12611261
cargo.rustflag("-Zdefault-visibility=protected");
12621262
}
12631263

1264+
if builder.config.llvm_enzyme && target.contains("apple") && build_compiler.stage != 0 {
1265+
cargo.rustflag("-Zexport-llvm-symbols");
1266+
}
1267+
12641268
if is_lto_stage(build_compiler) {
12651269
match builder.config.rust_lto {
12661270
RustcLto::Thin | RustcLto::Fat => {
@@ -2292,23 +2296,13 @@ impl Step for Assemble {
22922296
builder.compiler(target_compiler.stage - 1, builder.config.host_target);
22932297

22942298
// Build enzyme
2295-
if builder.config.llvm_enzyme && !builder.config.dry_run() {
2299+
if builder.config.llvm_enzyme {
22962300
debug!("`llvm_enzyme` requested");
2297-
let enzyme_install = builder.ensure(llvm::Enzyme { target: build_compiler.host });
2298-
if let Some(llvm_config) = builder.llvm_config(builder.config.host_target) {
2299-
let llvm_version_major = llvm::get_llvm_version_major(builder, &llvm_config);
2300-
let lib_ext = std::env::consts::DLL_EXTENSION;
2301-
let libenzyme = format!("libEnzyme-{llvm_version_major}");
2302-
let src_lib =
2303-
enzyme_install.join("build/Enzyme").join(&libenzyme).with_extension(lib_ext);
2304-
let libdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host);
2305-
let target_libdir =
2306-
builder.sysroot_target_libdir(target_compiler, target_compiler.host);
2307-
let dst_lib = libdir.join(&libenzyme).with_extension(lib_ext);
2308-
let target_dst_lib = target_libdir.join(&libenzyme).with_extension(lib_ext);
2309-
builder.copy_link(&src_lib, &dst_lib, FileType::NativeLibrary);
2310-
builder.copy_link(&src_lib, &target_dst_lib, FileType::NativeLibrary);
2311-
}
2301+
let enzyme = builder.ensure(llvm::Enzyme { target: build_compiler.host });
2302+
let target_libdir =
2303+
builder.sysroot_target_libdir(target_compiler, target_compiler.host);
2304+
let target_dst_lib = target_libdir.join(enzyme.enzyme_filename());
2305+
builder.copy_link(&enzyme.enzyme_path(), &target_dst_lib, FileType::NativeLibrary);
23122306
}
23132307

23142308
if builder.config.llvm_offload && !builder.config.dry_run() {

src/bootstrap/src/core/build_steps/dist.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2717,6 +2717,55 @@ impl Step for LlvmBitcodeLinker {
27172717
}
27182718
}
27192719

2720+
/// Distributes the `enzyme` library so that it can be used by a compiler whose host
2721+
/// is `target`.
2722+
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
2723+
pub struct Enzyme {
2724+
/// Enzyme will by usable by rustc on this host.
2725+
pub target: TargetSelection,
2726+
}
2727+
2728+
impl Step for Enzyme {
2729+
type Output = Option<GeneratedTarball>;
2730+
const IS_HOST: bool = true;
2731+
2732+
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
2733+
run.alias("enzyme")
2734+
}
2735+
2736+
fn is_default_step(builder: &Builder<'_>) -> bool {
2737+
builder.config.llvm_enzyme
2738+
}
2739+
2740+
fn make_run(run: RunConfig<'_>) {
2741+
run.builder.ensure(Enzyme { target: run.target });
2742+
}
2743+
2744+
fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
2745+
// This prevents Enzyme from being built for "dist"
2746+
// or "install" on the stable/beta channels. It is not yet stable and
2747+
// should not be included.
2748+
if !builder.build.unstable_features() {
2749+
return None;
2750+
}
2751+
2752+
let target = self.target;
2753+
2754+
let enzyme = builder.ensure(llvm::Enzyme { target });
2755+
2756+
let target_libdir = format!("lib/rustlib/{}/lib", target.triple);
2757+
2758+
// Prepare the image directory
2759+
let mut tarball = Tarball::new(builder, "enzyme", &target.triple);
2760+
tarball.set_overlay(OverlayKind::Enzyme);
2761+
tarball.is_preview(true);
2762+
2763+
tarball.add_file(enzyme.enzyme_path(), target_libdir, FileType::NativeLibrary);
2764+
2765+
Some(tarball.generate())
2766+
}
2767+
}
2768+
27202769
/// Tarball intended for internal consumption to ease rustc/std development.
27212770
///
27222771
/// Should not be considered stable by end users.

src/bootstrap/src/core/build_steps/llvm.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use std::{env, fs};
1717
use build_helper::exit;
1818
use build_helper::git::PathFreshness;
1919

20+
use crate::core::build_steps::llvm;
2021
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step, StepMetadata};
2122
use crate::core::config::{Config, TargetSelection};
2223
use crate::utils::build_stamp::{BuildStamp, generate_smart_stamp_hash};
@@ -1077,13 +1078,28 @@ impl Step for OmpOffload {
10771078
}
10781079
}
10791080

1081+
#[derive(Clone)]
1082+
pub struct BuiltEnzyme {
1083+
/// Path to the libEnzyme dylib.
1084+
enzyme: PathBuf,
1085+
}
1086+
1087+
impl BuiltEnzyme {
1088+
pub fn enzyme_path(&self) -> PathBuf {
1089+
self.enzyme.clone()
1090+
}
1091+
pub fn enzyme_filename(&self) -> String {
1092+
self.enzyme.file_name().unwrap().to_str().unwrap().to_owned()
1093+
}
1094+
}
1095+
10801096
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
10811097
pub struct Enzyme {
10821098
pub target: TargetSelection,
10831099
}
10841100

10851101
impl Step for Enzyme {
1086-
type Output = PathBuf;
1102+
type Output = BuiltEnzyme;
10871103
const IS_HOST: bool = true;
10881104

10891105
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -1095,16 +1111,16 @@ impl Step for Enzyme {
10951111
}
10961112

10971113
/// Compile Enzyme for `target`.
1098-
fn run(self, builder: &Builder<'_>) -> PathBuf {
1114+
fn run(self, builder: &Builder<'_>) -> Self::Output {
10991115
builder.require_submodule(
11001116
"src/tools/enzyme",
11011117
Some("The Enzyme sources are required for autodiff."),
11021118
);
1119+
let target = self.target;
1120+
11031121
if builder.config.dry_run() {
1104-
let out_dir = builder.enzyme_out(self.target);
1105-
return out_dir;
1122+
return BuiltEnzyme { enzyme: builder.config.tempdir().join("enzyme-dryrun") };
11061123
}
1107-
let target = self.target;
11081124

11091125
let LlvmResult { host_llvm_config, llvm_cmake_dir } = builder.ensure(Llvm { target });
11101126

@@ -1120,6 +1136,12 @@ impl Step for Enzyme {
11201136
let out_dir = builder.enzyme_out(target);
11211137
let stamp = BuildStamp::new(&out_dir).with_prefix("enzyme").add_stamp(smart_stamp_hash);
11221138

1139+
let llvm_version_major = llvm::get_llvm_version_major(builder, &host_llvm_config);
1140+
let lib_ext = std::env::consts::DLL_EXTENSION;
1141+
let libenzyme = format!("libEnzyme-{llvm_version_major}");
1142+
let build_dir = out_dir.join("lib");
1143+
let dylib = build_dir.join(&libenzyme).with_extension(lib_ext);
1144+
11231145
trace!("checking build stamp to see if we need to rebuild enzyme artifacts");
11241146
if stamp.is_up_to_date() {
11251147
trace!(?out_dir, "enzyme build artifacts are up to date");
@@ -1133,7 +1155,7 @@ impl Step for Enzyme {
11331155
stamp.path().display()
11341156
));
11351157
}
1136-
return out_dir;
1158+
return BuiltEnzyme { enzyme: dylib };
11371159
}
11381160

11391161
if !builder.config.dry_run() && !llvm_cmake_dir.is_dir() {
@@ -1149,7 +1171,6 @@ impl Step for Enzyme {
11491171
let _time = helpers::timeit(builder);
11501172
t!(fs::create_dir_all(&out_dir));
11511173

1152-
builder.config.update_submodule("src/tools/enzyme");
11531174
let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/"));
11541175
// Enzyme devs maintain upstream compatibility, but only fix deprecations when they are about
11551176
// to turn into a hard error. As such, Enzyme generates various warnings which could make it
@@ -1178,8 +1199,18 @@ impl Step for Enzyme {
11781199

11791200
cfg.build();
11801201

1202+
// At this point, `out_dir` should contain the built libEnzyme-<LLVM-version>.<dylib-ext>
1203+
// file.
1204+
if !dylib.exists() {
1205+
eprintln!(
1206+
"`{libenzyme}` not found in `{}`. Either the build has failed or Enzyme was built with a wrong version of LLVM",
1207+
build_dir.display()
1208+
);
1209+
exit!(1);
1210+
}
1211+
11811212
t!(stamp.write());
1182-
out_dir
1213+
BuiltEnzyme { enzyme: dylib }
11831214
}
11841215
}
11851216

src/bootstrap/src/core/builder/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ impl<'a> Builder<'a> {
980980
dist::LlvmTools,
981981
dist::LlvmBitcodeLinker,
982982
dist::RustDev,
983+
dist::Enzyme,
983984
dist::Bootstrap,
984985
dist::Extended,
985986
// It seems that PlainSourceTarball somehow changes how some of the tools

src/bootstrap/src/utils/tarball.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub(crate) enum OverlayKind {
2828
RustcCodegenGcc,
2929
Gcc,
3030
LlvmBitcodeLinker,
31+
Enzyme,
3132
}
3233

3334
impl OverlayKind {
@@ -37,6 +38,7 @@ impl OverlayKind {
3738
OverlayKind::Llvm => {
3839
&["src/llvm-project/llvm/LICENSE.TXT", "src/llvm-project/llvm/README.txt"]
3940
}
41+
OverlayKind::Enzyme => &["src/tools/enzyme/LICENSE", "src/tools/enzyme/Readme.md"],
4042
OverlayKind::Cargo => &[
4143
"src/tools/cargo/README.md",
4244
"src/tools/cargo/LICENSE-MIT",
@@ -111,6 +113,7 @@ impl OverlayKind {
111113
OverlayKind::RustcCodegenGcc => builder.rust_version(),
112114
OverlayKind::LlvmBitcodeLinker => builder.rust_version(),
113115
OverlayKind::Gcc => builder.rust_version(),
116+
OverlayKind::Enzyme => builder.rust_version(),
114117
}
115118
}
116119
}

src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ ENV RUST_CONFIGURE_ARGS \
9191
--set llvm.thin-lto=true \
9292
--set llvm.ninja=false \
9393
--set llvm.libzstd=true \
94+
--set llvm.enzyme=true \
9495
--set rust.jemalloc \
9596
--set rust.bootstrap-override-lld=true \
9697
--set rust.lto=thin \

src/ci/github-actions/jobs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ auto:
486486
--enable-full-tools
487487
--enable-sanitizers
488488
--enable-profiler
489+
--set llvm.enzyme=true
489490
--set rust.jemalloc
490491
--set rust.lto=thin
491492
--set rust.codegen-units=1

0 commit comments

Comments
 (0)