From 5edaec6c970c92f5613021032790ea65037014ca Mon Sep 17 00:00:00 2001 From: George Burgess IV Date: Tue, 2 Mar 2021 15:50:09 -0800 Subject: [PATCH 1/5] add support for building outlined aarch64 intrinsics llvm/llvm-project@a4ac434c47434d80bca54bab96f295ed4e972cc6 saw the addition of out-of-line aarch64 atomic intrinsics. LLVM will sometimes emit these, so we need to ensure they're included in Rust's compiler-rt. --- library/compiler-builtins/build.rs | 71 +++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/library/compiler-builtins/build.rs b/library/compiler-builtins/build.rs index 701c4d4950b0..2ff6443d7dea 100644 --- a/library/compiler-builtins/build.rs +++ b/library/compiler-builtins/build.rs @@ -81,7 +81,7 @@ mod c { use std::collections::BTreeMap; use std::env; - use std::path::PathBuf; + use std::path::{Path, PathBuf}; struct Sources { // SYMBOL -> PATH TO SOURCE @@ -489,7 +489,20 @@ mod c { // use of that macro in lib/builtins/int_util.h in compiler-rt. cfg.flag_if_supported(&format!("-ffile-prefix-map={}=.", root.display())); + // Include out-of-line atomics for aarch64, which are all generated by supplying different + // sets of flags to the same source file. let src_dir = root.join("lib/builtins"); + if target_arch == "aarch64" { + let atomics_libs = build_aarch64_out_of_line_atomics_libraries(&src_dir, cfg); + if !atomics_libs.is_empty() { + for library in atomics_libs { + cfg.object(library); + } + // Some run-time CPU feature detection is necessary, as well. + sources.extend(&[("__aarch64_have_lse_atomics", "cpu_model.c")]); + } + } + for (sym, src) in sources.map.iter() { let src = src_dir.join(src); cfg.file(&src); @@ -499,4 +512,60 @@ mod c { cfg.compile("libcompiler-rt.a"); } + + fn build_aarch64_out_of_line_atomics_libraries( + builtins_dir: &Path, + cfg: &cc::Build, + ) -> Vec { + // NOTE: because we're recompiling the same source file in N different ways, building + // serially is necessary. If we want to lift this restriction, we can either: + // - create symlinks to lse.S and build those_(though we'd still need to pass special + // #define-like flags to each of these), or + // - synthesizing tiny .S files in out/ with the proper #defines, which ultimately #include + // lse.S. + // That said, it's unclear how useful this added complexity will be, so just do the simple + // thing for now. + let outlined_atomics_file = builtins_dir.join("aarch64/lse.S"); + + // A stable release hasn't been made with lse.S yet. Until we pick that up, do nothing. + if !outlined_atomics_file.exists() { + return vec![]; + } + + println!("cargo:rerun-if-changed={}", outlined_atomics_file.display()); + let out_dir: PathBuf = env::var("OUT_DIR").unwrap().into(); + + // Ideally, this would be a Vec of object files, but cc doesn't make it *entirely* + // trivial to build an individual object. + let mut atomics_libraries = Vec::new(); + for instruction_type in &["cas", "cwp", "ldadd", "ldclr", "ldeor", "ldset"] { + for size in &[1, 2, 4, 8, 16] { + if *size == 16 && *instruction_type != "cas" { + continue; + } + + for (model_number, model_name) in + &[(1, "relax"), (2, "acq"), (3, "rel"), (4, "acq_rel")] + { + let library_name = format!( + "liboutline_atomic_helper_{}_{}_{}.a", + instruction_type, size, model_name + ); + let sym = format!("__aarch64_{}{}_{}", instruction_type, size, model_name); + let mut cfg = cfg.clone(); + + cfg.include(&builtins_dir) + .define(&format!("L_{}", instruction_type), None) + .define("SIZE", size.to_string().as_str()) + .define("MODEL", model_number.to_string().as_str()) + .file(&outlined_atomics_file); + cfg.compile(&library_name); + + atomics_libraries.push(out_dir.join(library_name)); + println!("cargo:rustc-cfg={}=\"optimized-c\"", sym); + } + } + } + atomics_libraries + } } From b9da06f662b5fe013b2601550b81ba9ad22e87b1 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 30 Apr 2021 02:38:39 -0700 Subject: [PATCH 2/5] Fix typo in instruction name: s/cwp/swp/ --- library/compiler-builtins/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/build.rs b/library/compiler-builtins/build.rs index 2ff6443d7dea..26296db0c84b 100644 --- a/library/compiler-builtins/build.rs +++ b/library/compiler-builtins/build.rs @@ -538,7 +538,7 @@ mod c { // Ideally, this would be a Vec of object files, but cc doesn't make it *entirely* // trivial to build an individual object. let mut atomics_libraries = Vec::new(); - for instruction_type in &["cas", "cwp", "ldadd", "ldclr", "ldeor", "ldset"] { + for instruction_type in &["cas", "swp", "ldadd", "ldclr", "ldeor", "ldset"] { for size in &[1, 2, 4, 8, 16] { if *size == 16 && *instruction_type != "cas" { continue; From df8e6f179a7f9045464617a8ce7d23bc7c90bfe1 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 30 Apr 2021 02:39:07 -0700 Subject: [PATCH 3/5] Require lse.S (now available in current LLVM) --- library/compiler-builtins/build.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/library/compiler-builtins/build.rs b/library/compiler-builtins/build.rs index 26296db0c84b..2178dc9353c1 100644 --- a/library/compiler-builtins/build.rs +++ b/library/compiler-builtins/build.rs @@ -526,13 +526,8 @@ mod c { // That said, it's unclear how useful this added complexity will be, so just do the simple // thing for now. let outlined_atomics_file = builtins_dir.join("aarch64/lse.S"); - - // A stable release hasn't been made with lse.S yet. Until we pick that up, do nothing. - if !outlined_atomics_file.exists() { - return vec![]; - } - println!("cargo:rerun-if-changed={}", outlined_atomics_file.display()); + let out_dir: PathBuf = env::var("OUT_DIR").unwrap().into(); // Ideally, this would be a Vec of object files, but cc doesn't make it *entirely* From 79c1e33364b002391584a35281d2862c1209efec Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 30 Apr 2021 02:41:44 -0700 Subject: [PATCH 4/5] Make the name of the intermediate library more closely match the intrinsic --- library/compiler-builtins/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/compiler-builtins/build.rs b/library/compiler-builtins/build.rs index 2178dc9353c1..3ba6d5883f25 100644 --- a/library/compiler-builtins/build.rs +++ b/library/compiler-builtins/build.rs @@ -543,7 +543,7 @@ mod c { &[(1, "relax"), (2, "acq"), (3, "rel"), (4, "acq_rel")] { let library_name = format!( - "liboutline_atomic_helper_{}_{}_{}.a", + "liboutline_atomic_helper_{}{}_{}.a", instruction_type, size, model_name ); let sym = format!("__aarch64_{}{}_{}", instruction_type, size, model_name); From fee637a7b6366200952775abe399eafb404a8a7b Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 30 Apr 2021 12:24:12 -0700 Subject: [PATCH 5/5] Update the version of compiler-rt in CI --- library/compiler-builtins/.github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/compiler-builtins/.github/workflows/main.yml b/library/compiler-builtins/.github/workflows/main.yml index 6e2d83879a26..3d63bc070cda 100644 --- a/library/compiler-builtins/.github/workflows/main.yml +++ b/library/compiler-builtins/.github/workflows/main.yml @@ -88,8 +88,8 @@ jobs: - run: rustup component add llvm-tools-preview - name: Download compiler-rt reference sources run: | - curl -L -o code.tar.gz https://github.com/rust-lang/llvm-project/archive/rustc/10.0-2020-05-05.tar.gz - tar xzf code.tar.gz --strip-components 1 llvm-project-rustc-10.0-2020-05-05/compiler-rt + curl -L -o code.tar.gz https://github.com/rust-lang/llvm-project/archive/rustc/12.0-2021-04-15.tar.gz + tar xzf code.tar.gz --strip-components 1 llvm-project-rustc-12.0-2021-04-15/compiler-rt echo RUST_COMPILER_RT_ROOT=./compiler-rt >> $GITHUB_ENV shell: bash