From 64e08e6b82711b24517b97de0364511d06d1e27f Mon Sep 17 00:00:00 2001
From: Alessandro Decina <alessandro.d@gmail.com>
Date: Mon, 30 Nov 2020 19:41:57 +0000
Subject: [PATCH 01/75] Add BPF target

This change adds the bpfel-unknown-none and bpfeb-unknown-none targets
which can be used to generate little endian and big endian BPF
---
 src/toolchain.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/toolchain.rs b/src/toolchain.rs
index 484a9b699a0..49475fe2469 100644
--- a/src/toolchain.rs
+++ b/src/toolchain.rs
@@ -67,6 +67,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
                     LinkerFlavor::Msvc => "link.exe",
                     LinkerFlavor::Lld(_) => "lld",
                     LinkerFlavor::PtxLinker => "rust-ptx-linker",
+                    LinkerFlavor::BpfLinker => "bpf-linker",
                 }),
                 flavor,
             )),

From 8b08cbd92fc8eb2ad3fe0f644b30731fb2374210 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Mon, 24 May 2021 18:55:30 +0200
Subject: [PATCH 02/75] Change the ice hook for cg_clif to refer to cg_clif's
 issue tracker

---
 src/bin/cg_clif.rs | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs
index 983839d48d2..2643fae0a81 100644
--- a/src/bin/cg_clif.rs
+++ b/src/bin/cg_clif.rs
@@ -1,4 +1,4 @@
-#![feature(rustc_private)]
+#![feature(rustc_private, once_cell)]
 
 extern crate rustc_data_structures;
 extern crate rustc_driver;
@@ -6,12 +6,33 @@ extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_target;
 
+use std::panic;
+use std::lazy::SyncLazy;
+
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 use rustc_interface::interface;
 use rustc_session::config::ErrorOutputType;
 use rustc_session::early_error;
 use rustc_target::spec::PanicStrategy;
 
+const BUG_REPORT_URL: &str = "https://github.com/bjorn3/rustc_codegen_cranelift/issues/new";
+
+static DEFAULT_HOOK: SyncLazy<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static>> =
+    SyncLazy::new(|| {
+        let hook = panic::take_hook();
+        panic::set_hook(Box::new(|info| {
+            // Invoke the default handler, which prints the actual panic message and optionally a backtrace
+            (*DEFAULT_HOOK)(info);
+
+            // Separate the output with an empty line
+            eprintln!();
+
+            // Print the ICE message
+            rustc_driver::report_ice(info, BUG_REPORT_URL);
+        }));
+        hook
+    });
+
 #[derive(Default)]
 pub struct CraneliftPassesCallbacks {
     time_passes: bool,
@@ -37,7 +58,7 @@ fn main() {
     let start_rss = get_resident_set_size();
     rustc_driver::init_rustc_env_logger();
     let mut callbacks = CraneliftPassesCallbacks::default();
-    rustc_driver::install_ice_hook();
+    SyncLazy::force(&DEFAULT_HOOK); // Install ice hook
     let exit_code = rustc_driver::catch_with_exit_code(|| {
         let args = std::env::args_os()
             .enumerate()

From d6b03451e6d1203f9e4fc1f4c2c609cb4d045dc8 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 27 May 2021 13:08:14 +0200
Subject: [PATCH 03/75] Merge commit '40dd3e2b7089b5e96714e064b731f6dbf17c61a9'
 into sync_cg_clif-2021-05-27

---
 Cargo.lock                                    | 140 +++---------------
 Cargo.toml                                    |  28 ++--
 build_sysroot/Cargo.lock                      |  14 +-
 build_sysroot/prepare_sysroot_src.sh          |   2 +-
 ...ns-Disable-128bit-atomic-operations.patch} |   0
 ...builtins-Remove-rotate_left-from-Int.patch |  35 -----
 example/std_example.rs                        |  16 +-
 ...022-core-Disable-not-compiling-tests.patch |  40 -----
 rust-toolchain                                |   2 +-
 scripts/setup_rust_fork.sh                    |  17 +--
 scripts/tests.sh                              |   1 +
 src/archive.rs                                |   2 +-
 src/base.rs                                   |  13 +-
 src/common.rs                                 |  13 +-
 src/config.rs                                 |   9 ++
 src/constant.rs                               |  97 +++++++++++-
 src/driver/aot.rs                             |  21 +--
 src/driver/jit.rs                             |   3 +-
 src/inline_asm.rs                             |  30 ++--
 src/intrinsics/cpuid.rs                       |   7 +
 src/intrinsics/mod.rs                         |   2 +-
 src/lib.rs                                    |  10 +-
 src/main_shim.rs                              |   9 +-
 src/trap.rs                                   |   2 +-
 src/value_and_place.rs                        |   1 +
 25 files changed, 218 insertions(+), 296 deletions(-)
 rename crate_patches/{0002-compiler-builtins-Disable-128bit-atomic-operations.patch => 0001-compiler-builtins-Disable-128bit-atomic-operations.patch} (100%)
 delete mode 100644 crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch

diff --git a/Cargo.lock b/Cargo.lock
index e6792def567..a6f5925149b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -25,12 +25,6 @@ version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 
-[[package]]
-name = "byteorder"
-version = "1.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b"
-
 [[package]]
 name = "cfg-if"
 version = "1.0.0"
@@ -39,18 +33,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
- "byteorder",
  "cranelift-bforest",
  "cranelift-codegen-meta",
  "cranelift-codegen-shared",
@@ -60,13 +53,12 @@ dependencies = [
  "regalloc",
  "smallvec",
  "target-lexicon",
- "thiserror",
 ]
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
@@ -74,18 +66,18 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 
 [[package]]
 name = "cranelift-entity"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -95,15 +87,14 @@ dependencies = [
 
 [[package]]
 name = "cranelift-jit"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
  "cranelift-entity",
  "cranelift-module",
  "cranelift-native",
- "errno",
  "libc",
  "log",
  "region",
@@ -113,20 +104,19 @@ dependencies = [
 
 [[package]]
 name = "cranelift-module"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
  "cranelift-entity",
  "log",
- "thiserror",
 ]
 
 [[package]]
 name = "cranelift-native"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "cranelift-codegen",
  "target-lexicon",
@@ -134,8 +124,8 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.73.0"
-source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#45bee40f338c631bff4a799288101ba328c7ad36"
+version = "0.74.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -154,38 +144,11 @@ dependencies = [
  "cfg-if",
 ]
 
-[[package]]
-name = "errno"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa68f2fb9cae9d37c9b2b3584aba698a2e97f72d7aef7b9f7aa71d8b54ce46fe"
-dependencies = [
- "errno-dragonfly",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "errno-dragonfly"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "14ca354e36190500e1e1fb267c647932382b54053c50b14970856c0b00a35067"
-dependencies = [
- "gcc",
- "libc",
-]
-
-[[package]]
-name = "gcc"
-version = "0.3.55"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
-
 [[package]]
 name = "gimli"
-version = "0.23.0"
+version = "0.24.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
+checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189"
 dependencies = [
  "indexmap",
 ]
@@ -242,32 +205,14 @@ dependencies = [
 
 [[package]]
 name = "object"
-version = "0.23.0"
+version = "0.24.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4"
+checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170"
 dependencies = [
  "crc32fast",
  "indexmap",
 ]
 
-[[package]]
-name = "proc-macro2"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
-dependencies = [
- "proc-macro2",
-]
-
 [[package]]
 name = "regalloc"
 version = "0.0.31"
@@ -322,49 +267,12 @@ version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
 
-[[package]]
-name = "syn"
-version = "1.0.60"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
 [[package]]
 name = "target-lexicon"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "64ae3b39281e4b14b8123bdbaddd472b7dfe215e444181f2f9d2443c2444f834"
 
-[[package]]
-name = "thiserror"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e"
-dependencies = [
- "thiserror-impl",
-]
-
-[[package]]
-name = "thiserror-impl"
-version = "1.0.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
-
 [[package]]
 name = "winapi"
 version = "0.3.9"
diff --git a/Cargo.toml b/Cargo.toml
index 2789207c655..fd149af4547 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,15 +9,15 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind"] }
-cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
-cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
-cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
-cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", optional = true }
-cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" }
+cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main", features = ["unwind"] }
+cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
+cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
+cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
+cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main", optional = true }
+cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
 target-lexicon = "0.12.0"
-gimli = { version = "0.23.0", default-features = false, features = ["write"]}
-object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
+gimli = { version = "0.24.0", default-features = false, features = ["write"]}
+object = { version = "0.24.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
 
 ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
 indexmap = "1.0.2"
@@ -25,11 +25,11 @@ libloading = { version = "0.6.0", optional = true }
 smallvec = "1.6.1"
 
 # Uncomment to use local checkout of cranelift
-#[patch."https://github.com/bytecodealliance/wasmtime/"]
+#[patch."https://github.com/bytecodealliance/wasmtime.git"]
 #cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
 #cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
 #cranelift-module = { path = "../wasmtime/cranelift/module" }
-#cranelift-native = { path = ../wasmtime/cranelift/native" }
+#cranelift-native = { path = "../wasmtime/cranelift/native" }
 #cranelift-jit = { path = "../wasmtime/cranelift/jit" }
 #cranelift-object = { path = "../wasmtime/cranelift/object" }
 
@@ -70,13 +70,5 @@ debug = false
 opt-level = 0
 debug = false
 
-[profile.dev.package.syn]
-opt-level = 0
-debug = false
-
-[profile.release.package.syn]
-opt-level = 0
-debug = false
-
 [package.metadata.rust-analyzer]
 rustc_private = true
diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock
index e058a972ead..923deb9aec4 100644
--- a/build_sysroot/Cargo.lock
+++ b/build_sysroot/Cargo.lock
@@ -40,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
 
 [[package]]
 name = "cc"
-version = "1.0.67"
+version = "1.0.68"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd"
+checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787"
 
 [[package]]
 name = "cfg-if"
@@ -56,7 +56,7 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.40"
+version = "0.1.43"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -132,9 +132,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.94"
+version = "0.2.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
+checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -195,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.18"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
+checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
 dependencies = [
  "compiler_builtins",
  "rustc-std-workspace-core",
diff --git a/build_sysroot/prepare_sysroot_src.sh b/build_sysroot/prepare_sysroot_src.sh
index f7fcef10774..54b7a94750c 100755
--- a/build_sysroot/prepare_sysroot_src.sh
+++ b/build_sysroot/prepare_sysroot_src.sh
@@ -32,7 +32,7 @@ popd
 git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/compiler-builtins has already been cloned"
 pushd compiler-builtins
 git checkout -- .
-git checkout 0.1.40
+git checkout 0.1.43
 git apply ../../crate_patches/000*-compiler-builtins-*.patch
 popd
 
diff --git a/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch b/crate_patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch
similarity index 100%
rename from crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch
rename to crate_patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch
diff --git a/crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch b/crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch
deleted file mode 100644
index b4acc4f5b73..00000000000
--- a/crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 7078cca3cb614e1e82da428380b4e16fc3afef46 Mon Sep 17 00:00:00 2001
-From: bjorn3 <bjorn3@users.noreply.github.com>
-Date: Thu, 21 Jan 2021 14:46:36 +0100
-Subject: [PATCH] Remove rotate_left from Int
-
----
- src/int/mod.rs | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/src/int/mod.rs b/src/int/mod.rs
-index 06054c8..3bea17b 100644
---- a/src/int/mod.rs
-+++ b/src/int/mod.rs
-@@ -85,7 +85,6 @@ pub trait Int:
-     fn wrapping_sub(self, other: Self) -> Self;
-     fn wrapping_shl(self, other: u32) -> Self;
-     fn wrapping_shr(self, other: u32) -> Self;
--    fn rotate_left(self, other: u32) -> Self;
-     fn overflowing_add(self, other: Self) -> (Self, bool);
-     fn leading_zeros(self) -> u32;
- }
-@@ -209,10 +208,6 @@ macro_rules! int_impl_common {
-             <Self>::wrapping_shr(self, other)
-         }
- 
--        fn rotate_left(self, other: u32) -> Self {
--            <Self>::rotate_left(self, other)
--        }
--
-         fn overflowing_add(self, other: Self) -> (Self, bool) {
-             <Self>::overflowing_add(self, other)
-         }
--- 
-2.26.2.7.g19db9cfb68
-
diff --git a/example/std_example.rs b/example/std_example.rs
index 77ba72df8ef..7d608df9253 100644
--- a/example/std_example.rs
+++ b/example/std_example.rs
@@ -187,20 +187,6 @@ unsafe fn test_mm_slli_si128() {
     );
     let r = _mm_slli_si128(a, 16);
     assert_eq_m128i(r, _mm_set1_epi8(0));
-
-    #[rustfmt::skip]
-    let a = _mm_setr_epi8(
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-    );
-    let r = _mm_slli_si128(a, -1);
-    assert_eq_m128i(_mm_set1_epi8(0), r);
-
-    #[rustfmt::skip]
-    let a = _mm_setr_epi8(
-        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-    );
-    let r = _mm_slli_si128(a, -0x80000000);
-    assert_eq_m128i(r, _mm_set1_epi8(0));
 }
 
 #[cfg(target_arch = "x86_64")]
@@ -295,7 +281,7 @@ unsafe fn test_mm_extract_epi8() {
         8, 9, 10, 11, 12, 13, 14, 15
     );
     let r1 = _mm_extract_epi8(a, 0);
-    let r2 = _mm_extract_epi8(a, 19);
+    let r2 = _mm_extract_epi8(a, 3);
     assert_eq!(r1, 0xFF);
     assert_eq!(r2, 3);
 }
diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch
index 8cfffe580a1..ba0eaacd828 100644
--- a/patches/0022-core-Disable-not-compiling-tests.patch
+++ b/patches/0022-core-Disable-not-compiling-tests.patch
@@ -39,46 +39,6 @@ index a35897e..f0bf645 100644
  
  pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
      match decode(v).1 {
-diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
-index 0475aeb..9558198 100644
---- a/library/core/tests/num/int_macros.rs
-+++ b/library/core/tests/num/int_macros.rs
-@@ -88,6 +88,7 @@ mod tests {
-                 assert_eq!(x.trailing_ones(), 0);
-             }
- 
-+            /*
-             #[test]
-             fn test_rotate() {
-                 assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-@@ -112,6 +113,7 @@ mod tests {
-                 assert_eq!(B.rotate_left(128), B);
-                 assert_eq!(C.rotate_left(128), C);
-             }
-+            */
- 
-             #[test]
-             fn test_swap_bytes() {
-diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs
-index 04ed14f..a6e372e 100644
---- a/library/core/tests/num/uint_macros.rs
-+++ b/library/core/tests/num/uint_macros.rs
-@@ -52,6 +52,7 @@ mod tests {
-                 assert_eq!(x.trailing_ones(), 0);
-             }
- 
-+            /*
-             #[test]
-             fn test_rotate() {
-                 assert_eq!(A.rotate_left(6).rotate_right(2).rotate_right(4), A);
-@@ -76,6 +77,7 @@ mod tests {
-                 assert_eq!(B.rotate_left(128), B);
-                 assert_eq!(C.rotate_left(128), C);
-             }
-+            */
- 
-             #[test]
-             fn test_swap_bytes() {
 diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
 index 1a6be3a..42dbd59 100644
 --- a/library/core/tests/ptr.rs
diff --git a/rust-toolchain b/rust-toolchain
index 5442e3345aa..9fe6e093a7b 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-04-28"
+channel = "nightly-2021-05-26"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh
index 4821a07ac5d..43c4887669c 100644
--- a/scripts/setup_rust_fork.sh
+++ b/scripts/setup_rust_fork.sh
@@ -24,18 +24,6 @@ index 5bd1147cad5..10d68a2ff14 100644
 +
  [patch."https://github.com/rust-lang/rust-clippy"]
  clippy_lints = { path = "src/tools/clippy/clippy_lints" }
-diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
-index 23e689fcae7..5f077b765b6 100644
---- a/compiler/rustc_data_structures/Cargo.toml
-+++ b/compiler/rustc_data_structures/Cargo.toml
-@@ -32,7 +32,6 @@ tempfile = "3.0.5"
-
- [dependencies.parking_lot]
- version = "0.11"
--features = ["nightly"]
-
- [target.'cfg(windows)'.dependencies]
- winapi = { version = "0.3", features = ["fileapi", "psapi"] }
 diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
 index d95b5b7f17f..00b6f0e3635 100644
 --- a/library/alloc/Cargo.toml
@@ -44,11 +32,12 @@ index d95b5b7f17f..00b6f0e3635 100644
 
  [dependencies]
  core = { path = "../core" }
--compiler_builtins = { version = "0.1.39", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std', 'no-asm'] }
+-compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
++compiler_builtins = { version = "0.1.43", features = ['rustc-dep-of-std', 'no-asm'] }
 
  [dev-dependencies]
  rand = "0.7"
+ rand_xorshift = "0.2"
 EOF
 
 cat > config.toml <<EOF
diff --git a/scripts/tests.sh b/scripts/tests.sh
index 3afcea8f06b..0d99d2c507c 100755
--- a/scripts/tests.sh
+++ b/scripts/tests.sh
@@ -116,6 +116,7 @@ function extended_sysroot_tests() {
     pushd regex
     echo "[TEST] rust-lang/regex example shootout-regex-dna"
     cargo clean
+    export RUSTFLAGS="$RUSTFLAGS --cap-lints warn" # newer aho_corasick versions throw a deprecation warning
     # Make sure `[codegen mono items] start` doesn't poison the diff
     ../build/cargo.sh build --example shootout-regex-dna --target $TARGET_TRIPLE
     if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
diff --git a/src/archive.rs b/src/archive.rs
index fc0823302e0..bd54adc53ee 100644
--- a/src/archive.rs
+++ b/src/archive.rs
@@ -160,7 +160,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             };
 
             if !self.no_builtin_ranlib {
-                match object::File::parse(&data) {
+                match object::File::parse(&*data) {
                     Ok(object) => {
                         symbol_table.insert(
                             entry_name.as_bytes().to_vec(),
diff --git a/src/base.rs b/src/base.rs
index 3ec5c14ff17..ec3e17e5b75 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -110,11 +110,6 @@ pub(crate) fn codegen_fn<'tcx>(
     // Verify function
     verify_func(tcx, &clif_comments, &context.func);
 
-    // Perform rust specific optimizations
-    tcx.sess.time("optimize clif ir", || {
-        crate::optimize::optimize_function(tcx, instance, context, &mut clif_comments);
-    });
-
     // If the return block is not reachable, then the SSA builder may have inserted an `iconst.i128`
     // instruction, which doesn't have an encoding.
     context.compute_cfg();
@@ -125,10 +120,14 @@ pub(crate) fn codegen_fn<'tcx>(
     // invalidate it when it would change.
     context.domtree.clear();
 
-    context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
+    // Perform rust specific optimizations
+    tcx.sess.time("optimize clif ir", || {
+        crate::optimize::optimize_function(tcx, instance, context, &mut clif_comments);
+    });
 
     // Define function
     tcx.sess.time("define function", || {
+        context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
         module
             .define_function(func_id, context, &mut NullTrapSink {}, &mut NullStackMapSink {})
             .unwrap()
@@ -870,7 +869,7 @@ pub(crate) fn codegen_operand<'tcx>(
 pub(crate) fn codegen_panic<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, span: Span) {
     let location = fx.get_caller_location(span).load_scalar(fx);
 
-    let msg_ptr = fx.anonymous_str("assert", msg_str);
+    let msg_ptr = fx.anonymous_str(msg_str);
     let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
     let args = [msg_ptr, msg_len, location];
 
diff --git a/src/common.rs b/src/common.rs
index c12d6d0f141..488ff6e1349 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -347,19 +347,10 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
         self.module.isa().triple()
     }
 
-    pub(crate) fn anonymous_str(&mut self, prefix: &str, msg: &str) -> Value {
-        use std::collections::hash_map::DefaultHasher;
-        use std::hash::{Hash, Hasher};
-
-        let mut hasher = DefaultHasher::new();
-        msg.hash(&mut hasher);
-        let msg_hash = hasher.finish();
+    pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value {
         let mut data_ctx = DataContext::new();
         data_ctx.define(msg.as_bytes().to_vec().into_boxed_slice());
-        let msg_id = self
-            .module
-            .declare_data(&format!("__{}_{:08x}", prefix, msg_hash), Linkage::Local, false, false)
-            .unwrap();
+        let msg_id = self.module.declare_anonymous_data(false, false).unwrap();
 
         // Ignore DuplicateDefinition error, as the data will be the same
         let _ = self.module.define_data(msg_id, &data_ctx);
diff --git a/src/config.rs b/src/config.rs
index e59a0cb0a23..eef3c8c8d6e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -48,6 +48,12 @@ pub struct BackendConfig {
     /// Can be set using `-Cllvm-args=display_cg_time=...`.
     pub display_cg_time: bool,
 
+    /// The register allocator to use.
+    ///
+    /// Defaults to the value of `CG_CLIF_REGALLOC` or `backtracking` otherwise. Can be set using
+    /// `-Cllvm-args=regalloc=...`.
+    pub regalloc: String,
+
     /// Enable the Cranelift ir verifier for all compilation passes. If not set it will only run
     /// once before passing the clif ir to Cranelift for compilation.
     ///
@@ -74,6 +80,8 @@ impl Default for BackendConfig {
                 args.split(' ').map(|arg| arg.to_string()).collect()
             },
             display_cg_time: bool_env_var("CG_CLIF_DISPLAY_CG_TIME"),
+            regalloc: std::env::var("CG_CLIF_REGALLOC")
+                .unwrap_or_else(|_| "backtracking".to_string()),
             enable_verifier: cfg!(debug_assertions) || bool_env_var("CG_CLIF_ENABLE_VERIFIER"),
             disable_incr_cache: bool_env_var("CG_CLIF_DISABLE_INCR_CACHE"),
         }
@@ -93,6 +101,7 @@ impl BackendConfig {
                 match name {
                     "mode" => config.codegen_mode = value.parse()?,
                     "display_cg_time" => config.display_cg_time = parse_bool(name, value)?,
+                    "regalloc" => config.regalloc = value.to_string(),
                     "enable_verifier" => config.enable_verifier = parse_bool(name, value)?,
                     "disable_incr_cache" => config.disable_incr_cache = parse_bool(name, value)?,
                     _ => return Err(format!("Unknown option `{}`", name)),
diff --git a/src/constant.rs b/src/constant.rs
index 6b132e4ff0f..3ba12c4e96d 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -7,7 +7,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::ErrorReported;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::{
-    alloc_range, read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
+    alloc_range, read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc,
+    Scalar,
 };
 use rustc_middle::ty::ConstKind;
 
@@ -375,8 +376,19 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
         data_ctx.set_align(alloc.align.bytes());
 
         if let Some(section_name) = section_name {
-            // FIXME set correct segment for Mach-O files
-            data_ctx.set_segment_section("", &*section_name);
+            let (segment_name, section_name) = if tcx.sess.target.is_like_osx {
+                if let Some(names) = section_name.split_once(',') {
+                    names
+                } else {
+                    tcx.sess.fatal(&format!(
+                        "#[link_section = \"{}\"] is not valid for macos target: must be segment and section separated by comma",
+                        section_name
+                    ));
+                }
+            } else {
+                ("", &*section_name)
+            };
+            data_ctx.set_segment_section(segment_name, section_name);
         }
 
         let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec();
@@ -438,12 +450,89 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
     operand: &Operand<'tcx>,
 ) -> Option<ConstValue<'tcx>> {
     match operand {
-        Operand::Copy(_) | Operand::Move(_) => None,
         Operand::Constant(const_) => match const_.literal {
             ConstantKind::Ty(const_) => {
                 fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value()
             }
             ConstantKind::Val(val, _) => Some(val),
         },
+        // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored
+        // inside a temporary before being passed to the intrinsic requiring the const argument.
+        // This code tries to find a single constant defining definition of the referenced local.
+        Operand::Copy(place) | Operand::Move(place) => {
+            if !place.projection.is_empty() {
+                return None;
+            }
+            let mut computed_const_val = None;
+            for bb_data in fx.mir.basic_blocks() {
+                for stmt in &bb_data.statements {
+                    match &stmt.kind {
+                        StatementKind::Assign(local_and_rvalue) if &local_and_rvalue.0 == place => {
+                            match &local_and_rvalue.1 {
+                                Rvalue::Cast(CastKind::Misc, operand, ty) => {
+                                    if computed_const_val.is_some() {
+                                        return None; // local assigned twice
+                                    }
+                                    if !matches!(ty.kind(), ty::Uint(_) | ty::Int(_)) {
+                                        return None;
+                                    }
+                                    let const_val = mir_operand_get_const_val(fx, operand)?;
+                                    if fx.layout_of(ty).size
+                                        != const_val.try_to_scalar_int()?.size()
+                                    {
+                                        return None;
+                                    }
+                                    computed_const_val = Some(const_val);
+                                }
+                                Rvalue::Use(operand) => {
+                                    computed_const_val = mir_operand_get_const_val(fx, operand)
+                                }
+                                _ => return None,
+                            }
+                        }
+                        StatementKind::SetDiscriminant { place: stmt_place, variant_index: _ }
+                            if &**stmt_place == place =>
+                        {
+                            return None;
+                        }
+                        StatementKind::LlvmInlineAsm(_) | StatementKind::CopyNonOverlapping(_) => {
+                            return None;
+                        } // conservative handling
+                        StatementKind::Assign(_)
+                        | StatementKind::FakeRead(_)
+                        | StatementKind::SetDiscriminant { .. }
+                        | StatementKind::StorageLive(_)
+                        | StatementKind::StorageDead(_)
+                        | StatementKind::Retag(_, _)
+                        | StatementKind::AscribeUserType(_, _)
+                        | StatementKind::Coverage(_)
+                        | StatementKind::Nop => {}
+                    }
+                }
+                match &bb_data.terminator().kind {
+                    TerminatorKind::Goto { .. }
+                    | TerminatorKind::SwitchInt { .. }
+                    | TerminatorKind::Resume
+                    | TerminatorKind::Abort
+                    | TerminatorKind::Return
+                    | TerminatorKind::Unreachable
+                    | TerminatorKind::Drop { .. }
+                    | TerminatorKind::Assert { .. } => {}
+                    TerminatorKind::DropAndReplace { .. }
+                    | TerminatorKind::Yield { .. }
+                    | TerminatorKind::GeneratorDrop
+                    | TerminatorKind::FalseEdge { .. }
+                    | TerminatorKind::FalseUnwind { .. } => unreachable!(),
+                    TerminatorKind::InlineAsm { .. } => return None,
+                    TerminatorKind::Call { destination: Some((call_place, _)), .. }
+                        if call_place == place =>
+                    {
+                        return None;
+                    }
+                    TerminatorKind::Call { .. } => {}
+                }
+            }
+            computed_const_val
+        }
     }
 }
diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 24d933728db..9cf51d15c8c 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -73,9 +73,8 @@ fn reuse_workproduct_for_cgu(
     let mut object = None;
     let work_product = cgu.work_product(tcx);
     if let Some(saved_file) = &work_product.saved_file {
-        let obj_out = tcx
-            .output_filenames(())
-            .temp_path(OutputType::Object, Some(&cgu.name().as_str()));
+        let obj_out =
+            tcx.output_filenames(()).temp_path(OutputType::Object, Some(&cgu.name().as_str()));
         object = Some(obj_out.clone());
         let source_file = rustc_incremental::in_incr_comp_dir(&incr_comp_session_dir, &saved_file);
         if let Err(err) = rustc_fs_util::link_or_copy(&source_file, &obj_out) {
@@ -145,7 +144,13 @@ fn module_codegen(
             }
         }
     }
-    crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut cx.unwind_context, false);
+    crate::main_shim::maybe_create_entry_wrapper(
+        tcx,
+        &mut module,
+        &mut cx.unwind_context,
+        false,
+        cgu.is_primary(),
+    );
 
     let debug_context = cx.debug_context;
     let unwind_context = cx.unwind_context;
@@ -275,9 +280,8 @@ pub(crate) fn run_aot(
                 .as_str()
                 .to_string();
 
-            let tmp_file = tcx
-                .output_filenames(())
-                .temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
+            let tmp_file =
+                tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
 
             let obj = crate::backend::with_object(tcx.sess, &metadata_cgu_name, |object| {
                 crate::metadata::write_metadata(tcx, object);
@@ -352,8 +356,7 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) {
         .collect::<Vec<_>>()
         .join("\n");
 
-    let output_object_file =
-        tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
+    let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
 
     // Assemble `global_asm`
     let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index 632e86da736..4a99cb727c8 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -45,6 +45,7 @@ fn create_jit_module<'tcx>(
         &mut jit_module,
         &mut cx.unwind_context,
         true,
+        true,
     );
 
     (jit_module, cx)
@@ -206,7 +207,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
         use object::{Object, ObjectSymbol};
         let lib = libloading::Library::new(&path).unwrap();
         let obj = std::fs::read(path).unwrap();
-        let obj = object::File::parse(&obj).unwrap();
+        let obj = object::File::parse(&*obj).unwrap();
         imported_symbols.extend(obj.dynamic_symbols().filter_map(|symbol| {
             let name = symbol.name().unwrap().to_string();
             if name.is_empty() || !symbol.is_global() || symbol.is_undefined() {
diff --git a/src/inline_asm.rs b/src/inline_asm.rs
index 4ab4c2957ca..09c5e6031c7 100644
--- a/src/inline_asm.rs
+++ b/src/inline_asm.rs
@@ -24,14 +24,22 @@ pub(crate) fn codegen_inline_asm<'tcx>(
         let true_ = fx.bcx.ins().iconst(types::I32, 1);
         fx.bcx.ins().trapnz(true_, TrapCode::User(1));
         return;
-    } else if template[0] == InlineAsmTemplatePiece::String("mov rsi, rbx".to_string())
-        && template[1] == InlineAsmTemplatePiece::String("\n".to_string())
-        && template[2] == InlineAsmTemplatePiece::String("cpuid".to_string())
-        && template[3] == InlineAsmTemplatePiece::String("\n".to_string())
-        && template[4] == InlineAsmTemplatePiece::String("xchg rsi, rbx".to_string())
+    } else if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string())
+        && matches!(
+            template[1],
+            InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
+        )
+        && template[2] == InlineAsmTemplatePiece::String("\n".to_string())
+        && template[3] == InlineAsmTemplatePiece::String("cpuid".to_string())
+        && template[4] == InlineAsmTemplatePiece::String("\n".to_string())
+        && template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string())
+        && matches!(
+            template[6],
+            InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: Some('r'), span: _ }
+        )
     {
         assert_eq!(operands.len(), 4);
-        let (leaf, eax_place) = match operands[0] {
+        let (leaf, eax_place) = match operands[1] {
             InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
                 let reg = expect_reg(reg);
                 assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::ax));
@@ -42,10 +50,14 @@ pub(crate) fn codegen_inline_asm<'tcx>(
             }
             _ => unreachable!(),
         };
-        let ebx_place = match operands[1] {
+        let ebx_place = match operands[0] {
             InlineAsmOperand::Out { reg, late: true, place } => {
-                let reg = expect_reg(reg);
-                assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::si));
+                assert_eq!(
+                    reg,
+                    InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
+                        X86InlineAsmRegClass::reg
+                    ))
+                );
                 crate::base::codegen_place(fx, place.unwrap())
             }
             _ => unreachable!(),
diff --git a/src/intrinsics/cpuid.rs b/src/intrinsics/cpuid.rs
index 9de12e759bc..d02dfd93c3e 100644
--- a/src/intrinsics/cpuid.rs
+++ b/src/intrinsics/cpuid.rs
@@ -12,6 +12,7 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
 ) -> (Value, Value, Value, Value) {
     let leaf_0 = fx.bcx.create_block();
     let leaf_1 = fx.bcx.create_block();
+    let leaf_7 = fx.bcx.create_block();
     let leaf_8000_0000 = fx.bcx.create_block();
     let leaf_8000_0001 = fx.bcx.create_block();
     let unsupported_leaf = fx.bcx.create_block();
@@ -25,6 +26,7 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
     let mut switch = cranelift_frontend::Switch::new();
     switch.set_entry(0, leaf_0);
     switch.set_entry(1, leaf_1);
+    switch.set_entry(7, leaf_7);
     switch.set_entry(0x8000_0000, leaf_8000_0000);
     switch.set_entry(0x8000_0001, leaf_8000_0001);
     switch.emit(&mut fx.bcx, leaf, unsupported_leaf);
@@ -43,6 +45,11 @@ pub(crate) fn codegen_cpuid_call<'tcx>(
     let edx_features = fx.bcx.ins().iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */);
     fx.bcx.ins().jump(dest, &[cpu_signature, additional_information, ecx_features, edx_features]);
 
+    fx.bcx.switch_to_block(leaf_7);
+    // This leaf technically has subleaves, but we just return zero for all subleaves.
+    let zero = fx.bcx.ins().iconst(types::I32, 0);
+    fx.bcx.ins().jump(dest, &[zero, zero, zero, zero]);
+
     fx.bcx.switch_to_block(leaf_8000_0000);
     let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0);
     let zero = fx.bcx.ins().iconst(types::I32, 0);
diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs
index 435737f3a51..52896fc7127 100644
--- a/src/intrinsics/mod.rs
+++ b/src/intrinsics/mod.rs
@@ -8,8 +8,8 @@ mod simd;
 pub(crate) use cpuid::codegen_cpuid_call;
 pub(crate) use llvm::codegen_llvm_intrinsic_call;
 
-use rustc_span::symbol::{sym, kw};
 use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_span::symbol::{kw, sym};
 
 use crate::prelude::*;
 use cranelift_codegen::ir::AtomicRmwOp;
diff --git a/src/lib.rs b/src/lib.rs
index ff6e1856059..4ee887cd5af 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -256,6 +256,8 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
 
     flags_builder.set("enable_llvm_abi_extensions", "true").unwrap();
 
+    flags_builder.set("regalloc", &backend_config.regalloc).unwrap();
+
     use rustc_session::config::OptLevel;
     match sess.opts.optimize {
         OptLevel::No => {
@@ -277,21 +279,23 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
             builder
         }
         Some(value) => {
-            let mut builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
+            let mut builder =
+                cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
             if let Err(_) = builder.enable(value) {
                 sess.fatal("The specified target cpu isn't currently supported by Cranelift.");
             }
             builder
         }
         None => {
-            let mut builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
+            let mut builder =
+                cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
             // Don't use "haswell" as the default, as it implies `has_lzcnt`.
             // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
             builder.enable("nehalem").unwrap();
             builder
         }
     };
-    
+
     isa_builder.finish(flags)
 }
 
diff --git a/src/main_shim.rs b/src/main_shim.rs
index d1958c5f96b..8fd1e4f5811 100644
--- a/src/main_shim.rs
+++ b/src/main_shim.rs
@@ -14,6 +14,7 @@ pub(crate) fn maybe_create_entry_wrapper(
     module: &mut impl Module,
     unwind_context: &mut UnwindContext,
     is_jit: bool,
+    is_primary_cgu: bool,
 ) {
     let (main_def_id, is_main_fn) = match tcx.entry_fn(()) {
         Some((def_id, entry_ty)) => (
@@ -26,8 +27,12 @@ pub(crate) fn maybe_create_entry_wrapper(
         None => return,
     };
 
-    let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx);
-    if !is_jit && module.get_name(&*tcx.symbol_name(instance).name).is_none() {
+    if main_def_id.is_local() {
+        let instance = Instance::mono(tcx, main_def_id).polymorphize(tcx);
+        if !is_jit && module.get_name(&*tcx.symbol_name(instance).name).is_none() {
+            return;
+        }
+    } else if !is_primary_cgu {
         return;
     }
 
diff --git a/src/trap.rs b/src/trap.rs
index 819c8b51558..21d3e68dbc7 100644
--- a/src/trap.rs
+++ b/src/trap.rs
@@ -21,7 +21,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
     }
 
     let real_msg = format!("trap at {:?} ({}): {}\0", fx.instance, fx.symbol_name, msg);
-    let msg_ptr = fx.anonymous_str("trap", &real_msg);
+    let msg_ptr = fx.anonymous_str(&real_msg);
     fx.bcx.ins().call(puts, &[msg_ptr]);
 }
 
diff --git a/src/value_and_place.rs b/src/value_and_place.rs
index 9a572c3501f..171f39805f8 100644
--- a/src/value_and_place.rs
+++ b/src/value_and_place.rs
@@ -561,6 +561,7 @@ impl<'tcx> CPlace<'tcx> {
                     dst_align,
                     src_align,
                     true,
+                    MemFlags::trusted(),
                 );
             }
             CValueInner::ByRef(_, Some(_)) => todo!(),

From 4e62376059c0b2421bf5eb1fdeb31cc2768727f1 Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Tue, 11 May 2021 22:05:54 +0200
Subject: [PATCH 04/75] Make allocator_kind a query.

---
 src/allocator.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/allocator.rs b/src/allocator.rs
index 357a9f2daf7..d39486c2f10 100644
--- a/src/allocator.rs
+++ b/src/allocator.rs
@@ -19,7 +19,7 @@ pub(crate) fn codegen(
     });
     if any_dynamic_crate {
         false
-    } else if let Some(kind) = tcx.allocator_kind() {
+    } else if let Some(kind) = tcx.allocator_kind(()) {
         codegen_inner(module, unwind_context, kind);
         true
     } else {

From 228f1c549da28dd9e740cf8099a23212dab551de Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Sat, 29 May 2021 22:49:59 +0200
Subject: [PATCH 05/75] Drop metadata_encoding_version.

---
 src/lib.rs      | 1 +
 src/metadata.rs | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/lib.rs b/src/lib.rs
index 4ee887cd5af..637e91f5117 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,7 @@ extern crate rustc_fs_util;
 extern crate rustc_hir;
 extern crate rustc_incremental;
 extern crate rustc_index;
+extern crate rustc_metadata;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
diff --git a/src/metadata.rs b/src/metadata.rs
index ab238244d68..db24bf65eb5 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -10,7 +10,7 @@ pub(crate) fn write_metadata<O: WriteMetadata>(tcx: TyCtxt<'_>, object: &mut O)
     use std::io::Write;
 
     let metadata = tcx.encode_metadata();
-    let mut compressed = tcx.metadata_encoding_version();
+    let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
     FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
 
     object.add_rustc_section(

From d8d6a5aee0b258d5727d647d3943a75e66924932 Mon Sep 17 00:00:00 2001
From: Camille Gillot <gillot.camille@gmail.com>
Date: Tue, 1 Jun 2021 09:05:22 +0200
Subject: [PATCH 06/75] Revert "Reduce the amount of untracked state in TyCtxt"

---
 src/allocator.rs | 2 +-
 src/lib.rs       | 1 -
 src/metadata.rs  | 2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/allocator.rs b/src/allocator.rs
index d39486c2f10..357a9f2daf7 100644
--- a/src/allocator.rs
+++ b/src/allocator.rs
@@ -19,7 +19,7 @@ pub(crate) fn codegen(
     });
     if any_dynamic_crate {
         false
-    } else if let Some(kind) = tcx.allocator_kind(()) {
+    } else if let Some(kind) = tcx.allocator_kind() {
         codegen_inner(module, unwind_context, kind);
         true
     } else {
diff --git a/src/lib.rs b/src/lib.rs
index 637e91f5117..4ee887cd5af 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,7 +14,6 @@ extern crate rustc_fs_util;
 extern crate rustc_hir;
 extern crate rustc_incremental;
 extern crate rustc_index;
-extern crate rustc_metadata;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
diff --git a/src/metadata.rs b/src/metadata.rs
index db24bf65eb5..ab238244d68 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -10,7 +10,7 @@ pub(crate) fn write_metadata<O: WriteMetadata>(tcx: TyCtxt<'_>, object: &mut O)
     use std::io::Write;
 
     let metadata = tcx.encode_metadata();
-    let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
+    let mut compressed = tcx.metadata_encoding_version();
     FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
 
     object.add_rustc_section(

From f4eb0170aa7d9879f5d96b82d0ca2eb46b622907 Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Sat, 29 May 2021 22:49:59 +0200
Subject: [PATCH 07/75] Drop metadata_encoding_version.

---
 src/lib.rs      | 1 +
 src/metadata.rs | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/lib.rs b/src/lib.rs
index 4ee887cd5af..637e91f5117 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,7 @@ extern crate rustc_fs_util;
 extern crate rustc_hir;
 extern crate rustc_incremental;
 extern crate rustc_index;
+extern crate rustc_metadata;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
diff --git a/src/metadata.rs b/src/metadata.rs
index ab238244d68..db24bf65eb5 100644
--- a/src/metadata.rs
+++ b/src/metadata.rs
@@ -10,7 +10,7 @@ pub(crate) fn write_metadata<O: WriteMetadata>(tcx: TyCtxt<'_>, object: &mut O)
     use std::io::Write;
 
     let metadata = tcx.encode_metadata();
-    let mut compressed = tcx.metadata_encoding_version();
+    let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
     FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();
 
     object.add_rustc_section(

From b10a4424051dc5017e2c10055c732658be143e7f Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 29 May 2021 14:51:27 +0200
Subject: [PATCH 08/75] Provide a default provide* implementation for
 CodegenBackend

Both cg_llvm and cg_clif don't override it. cg_spirv does override it,
so it needs to be preserved.
---
 src/lib.rs | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index 4ee887cd5af..fbef575ba88 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -29,7 +29,6 @@ use rustc_codegen_ssa::CodegenResults;
 use rustc_errors::ErrorReported;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
 use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
-use rustc_middle::ty::query::Providers;
 use rustc_session::config::OutputFilenames;
 use rustc_session::Session;
 
@@ -168,9 +167,6 @@ impl CodegenBackend for CraneliftCodegenBackend {
         Box::new(rustc_codegen_ssa::back::metadata::DefaultMetadataLoader)
     }
 
-    fn provide(&self, _providers: &mut Providers) {}
-    fn provide_extern(&self, _providers: &mut Providers) {}
-
     fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
         vec![]
     }

From 20e9a1372b136a1d62d6fb8f5c351260f388eb58 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 29 May 2021 15:00:18 +0200
Subject: [PATCH 09/75] Provide default MetadataLoader

---
 src/lib.rs | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/lib.rs b/src/lib.rs
index fbef575ba88..de2afc49384 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -28,7 +28,7 @@ use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::CodegenResults;
 use rustc_errors::ErrorReported;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
+use rustc_middle::middle::cstore::EncodedMetadata;
 use rustc_session::config::OutputFilenames;
 use rustc_session::Session;
 
@@ -163,10 +163,6 @@ impl CodegenBackend for CraneliftCodegenBackend {
         }
     }
 
-    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
-        Box::new(rustc_codegen_ssa::back::metadata::DefaultMetadataLoader)
-    }
-
     fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
         vec![]
     }

From b6f0b46e2004d7a40f2deae0caa5dc22e53e42b7 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 29 May 2021 15:14:05 +0200
Subject: [PATCH 10/75] Allow printing the version of the default codegen
 backend if it isn't llvm

---
 src/lib.rs | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/lib.rs b/src/lib.rs
index de2afc49384..fa776bf9921 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -167,6 +167,10 @@ impl CodegenBackend for CraneliftCodegenBackend {
         vec![]
     }
 
+    fn print_version(&self) {
+        println!("Cranelift version: {}", cranelift_codegen::VERSION);
+    }
+
     fn codegen_crate(
         &self,
         tcx: TyCtxt<'_>,

From 646c6043a712c661e6774d3128eab2c1be517ee3 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 29 May 2021 17:08:46 +0200
Subject: [PATCH 11/75] Move windows_subsystem field from CodegenResults to
 CrateInfo

---
 src/driver/aot.rs | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 9cf51d15c8c..2270b18163b 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -177,21 +177,6 @@ pub(crate) fn run_aot(
     metadata: EncodedMetadata,
     need_metadata_module: bool,
 ) -> Box<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)> {
-    use rustc_span::symbol::sym;
-
-    let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
-    let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
-    let windows_subsystem = subsystem.map(|subsystem| {
-        if subsystem != sym::windows && subsystem != sym::console {
-            tcx.sess.fatal(&format!(
-                "invalid windows subsystem `{}`, only \
-                                    `windows` and `console` are allowed",
-                subsystem
-            ));
-        }
-        subsystem.to_string()
-    });
-
     let mut work_products = FxHashMap::default();
 
     let cgus = if tcx.sess.opts.output_types.should_codegen() {
@@ -312,7 +297,6 @@ pub(crate) fn run_aot(
             allocator_module,
             metadata_module,
             metadata,
-            windows_subsystem,
             linker_info: LinkerInfo::new(tcx, crate::target_triple(tcx.sess).to_string()),
             crate_info: CrateInfo::new(tcx),
         },

From dbdeafbc2688c52e056befee035829d0e30ee924 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 29 May 2021 17:37:38 +0200
Subject: [PATCH 12/75] Move crate_name field from OngoingCodegen to CrateInfo

---
 src/driver/aot.rs | 1 -
 src/lib.rs        | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 2270b18163b..6676d88602c 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -292,7 +292,6 @@ pub(crate) fn run_aot(
 
     Box::new((
         CodegenResults {
-            crate_name: tcx.crate_name(LOCAL_CRATE),
             modules,
             allocator_module,
             metadata_module,
diff --git a/src/lib.rs b/src/lib.rs
index fa776bf9921..904efed5bd9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -218,7 +218,7 @@ impl CodegenBackend for CraneliftCodegenBackend {
             sess,
             &codegen_results,
             outputs,
-            &codegen_results.crate_name.as_str(),
+            &codegen_results.crate_info.local_crate_name.as_str(),
         );
 
         Ok(())

From 1248ff139d85c0f9f9aec0684d991e62013541b7 Mon Sep 17 00:00:00 2001
From: Richard Cobbe <ricobbe@microsoft.com>
Date: Mon, 8 Mar 2021 12:42:54 -0800
Subject: [PATCH 13/75] Add first cut of functionality for #58713: support for
 #[link(kind = "raw-dylib")].

This does not yet support #[link_name] attributes on functions, the #[link_ordinal]
attribute, #[link(kind = "raw-dylib")] on extern blocks in bin crates, or
stdcall functions on 32-bit x86.
---
 src/archive.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/archive.rs b/src/archive.rs
index bd54adc53ee..22897c43e7e 100644
--- a/src/archive.rs
+++ b/src/archive.rs
@@ -254,6 +254,15 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
             }
         }
     }
+
+    fn inject_dll_import_lib(
+        &mut self,
+        _lib_name: &str,
+        _dll_imports: &[rustc_middle::middle::cstore::DllImport],
+        _tmpdir: &rustc_data_structures::temp_dir::MaybeTempDir,
+    ) {
+        bug!("injecting dll imports is not supported");
+    }
 }
 
 impl<'a> ArArchiveBuilder<'a> {

From bc9926a29bb9b4f3e5f8e9f20d881f45ebba81cc Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 5 Jun 2021 18:29:28 +0200
Subject: [PATCH 14/75] Remove unused dylib_ext variable from build.sh

---
 build.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/build.sh b/build.sh
index 76bc1884334..086b9617fdf 100755
--- a/build.sh
+++ b/build.sh
@@ -34,7 +34,6 @@ if [[ "$unamestr" == 'Linux' || "$unamestr" == "FreeBSD" ]]; then
    export RUSTFLAGS='-Clink-arg=-Wl,-rpath=$ORIGIN/../lib '$RUSTFLAGS
 elif [[ "$unamestr" == 'Darwin' ]]; then
    export RUSTFLAGS='-Csplit-debuginfo=unpacked -Clink-arg=-Wl,-rpath,@loader_path/../lib -Zosx-rpath-install-name '$RUSTFLAGS
-   dylib_ext='dylib'
 else
    echo "Unsupported os $unamestr"
    exit 1

From 20beb555655802dc84ba48185b43b61e22d808ad Mon Sep 17 00:00:00 2001
From: Luqman Aden <me@luqman.ca>
Date: Fri, 4 Jun 2021 19:47:28 -0700
Subject: [PATCH 15/75] Unify duplicate linker_and_flavor methods in
 rustc_codegen_{cranelift,ssa}.

---
 src/toolchain.rs | 90 +-----------------------------------------------
 1 file changed, 1 insertion(+), 89 deletions(-)

diff --git a/src/toolchain.rs b/src/toolchain.rs
index 49475fe2469..f86236ef3ea 100644
--- a/src/toolchain.rs
+++ b/src/toolchain.rs
@@ -2,9 +2,8 @@
 
 use std::path::PathBuf;
 
-use rustc_middle::bug;
+use rustc_codegen_ssa::back::link::linker_and_flavor;
 use rustc_session::Session;
-use rustc_target::spec::LinkerFlavor;
 
 /// Tries to infer the path of a binary for the target toolchain from the linker name.
 pub(crate) fn get_toolchain_binary(sess: &Session, tool: &str) -> PathBuf {
@@ -30,90 +29,3 @@ pub(crate) fn get_toolchain_binary(sess: &Session, tool: &str) -> PathBuf {
 
     linker
 }
-
-// Adapted from https://github.com/rust-lang/rust/blob/5db778affee7c6600c8e7a177c48282dab3f6292/src/librustc_codegen_ssa/back/link.rs#L848-L931
-fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
-    fn infer_from(
-        sess: &Session,
-        linker: Option<PathBuf>,
-        flavor: Option<LinkerFlavor>,
-    ) -> Option<(PathBuf, LinkerFlavor)> {
-        match (linker, flavor) {
-            (Some(linker), Some(flavor)) => Some((linker, flavor)),
-            // only the linker flavor is known; use the default linker for the selected flavor
-            (None, Some(flavor)) => Some((
-                PathBuf::from(match flavor {
-                    LinkerFlavor::Em => {
-                        if cfg!(windows) {
-                            "emcc.bat"
-                        } else {
-                            "emcc"
-                        }
-                    }
-                    LinkerFlavor::Gcc => {
-                        if cfg!(any(target_os = "solaris", target_os = "illumos")) {
-                            // On historical Solaris systems, "cc" may have
-                            // been Sun Studio, which is not flag-compatible
-                            // with "gcc".  This history casts a long shadow,
-                            // and many modern illumos distributions today
-                            // ship GCC as "gcc" without also making it
-                            // available as "cc".
-                            "gcc"
-                        } else {
-                            "cc"
-                        }
-                    }
-                    LinkerFlavor::Ld => "ld",
-                    LinkerFlavor::Msvc => "link.exe",
-                    LinkerFlavor::Lld(_) => "lld",
-                    LinkerFlavor::PtxLinker => "rust-ptx-linker",
-                    LinkerFlavor::BpfLinker => "bpf-linker",
-                }),
-                flavor,
-            )),
-            (Some(linker), None) => {
-                let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| {
-                    sess.fatal("couldn't extract file stem from specified linker")
-                });
-
-                let flavor = if stem == "emcc" {
-                    LinkerFlavor::Em
-                } else if stem == "gcc"
-                    || stem.ends_with("-gcc")
-                    || stem == "clang"
-                    || stem.ends_with("-clang")
-                {
-                    LinkerFlavor::Gcc
-                } else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") {
-                    LinkerFlavor::Ld
-                } else if stem == "link" || stem == "lld-link" {
-                    LinkerFlavor::Msvc
-                } else if stem == "lld" || stem == "rust-lld" {
-                    LinkerFlavor::Lld(sess.target.lld_flavor)
-                } else {
-                    // fall back to the value in the target spec
-                    sess.target.linker_flavor
-                };
-
-                Some((linker, flavor))
-            }
-            (None, None) => None,
-        }
-    }
-
-    // linker and linker flavor specified via command line have precedence over what the target
-    // specification specifies
-    if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) {
-        return ret;
-    }
-
-    if let Some(ret) = infer_from(
-        sess,
-        sess.target.linker.clone().map(PathBuf::from),
-        Some(sess.target.linker_flavor),
-    ) {
-        return ret;
-    }
-
-    bug!("Not enough information provided to determine how to invoke the linker");
-}

From a6cce1965934d7344dd77dff53dc74f3a5662d9e Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 8 Jun 2021 19:36:12 +0200
Subject: [PATCH 16/75] Rustup to rustc 1.54.0-nightly (e4a603270 2021-06-07)

---
 build_sysroot/Cargo.lock             | 2 +-
 build_sysroot/prepare_sysroot_src.sh | 2 +-
 rust-toolchain                       | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock
index 923deb9aec4..518c6ff3b3b 100644
--- a/build_sysroot/Cargo.lock
+++ b/build_sysroot/Cargo.lock
@@ -56,7 +56,7 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.43"
+version = "0.1.45"
 dependencies = [
  "rustc-std-workspace-core",
 ]
diff --git a/build_sysroot/prepare_sysroot_src.sh b/build_sysroot/prepare_sysroot_src.sh
index 54b7a94750c..7032a52a3d3 100755
--- a/build_sysroot/prepare_sysroot_src.sh
+++ b/build_sysroot/prepare_sysroot_src.sh
@@ -32,7 +32,7 @@ popd
 git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/compiler-builtins has already been cloned"
 pushd compiler-builtins
 git checkout -- .
-git checkout 0.1.43
+git checkout 0.1.45
 git apply ../../crate_patches/000*-compiler-builtins-*.patch
 popd
 
diff --git a/rust-toolchain b/rust-toolchain
index 9fe6e093a7b..92de398cc8b 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-05-26"
+channel = "nightly-2021-06-08"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

From 0d68742d37318a7eae1372a3c0ee3452d2d35bba Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 8 Jun 2021 20:12:29 +0200
Subject: [PATCH 17/75] Ignore unsupported test

---
 scripts/test_rustc_tests.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh
index 347fb40e6f9..428c2480684 100755
--- a/scripts/test_rustc_tests.sh
+++ b/scripts/test_rustc_tests.sh
@@ -64,6 +64,7 @@ rm src/test/incremental/lto.rs # requires lto
 
 rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
 rm -r src/test/run-make/unstable-flag-required # same
+rm -r src/test/run-make/emit-named-files # requires full --emit support
 
 rm src/test/pretty/asm.rs # inline asm
 rm src/test/pretty/raw-str-nonexpr.rs # same

From b7180ae39a5be0884c7be8afa61290cc1cf7451a Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 10 Jun 2021 10:16:49 +0200
Subject: [PATCH 18/75] Add missing cargo clean when cross-compiling

---
 scripts/tests.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/tests.sh b/scripts/tests.sh
index 0d99d2c507c..243a0ef2851 100755
--- a/scripts/tests.sh
+++ b/scripts/tests.sh
@@ -96,6 +96,7 @@ function extended_sysroot_tests() {
         cp ./target/debug/main ./raytracer_cg_clif
         hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
     else
+        cargo clean
         echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
         echo "[COMPILE] ebobby/simple-raytracer"
         ../build/cargo.sh build --target $TARGET_TRIPLE

From 84dd22969f79da4a417b4c424a7095522d4b83c5 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 10 Jun 2021 10:19:58 +0200
Subject: [PATCH 19/75] Include rustc and cranelift version in debuginfo

---
 src/debuginfo/mod.rs | 8 +++++---
 src/lib.rs           | 1 +
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs
index 61e54a76f29..c67336eb3f2 100644
--- a/src/debuginfo/mod.rs
+++ b/src/debuginfo/mod.rs
@@ -61,9 +61,11 @@ impl<'tcx> DebugContext<'tcx> {
 
         let mut dwarf = DwarfUnit::new(encoding);
 
-        // FIXME: how to get version when building out of tree?
-        // Normally this would use option_env!("CFG_VERSION").
-        let producer = format!("cg_clif (rustc {})", "unknown version");
+        let producer = format!(
+            "cg_clif (rustc {}, cranelift {})",
+            rustc_interface::util::version_str().unwrap_or("unknown version"),
+            cranelift_codegen::VERSION,
+        );
         let comp_dir = tcx.sess.working_dir.to_string_lossy(false).into_owned();
         let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
             Some(path) => {
diff --git a/src/lib.rs b/src/lib.rs
index 904efed5bd9..cfc5902cbe3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,7 @@ extern crate rustc_fs_util;
 extern crate rustc_hir;
 extern crate rustc_incremental;
 extern crate rustc_index;
+extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;

From ae1bcb209a010a23858ca37117a2d57464034aba Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 10 Jun 2021 10:46:00 +0200
Subject: [PATCH 20/75] Use -Cprefer-dynamic for all crates in jit mode

---
 scripts/cargo.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/cargo.sh b/scripts/cargo.sh
index 1daa5a78f7b..267b5d99a08 100755
--- a/scripts/cargo.sh
+++ b/scripts/cargo.sh
@@ -10,9 +10,9 @@ cmd=$1
 shift || true
 
 if [[ "$cmd" = "jit" ]]; then
-cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit -Cprefer-dynamic
+RUSTFLAGS="-Cprefer-dynamic" cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit
 elif [[ "$cmd" = "lazy-jit" ]]; then
-cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit-lazy -Cprefer-dynamic
+RUSTFLAGS="-Cprefer-dynamic" cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit-lazy
 else
 cargo "+${TOOLCHAIN}" "$cmd" "$@"
 fi

From 4492f32d155dcee58f9550387c38231e10570878 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 10 Jun 2021 12:17:42 +0200
Subject: [PATCH 21/75] Update Cranelift and object

---
 Cargo.lock | 53 ++++++++++++++++++++++++++++++-----------------------
 Cargo.toml |  2 +-
 2 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index a6f5925149b..964a002d92e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -33,16 +33,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "cranelift-bforest"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "cranelift-entity",
 ]
 
 [[package]]
 name = "cranelift-codegen"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "cranelift-bforest",
  "cranelift-codegen-meta",
@@ -57,8 +57,8 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-meta"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
@@ -66,18 +66,18 @@ dependencies = [
 
 [[package]]
 name = "cranelift-codegen-shared"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 
 [[package]]
 name = "cranelift-entity"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 
 [[package]]
 name = "cranelift-frontend"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -87,8 +87,8 @@ dependencies = [
 
 [[package]]
 name = "cranelift-jit"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -104,8 +104,8 @@ dependencies = [
 
 [[package]]
 name = "cranelift-module"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -115,8 +115,8 @@ dependencies = [
 
 [[package]]
 name = "cranelift-native"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "cranelift-codegen",
  "target-lexicon",
@@ -124,8 +124,8 @@ dependencies = [
 
 [[package]]
 name = "cranelift-object"
-version = "0.74.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#76c6b83f6a21a12a11d4f890490f8acb6329a600"
+version = "0.75.0"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -204,13 +204,20 @@ dependencies = [
 ]
 
 [[package]]
-name = "object"
-version = "0.24.0"
+name = "memchr"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a5b3dd1c072ee7963717671d1ca129f1048fda25edea6b752bfc71ac8854170"
+checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
+
+[[package]]
+name = "object"
+version = "0.25.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8bc1d42047cf336f0f939c99e97183cf31551bf0f2865a2ec9c8d91fd4ffb5e"
 dependencies = [
  "crc32fast",
  "indexmap",
+ "memchr",
 ]
 
 [[package]]
diff --git a/Cargo.toml b/Cargo.toml
index fd149af4547..1bd7b89ac0a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,7 +17,7 @@ cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", bran
 cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
 target-lexicon = "0.12.0"
 gimli = { version = "0.24.0", default-features = false, features = ["write"]}
-object = { version = "0.24.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
+object = { version = "0.25.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
 
 ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
 indexmap = "1.0.2"

From 75eff64977ff149ead73bc0077bac5872d599aa2 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 10 Jun 2021 12:18:10 +0200
Subject: [PATCH 22/75] Enable cross-compilation support in Cranelift

---
 Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index 1bd7b89ac0a..ef68d7ee532 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,7 +9,7 @@ crate-type = ["dylib"]
 
 [dependencies]
 # These have to be in sync with each other
-cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main", features = ["unwind"] }
+cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main", features = ["unwind", "all-arch"] }
 cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
 cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }
 cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "main" }

From d3e123fc4f8c2907db8a88e851ecb5149fa7670f Mon Sep 17 00:00:00 2001
From: Charles Lew <crlf0710@gmail.com>
Date: Mon, 14 Jun 2021 18:02:53 +0800
Subject: [PATCH 23/75] Refactor to make interpreter and codegen backend
 neutral to vtable internal representation.

---
 src/vtable.rs | 72 +++++++++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 34 deletions(-)

diff --git a/src/vtable.rs b/src/vtable.rs
index bbf07ffc85d..4d1ee47b41e 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -4,10 +4,7 @@
 // FIXME dedup this logic between miri, cg_llvm and cg_clif
 
 use crate::prelude::*;
-
-const DROP_FN_INDEX: usize = 0;
-const SIZE_INDEX: usize = 1;
-const ALIGN_INDEX: usize = 2;
+use ty::VtblEntry;
 
 fn vtable_memflags() -> MemFlags {
     let mut flags = MemFlags::trusted(); // A vtable access is always aligned and will never trap.
@@ -21,7 +18,7 @@ pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) ->
         pointer_ty(fx.tcx),
         vtable_memflags(),
         vtable,
-        (DROP_FN_INDEX * usize_size) as i32,
+        (ty::COMMON_VTABLE_ENTRIES_DROPINPLACE * usize_size) as i32,
     )
 }
 
@@ -31,7 +28,7 @@ pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Val
         pointer_ty(fx.tcx),
         vtable_memflags(),
         vtable,
-        (SIZE_INDEX * usize_size) as i32,
+        (ty::COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32,
     )
 }
 
@@ -41,7 +38,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -
         pointer_ty(fx.tcx),
         vtable_memflags(),
         vtable,
-        (ALIGN_INDEX * usize_size) as i32,
+        (ty::COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32,
     )
 }
 
@@ -62,7 +59,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
         pointer_ty(fx.tcx),
         vtable_memflags(),
         vtable,
-        ((idx + 3) * usize_size as usize) as i32,
+        (idx * usize_size as usize) as i32,
     );
     (ptr, func_ref)
 }
@@ -98,42 +95,49 @@ fn build_vtable<'tcx>(
         Instance::resolve_drop_in_place(tcx, layout.ty).polymorphize(fx.tcx),
     );
 
-    let mut components: Vec<_> = vec![Some(drop_in_place_fn), None, None];
-
-    let methods_root;
-    let methods = if let Some(trait_ref) = trait_ref {
-        methods_root = tcx.vtable_methods(trait_ref.with_self_ty(tcx, layout.ty));
-        methods_root.iter()
+    let vtable_entries = if let Some(trait_ref) = trait_ref {
+        tcx.vtable_entries(trait_ref.with_self_ty(tcx, layout.ty))
     } else {
-        (&[]).iter()
+        ty::COMMON_VTABLE_ENTRIES
     };
-    let methods = methods.cloned().map(|opt_mth| {
-        opt_mth.map(|(def_id, substs)| {
-            import_function(
-                tcx,
-                fx.module,
-                Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), def_id, substs)
-                    .unwrap()
-                    .polymorphize(fx.tcx),
-            )
-        })
-    });
-    components.extend(methods);
 
     let mut data_ctx = DataContext::new();
     let mut data = ::std::iter::repeat(0u8)
-        .take(components.len() * usize_size)
+        .take(vtable_entries.len() * usize_size)
         .collect::<Vec<u8>>()
         .into_boxed_slice();
 
-    write_usize(fx.tcx, &mut data, SIZE_INDEX, layout.size.bytes());
-    write_usize(fx.tcx, &mut data, ALIGN_INDEX, layout.align.abi.bytes());
+    for (idx, entry) in vtable_entries.iter().enumerate() {
+        match entry {
+            VtblEntry::MetadataSize => {
+                write_usize(fx.tcx, &mut data, idx, layout.size.bytes());
+            }
+            VtblEntry::MetadataAlign => {
+                write_usize(fx.tcx, &mut data, idx, layout.align.abi.bytes());
+            }
+            VtblEntry::MetadataDropInPlace | VtblEntry::Vacant | VtblEntry::Method(_, _) => {}
+        }
+    }
     data_ctx.define(data);
 
-    for (i, component) in components.into_iter().enumerate() {
-        if let Some(func_id) = component {
-            let func_ref = fx.module.declare_func_in_data(func_id, &mut data_ctx);
-            data_ctx.write_function_addr((i * usize_size) as u32, func_ref);
+    for (idx, entry) in vtable_entries.iter().enumerate() {
+        match entry {
+            VtblEntry::MetadataDropInPlace => {
+                let func_ref = fx.module.declare_func_in_data(drop_in_place_fn, &mut data_ctx);
+                data_ctx.write_function_addr((idx * usize_size) as u32, func_ref);
+            }
+            VtblEntry::Method(def_id, substs) => {
+                let func_id = import_function(
+                    tcx,
+                    fx.module,
+                    Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), *def_id, substs)
+                        .unwrap()
+                        .polymorphize(fx.tcx),
+                );
+                let func_ref = fx.module.declare_func_in_data(func_id, &mut data_ctx);
+                data_ctx.write_function_addr((idx * usize_size) as u32, func_ref);
+            }
+            VtblEntry::MetadataSize | VtblEntry::MetadataAlign | VtblEntry::Vacant => {}
         }
     }
 

From 8923e42a05b59022ffcc163d9e9b13c9de1189c9 Mon Sep 17 00:00:00 2001
From: LeSeulArtichaut <leseulartichaut@gmail.com>
Date: Mon, 14 Jun 2021 23:40:09 +0200
Subject: [PATCH 24/75] Use the now available implementation of `IntoIterator`
 for arrays

---
 src/compiler_builtins.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs
index 177f850afb3..100c3b43160 100644
--- a/src/compiler_builtins.rs
+++ b/src/compiler_builtins.rs
@@ -7,7 +7,7 @@ macro builtin_functions($register:ident; $(fn $name:ident($($arg_name:ident: $ar
 
     #[cfg(feature = "jit")]
     pub(crate) fn $register(builder: &mut cranelift_jit::JITBuilder) {
-        for &(name, val) in &[$((stringify!($name), $name as *const u8)),*] {
+        for (name, val) in [$((stringify!($name), $name as *const u8)),*] {
             builder.symbol(name, val);
         }
     }

From 432285fbc69ab0396f8226beb9fe2ef1496f73da Mon Sep 17 00:00:00 2001
From: Alexander <alex.m.vlasov@gmail.com>
Date: Tue, 15 Jun 2021 13:41:46 +0200
Subject: [PATCH 25/75] Implement llvm.x86.addcarry.64 and
 llvm.x86.subborrow.64 (#1178)

---
 src/intrinsics/llvm.rs | 60 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/src/intrinsics/llvm.rs b/src/intrinsics/llvm.rs
index ba4ed2162cd..0b5435285b4 100644
--- a/src/intrinsics/llvm.rs
+++ b/src/intrinsics/llvm.rs
@@ -106,6 +106,26 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
             let dest = CPlace::for_ptr(Pointer::new(mem_addr), a.layout());
             dest.write_cvalue(fx, a);
         };
+        "llvm.x86.addcarry.64", (v c_in, c a, c b) {
+            llvm_add_sub(
+                fx,
+                BinOp::Add,
+                ret,
+                c_in,
+                a,
+                b
+            );
+        };
+        "llvm.x86.subborrow.64", (v b_in, c a, c b) {
+            llvm_add_sub(
+                fx,
+                BinOp::Sub,
+                ret,
+                b_in,
+                a,
+                b
+            );
+        };
     }
 
     if let Some((_, dest)) = destination {
@@ -121,3 +141,43 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
 // llvm.x86.avx2.pshuf.b
 // llvm.x86.avx2.psrli.w
 // llvm.x86.sse2.psrli.w
+
+fn llvm_add_sub<'tcx>(
+    fx: &mut FunctionCx<'_, '_, 'tcx>,
+    bin_op: BinOp,
+    ret: CPlace<'tcx>,
+    cb_in: Value,
+    a: CValue<'tcx>,
+    b: CValue<'tcx>
+) {
+    assert_eq!(a.layout().ty, fx.tcx.types.u64, "llvm.x86.addcarry.64/llvm.x86.subborrow.64 second operand must be u64");
+    assert_eq!(b.layout().ty, fx.tcx.types.u64, "llvm.x86.addcarry.64/llvm.x86.subborrow.64 third operand must be u64");
+
+    // c + carry -> c + first intermediate carry or borrow respectively
+    let int0 = crate::num::codegen_checked_int_binop(
+        fx,
+        bin_op,
+        a,
+        b,
+    );
+    let c = int0.value_field(fx, mir::Field::new(0));
+    let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx);
+
+    // c + carry -> c + second intermediate carry or borrow respectively
+    let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in);
+    let cb_in_as_u64 = CValue::by_val(cb_in_as_u64, fx.layout_of(fx.tcx.types.u64));
+    let int1 = crate::num::codegen_checked_int_binop(
+        fx,
+        bin_op,
+        c,
+        cb_in_as_u64,
+    );
+    let (c, cb1) = int1.load_scalar_pair(fx);
+
+    // carry0 | carry1 -> carry or borrow respectively
+    let cb_out = fx.bcx.ins().bor(cb0, cb1);
+
+    let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter()));
+    let val = CValue::by_val_pair(cb_out, c, layout);
+    ret.write_cvalue(fx, val);
+}

From 2945b96e587e162a52c66dfaa95aec8944b11797 Mon Sep 17 00:00:00 2001
From: Alan Egerton <eggyal@gmail.com>
Date: Wed, 28 Apr 2021 14:44:18 +0100
Subject: [PATCH 26/75] Multithreading support for lazy-jit

---
 src/driver/jit.rs | 81 +++++++++++++++++++++++++++++++++++++++++++----
 src/lib.rs        |  9 +++++-
 2 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index 4a99cb727c8..3d8f837a66c 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -3,7 +3,9 @@
 
 use std::cell::RefCell;
 use std::ffi::CString;
+use std::lazy::{Lazy, SyncOnceCell};
 use std::os::raw::{c_char, c_int};
+use std::sync::{mpsc, Mutex};
 
 use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
 use rustc_codegen_ssa::CrateInfo;
@@ -23,6 +25,39 @@ thread_local! {
     static LAZY_JIT_STATE: RefCell<Option<JitState>> = RefCell::new(None);
 }
 
+/// The Sender owned by the rustc thread
+static GLOBAL_MESSAGE_SENDER: SyncOnceCell<Mutex<mpsc::Sender<UnsafeMessage>>> = SyncOnceCell::new();
+
+/// A message that is sent from the jitted runtime to the rustc thread.
+/// Senders are responsible for upholding `Send` semantics.
+enum UnsafeMessage {
+    /// Request that the specified `Instance` be lazily jitted.
+    ///
+    /// Nothing accessible through `instance_ptr` may be moved or mutated by the sender after
+    /// this message is sent.
+    JitFn {
+        instance_ptr: *const Instance<'static>,
+        tx: mpsc::Sender<*const u8>,
+    },
+}
+unsafe impl Send for UnsafeMessage {}
+
+impl UnsafeMessage {
+    /// Send the message.
+    fn send(self) -> Result<(), mpsc::SendError<UnsafeMessage>> {
+        thread_local! {
+            /// The Sender owned by the local thread
+            static LOCAL_MESSAGE_SENDER: Lazy<mpsc::Sender<UnsafeMessage>> = Lazy::new(||
+                GLOBAL_MESSAGE_SENDER
+                    .get().unwrap()
+                    .lock().unwrap()
+                    .clone()
+            );
+        }
+        LOCAL_MESSAGE_SENDER.with(|sender| sender.send(self))
+    }
+}
+
 fn create_jit_module<'tcx>(
     tcx: TyCtxt<'tcx>,
     backend_config: &BackendConfig,
@@ -116,11 +151,6 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
         .chain(backend_config.jit_args.iter().map(|arg| &**arg))
         .map(|arg| CString::new(arg).unwrap())
         .collect::<Vec<_>>();
-    let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
-
-    // Push a null pointer as a terminating argument. This is required by POSIX and
-    // useful as some dynamic linkers use it as a marker to jump over.
-    argv.push(std::ptr::null());
 
     let start_sig = Signature {
         params: vec![
@@ -141,12 +171,49 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
 
     let f: extern "C" fn(c_int, *const *const c_char) -> c_int =
         unsafe { ::std::mem::transmute(finalized_start) };
-    let ret = f(args.len() as c_int, argv.as_ptr());
-    std::process::exit(ret);
+
+    let (tx, rx) = mpsc::channel();
+    GLOBAL_MESSAGE_SENDER.set(Mutex::new(tx)).unwrap();
+
+    // Spawn the jitted runtime in a new thread so that this rustc thread can handle messages
+    // (eg to lazily JIT further functions as required)
+    std::thread::spawn(move || {
+        let mut argv = args.iter().map(|arg| arg.as_ptr()).collect::<Vec<_>>();
+
+        // Push a null pointer as a terminating argument. This is required by POSIX and
+        // useful as some dynamic linkers use it as a marker to jump over.
+        argv.push(std::ptr::null());
+
+        let ret = f(args.len() as c_int, argv.as_ptr());
+        std::process::exit(ret);
+    });
+
+    // Handle messages
+    loop {
+        match rx.recv().unwrap() {
+            // lazy JIT compilation request - compile requested instance and return pointer to result
+            UnsafeMessage::JitFn { instance_ptr, tx } => {
+                tx.send(jit_fn(instance_ptr))
+                  .expect("jitted runtime hung up before response to lazy JIT request was sent");
+            }
+        }
+    }
 }
 
 #[no_mangle]
 extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 {
+    // send the JIT request to the rustc thread, with a channel for the response
+    let (tx, rx) = mpsc::channel();
+    UnsafeMessage::JitFn { instance_ptr, tx }
+        .send()
+        .expect("rustc thread hung up before lazy JIT request was sent");
+
+    // block on JIT compilation result
+    rx.recv()
+      .expect("rustc thread hung up before responding to sent lazy JIT request")
+}
+
+fn jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 {
     rustc_middle::ty::tls::with(|tcx| {
         // lift is used to ensure the correct lifetime for instance.
         let instance = tcx.lift(unsafe { *instance_ptr }).unwrap();
diff --git a/src/lib.rs b/src/lib.rs
index cfc5902cbe3..91ef6265938 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,11 @@
-#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts)]
+#![feature(
+    rustc_private,
+    decl_macro,
+    never_type,
+    hash_drain_filter,
+    vec_into_raw_parts,
+    once_cell,
+)]
 #![warn(rust_2018_idioms)]
 #![warn(unused_lifetimes)]
 #![warn(unreachable_pub)]

From 4a7068dbfc87ab3af3fc8a1e5ca9a346c8787fcb Mon Sep 17 00:00:00 2001
From: Alan Egerton <eggyal@gmail.com>
Date: Thu, 29 Apr 2021 00:01:59 +0100
Subject: [PATCH 27/75] Ensure Instances are only jitted once

---
 src/driver/jit.rs | 28 +++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index 3d8f837a66c..39a39e764cb 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -37,6 +37,7 @@ enum UnsafeMessage {
     /// this message is sent.
     JitFn {
         instance_ptr: *const Instance<'static>,
+        trampoline_ptr: *const u8,
         tx: mpsc::Sender<*const u8>,
     },
 }
@@ -192,8 +193,8 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
     loop {
         match rx.recv().unwrap() {
             // lazy JIT compilation request - compile requested instance and return pointer to result
-            UnsafeMessage::JitFn { instance_ptr, tx } => {
-                tx.send(jit_fn(instance_ptr))
+            UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx } => {
+                tx.send(jit_fn(instance_ptr, trampoline_ptr))
                   .expect("jitted runtime hung up before response to lazy JIT request was sent");
             }
         }
@@ -201,10 +202,10 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
 }
 
 #[no_mangle]
-extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 {
+extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> *const u8 {
     // send the JIT request to the rustc thread, with a channel for the response
     let (tx, rx) = mpsc::channel();
-    UnsafeMessage::JitFn { instance_ptr, tx }
+    UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx }
         .send()
         .expect("rustc thread hung up before lazy JIT request was sent");
 
@@ -213,7 +214,7 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8
       .expect("rustc thread hung up before responding to sent lazy JIT request")
 }
 
-fn jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 {
+fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> *const u8 {
     rustc_middle::ty::tls::with(|tcx| {
         // lift is used to ensure the correct lifetime for instance.
         let instance = tcx.lift(unsafe { *instance_ptr }).unwrap();
@@ -227,6 +228,17 @@ fn jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 {
             let name = tcx.symbol_name(instance).name;
             let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
             let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap();
+
+            let current_ptr = jit_module.read_got_entry(func_id);
+
+            // If the function's GOT entry has already been updated to point at something other
+            // than the shim trampoline, don't re-jit but just return the new pointer instead.
+            // This does not need synchronization as this code is executed only by a sole rustc
+            // thread.
+            if current_ptr != trampoline_ptr {
+                return current_ptr;
+            }
+
             jit_module.prepare_for_function_redefine(func_id).unwrap();
 
             let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module.isa(), false);
@@ -321,7 +333,7 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
             Linkage::Import,
             &Signature {
                 call_conv: module.target_config().default_call_conv,
-                params: vec![AbiParam::new(pointer_type)],
+                params: vec![AbiParam::new(pointer_type), AbiParam::new(pointer_type)],
                 returns: vec![AbiParam::new(pointer_type)],
             },
         )
@@ -334,6 +346,7 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
     let mut builder_ctx = FunctionBuilderContext::new();
     let mut trampoline_builder = FunctionBuilder::new(trampoline, &mut builder_ctx);
 
+    let trampoline_fn = module.declare_func_in_func(func_id, trampoline_builder.func);
     let jit_fn = module.declare_func_in_func(jit_fn, trampoline_builder.func);
     let sig_ref = trampoline_builder.func.import_signature(sig);
 
@@ -343,7 +356,8 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx>, module: &mut JITModule, inst: In
 
     trampoline_builder.switch_to_block(entry_block);
     let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64);
-    let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]);
+    let trampoline_ptr = trampoline_builder.ins().func_addr(pointer_type, trampoline_fn);
+    let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr, trampoline_ptr]);
     let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0];
     let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args);
     let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec();

From 5c783242150f491757231e1fff1830bf1bd6a435 Mon Sep 17 00:00:00 2001
From: Alan Egerton <eggyal@gmail.com>
Date: Thu, 17 Jun 2021 09:51:04 +0100
Subject: [PATCH 28/75] Remove lack of mulithreading support from usage.md

---
 docs/usage.md | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/docs/usage.md b/docs/usage.md
index 3eee3b554e3..68e62da9ac3 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -40,8 +40,7 @@ $ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.
 ```
 
 There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
-first called. It currently does not work with multi-threaded programs. When a not yet compiled
-function is called from another thread than the main thread, you will get an ICE.
+first called.
 
 ```bash
 $ $cg_clif_dir/build/cargo.sh lazy-jit

From a12e23bc7eaf491912e4f9887db984fe25636e1e Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 17 Jun 2021 15:36:32 +0200
Subject: [PATCH 29/75] Rustup to rustc 1.55.0-nightly (a85f584ae 2021-06-16)

---
 build_sysroot/Cargo.lock | 4 ++--
 rust-toolchain           | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock
index 518c6ff3b3b..bcf692f1dc6 100644
--- a/build_sysroot/Cargo.lock
+++ b/build_sysroot/Cargo.lock
@@ -132,9 +132,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.95"
+version = "0.2.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "789da6d93f1b866ffe175afc5322a4d76c038605a1c3319bb57b06967ca98a36"
+checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
 dependencies = [
  "rustc-std-workspace-core",
 ]
diff --git a/rust-toolchain b/rust-toolchain
index 92de398cc8b..6cb05bef6d3 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-06-08"
+channel = "nightly-2021-06-17"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

From ab7f1c8a0ebc39ec0a07b806980aca38413f9e90 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 17 Jun 2021 18:41:43 +0200
Subject: [PATCH 30/75] Fix miscompilation in vtable access

Fixes #1179
---
 src/vtable.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/vtable.rs b/src/vtable.rs
index 4d1ee47b41e..3f78501bcb0 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -38,7 +38,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -
         pointer_ty(fx.tcx),
         vtable_memflags(),
         vtable,
-        (ty::COMMON_VTABLE_ENTRIES_SIZE * usize_size) as i32,
+        (ty::COMMON_VTABLE_ENTRIES_ALIGN * usize_size) as i32,
     )
 }
 

From 0ddb937624265f167f66b034422252d00801cd29 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 17 Jun 2021 18:42:09 +0200
Subject: [PATCH 31/75] Update rust patch for compiler_builtins update

---
 scripts/setup_rust_fork.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh
index 43c4887669c..b52ca6ea2ad 100644
--- a/scripts/setup_rust_fork.sh
+++ b/scripts/setup_rust_fork.sh
@@ -33,7 +33,7 @@ index d95b5b7f17f..00b6f0e3635 100644
  [dependencies]
  core = { path = "../core" }
 -compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "0.1.43", features = ['rustc-dep-of-std', 'no-asm'] }
++compiler_builtins = { version = "0.1.45", features = ['rustc-dep-of-std', 'no-asm'] }
 
  [dev-dependencies]
  rand = "0.7"

From 2db4e50618faf277aa6e7b0b45b6fc1aa5389653 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 8 Jun 2021 14:33:25 +0200
Subject: [PATCH 32/75] Rewrite build.sh in rust

This makes it easier to compile cg_clif on systems that don't support
bash shell scripts like Windows
---
 .gitignore                    |   1 +
 .vscode/settings.json         |  17 ++++
 build.sh                      |  88 ---------------------
 build_system/build_backend.rs |  41 ++++++++++
 build_system/build_sysroot.rs | 128 ++++++++++++++++++++++++++++++
 build_system/rustc_info.rs    |  41 ++++++++++
 scripts/setup_rust_fork.sh    |   2 +-
 test.sh                       |   4 +-
 y.rs                          | 141 ++++++++++++++++++++++++++++++++++
 9 files changed, 372 insertions(+), 91 deletions(-)
 delete mode 100755 build.sh
 create mode 100644 build_system/build_backend.rs
 create mode 100644 build_system/build_sysroot.rs
 create mode 100644 build_system/rustc_info.rs
 create mode 100755 y.rs

diff --git a/.gitignore b/.gitignore
index b241bef9d1e..3e010204655 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ perf.data
 perf.data.old
 *.events
 *.string*
+/y.bin
 /build
 /build_sysroot/sysroot_src
 /build_sysroot/compiler-builtins
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9009a532c54..cec110792ce 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -49,6 +49,23 @@
                     "cfg": [],
                 },
             ]
+        },
+        {
+            "roots": ["./y.rs"],
+            "crates": [
+                {
+                    "root_module": "./y.rs",
+                    "edition": "2018",
+                    "deps": [{ "crate": 1, "name": "std" }],
+                    "cfg": [],
+                },
+                {
+                    "root_module": "./build_sysroot/sysroot_src/library/std/src/lib.rs",
+                    "edition": "2018",
+                    "deps": [],
+                    "cfg": [],
+                },
+            ]
         }
     ]
 }
diff --git a/build.sh b/build.sh
deleted file mode 100755
index 086b9617fdf..00000000000
--- a/build.sh
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-# Settings
-export CHANNEL="release"
-build_sysroot="clif"
-target_dir='build'
-while [[ $# != 0 ]]; do
-    case $1 in
-        "--debug")
-            export CHANNEL="debug"
-            ;;
-        "--sysroot")
-            build_sysroot=$2
-            shift
-            ;;
-        "--target-dir")
-            target_dir=$2
-            shift
-            ;;
-        *)
-            echo "Unknown flag '$1'"
-            echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]"
-            exit 1
-            ;;
-    esac
-    shift
-done
-
-# Build cg_clif
-unset CARGO_TARGET_DIR
-unamestr=$(uname)
-if [[ "$unamestr" == 'Linux' || "$unamestr" == "FreeBSD" ]]; then
-   export RUSTFLAGS='-Clink-arg=-Wl,-rpath=$ORIGIN/../lib '$RUSTFLAGS
-elif [[ "$unamestr" == 'Darwin' ]]; then
-   export RUSTFLAGS='-Csplit-debuginfo=unpacked -Clink-arg=-Wl,-rpath,@loader_path/../lib -Zosx-rpath-install-name '$RUSTFLAGS
-else
-   echo "Unsupported os $unamestr"
-   exit 1
-fi
-if [[ "$CHANNEL" == "release" ]]; then
-    cargo build --release
-else
-    cargo build
-fi
-
-source scripts/ext_config.sh
-
-rm -rf "$target_dir"
-mkdir "$target_dir"
-mkdir "$target_dir"/bin "$target_dir"/lib
-ln target/$CHANNEL/cg_clif{,_build_sysroot} "$target_dir"/bin
-ln target/$CHANNEL/*rustc_codegen_cranelift* "$target_dir"/lib
-ln rust-toolchain scripts/config.sh scripts/cargo.sh "$target_dir"
-
-mkdir -p "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/"
-mkdir -p "$target_dir/lib/rustlib/$HOST_TRIPLE/lib/"
-if [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then
-    cp $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib/*.o "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/"
-fi
-
-case "$build_sysroot" in
-    "none")
-        ;;
-    "llvm")
-        cp -r $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib "$target_dir/lib/rustlib/$TARGET_TRIPLE/"
-        if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
-            cp -r $(rustc --print sysroot)/lib/rustlib/$HOST_TRIPLE/lib "$target_dir/lib/rustlib/$HOST_TRIPLE/"
-        fi
-        ;;
-    "clif")
-        echo "[BUILD] sysroot"
-        dir=$(pwd)
-        cd "$target_dir"
-        time "$dir/build_sysroot/build_sysroot.sh"
-        if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
-            time TARGET_TRIPLE="$HOST_TRIPLE" "$dir/build_sysroot/build_sysroot.sh"
-        fi
-        cp lib/rustlib/*/lib/libstd-* lib/
-        ;;
-    *)
-        echo "Unknown sysroot kind \`$build_sysroot\`."
-        echo "The allowed values are:"
-        echo "    none A sysroot that doesn't contain the standard library"
-        echo "    llvm Copy the sysroot from rustc compiled by cg_llvm"
-        echo "    clif Build a new sysroot using cg_clif"
-        exit 1
-esac
diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
new file mode 100644
index 00000000000..cdddeae2a33
--- /dev/null
+++ b/build_system/build_backend.rs
@@ -0,0 +1,41 @@
+use std::env;
+use std::process::{self, Command};
+
+pub(crate) fn build_backend(channel: &str) -> String {
+    let mut cmd = Command::new("cargo");
+    cmd.arg("build");
+
+    match channel {
+        "debug" => {}
+        "release" => {
+            cmd.arg("--release");
+        }
+        _ => unreachable!(),
+    }
+
+    if cfg!(unix) {
+        if cfg!(target_os = "macos") {
+            cmd.env(
+                "RUSTFLAGS",
+                "-Csplit-debuginfo=unpacked \
+                -Clink-arg=-Wl,-rpath,@loader_path/../lib \
+                -Zosx-rpath-install-name"
+                    .to_string()
+                    + env::var("RUSTFLAGS").as_deref().unwrap_or(""),
+            );
+        } else {
+            cmd.env(
+                "RUSTFLAGS",
+                "-Clink-arg=-Wl,-rpath=$ORIGIN/../lib ".to_string()
+                    + env::var("RUSTFLAGS").as_deref().unwrap_or(""),
+            );
+        }
+    }
+
+    eprintln!("[BUILD] rustc_codegen_cranelift");
+    if !cmd.spawn().unwrap().wait().unwrap().success() {
+        process::exit(1);
+    }
+
+    crate::rustc_info::get_dylib_name("rustc_codegen_cranelift")
+}
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
new file mode 100644
index 00000000000..d6ac19dd1cc
--- /dev/null
+++ b/build_system/build_sysroot.rs
@@ -0,0 +1,128 @@
+use crate::{try_hard_link, SysrootKind};
+use std::env;
+use std::fs;
+use std::path::Path;
+use std::process::{self, Command};
+
+pub(crate) fn build_sysroot(
+    channel: &str,
+    sysroot_kind: SysrootKind,
+    target_dir: &Path,
+    cg_clif_dylib: String,
+    host_triple: &str,
+    target_triple: &str,
+) {
+    if target_dir.exists() {
+        fs::remove_dir_all(target_dir).unwrap();
+    }
+    fs::create_dir_all(target_dir.join("bin")).unwrap();
+    fs::create_dir_all(target_dir.join("lib")).unwrap();
+
+    // Copy the backend
+    for file in ["cg_clif", "cg_clif_build_sysroot"] {
+        try_hard_link(
+            Path::new("target").join(channel).join(file),
+            target_dir.join("bin").join(file),
+        );
+    }
+
+    try_hard_link(
+        Path::new("target").join(channel).join(&cg_clif_dylib),
+        target_dir.join("lib").join(cg_clif_dylib),
+    );
+
+    // Copy supporting files
+    try_hard_link("rust-toolchain", target_dir.join("rust-toolchain"));
+    try_hard_link("scripts/config.sh", target_dir.join("config.sh"));
+    try_hard_link("scripts/cargo.sh", target_dir.join("cargo.sh"));
+
+    let default_sysroot = crate::rustc_info::get_default_sysroot();
+
+    let rustlib = target_dir.join("lib").join("rustlib");
+    let host_rustlib_lib = rustlib.join(host_triple).join("lib");
+    let target_rustlib_lib = rustlib.join(target_triple).join("lib");
+    fs::create_dir_all(&host_rustlib_lib).unwrap();
+    fs::create_dir_all(&target_rustlib_lib).unwrap();
+
+    if target_triple == "x86_64-pc-windows-gnu" {
+        if !default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib").exists() {
+            eprintln!(
+                "The x86_64-pc-windows-gnu target needs to be installed first before it is possible \
+                to compile a sysroot for it.",
+            );
+            process::exit(1);
+        }
+        for file in fs::read_dir(
+            default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
+        )
+        .unwrap()
+        {
+            let file = file.unwrap().path();
+            if file.extension().map_or(true, |ext| ext.to_str().unwrap() != "o") {
+                continue; // only copy object files
+            }
+            try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
+        }
+    }
+
+    match sysroot_kind {
+        SysrootKind::None => {} // Nothing to do
+        SysrootKind::Llvm => {
+            for file in fs::read_dir(
+                default_sysroot.join("lib").join("rustlib").join(host_triple).join("lib"),
+            )
+            .unwrap()
+            {
+                let file = file.unwrap().path();
+                let file_name_str = file.file_name().unwrap().to_str().unwrap();
+                if file_name_str.contains("rustc_")
+                    || file_name_str.contains("chalk")
+                    || file_name_str.contains("tracing")
+                    || file_name_str.contains("regex")
+                {
+                    // These are large crates that are part of the rustc-dev component and are not
+                    // necessary to run regular programs.
+                    continue;
+                }
+                try_hard_link(&file, host_rustlib_lib.join(file.file_name().unwrap()));
+            }
+
+            if target_triple != host_triple {
+                for file in fs::read_dir(
+                    default_sysroot.join("lib").join("rustlib").join(target_triple).join("lib"),
+                )
+                .unwrap()
+                {
+                    let file = file.unwrap().path();
+                    try_hard_link(&file, target_rustlib_lib.join(file.file_name().unwrap()));
+                }
+            }
+        }
+        SysrootKind::Clif => {
+            let cwd = env::current_dir().unwrap();
+
+            let mut cmd = Command::new(cwd.join("build_sysroot").join("build_sysroot.sh"));
+            cmd.current_dir(target_dir).env("TARGET_TRIPLE", target_triple);
+            eprintln!("[BUILD] sysroot");
+            if !cmd.spawn().unwrap().wait().unwrap().success() {
+                process::exit(1);
+            }
+
+            if host_triple != target_triple {
+                let mut cmd = Command::new(cwd.join("build_sysroot").join("build_sysroot.sh"));
+                cmd.current_dir(target_dir).env("TARGET_TRIPLE", host_triple);
+                eprintln!("[BUILD] sysroot");
+                if !cmd.spawn().unwrap().wait().unwrap().success() {
+                    process::exit(1);
+                }
+            }
+
+            for file in fs::read_dir(host_rustlib_lib).unwrap() {
+                let file = file.unwrap().path();
+                if file.file_name().unwrap().to_str().unwrap().contains("std-") {
+                    try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap()));
+                }
+            }
+        }
+    }
+}
diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs
new file mode 100644
index 00000000000..28222743022
--- /dev/null
+++ b/build_system/rustc_info.rs
@@ -0,0 +1,41 @@
+use std::path::{Path, PathBuf};
+use std::process::{Command, Stdio};
+
+pub(crate) fn get_host_triple() -> String {
+    let version_info =
+        Command::new("rustc").stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout;
+    String::from_utf8(version_info)
+        .unwrap()
+        .lines()
+        .to_owned()
+        .find(|line| line.starts_with("host"))
+        .unwrap()
+        .split(":")
+        .nth(1)
+        .unwrap()
+        .trim()
+        .to_owned()
+}
+
+pub(crate) fn get_default_sysroot() -> PathBuf {
+    let default_sysroot = Command::new("rustc")
+        .stderr(Stdio::inherit())
+        .args(&["--print", "sysroot"])
+        .output()
+        .unwrap()
+        .stdout;
+    Path::new(String::from_utf8(default_sysroot).unwrap().trim()).to_owned()
+}
+
+pub(crate) fn get_dylib_name(crate_name: &str) -> String {
+    let dylib_name = Command::new("rustc")
+        .stderr(Stdio::inherit())
+        .args(&["--crate-name", crate_name, "--crate-type", "dylib", "--print", "file-names", "-"])
+        .output()
+        .unwrap()
+        .stdout;
+    let dylib_name = String::from_utf8(dylib_name).unwrap().trim().to_owned();
+    assert!(!dylib_name.contains('\n'));
+    assert!(dylib_name.contains(crate_name));
+    dylib_name
+}
diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh
index b52ca6ea2ad..c494e78050a 100644
--- a/scripts/setup_rust_fork.sh
+++ b/scripts/setup_rust_fork.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 set -e
 
-./build.sh
+./y.rs build
 source build/config.sh
 
 echo "[SETUP] Rust fork"
diff --git a/test.sh b/test.sh
index e222adc7b80..a10924628bb 100755
--- a/test.sh
+++ b/test.sh
@@ -1,13 +1,13 @@
 #!/usr/bin/env bash
 set -e
 
-./build.sh --sysroot none "$@"
+./y.rs build --sysroot none "$@"
 
 rm -r target/out || true
 
 scripts/tests.sh no_sysroot
 
-./build.sh "$@"
+./y.rs build "$@"
 
 scripts/tests.sh base_sysroot
 scripts/tests.sh extended_sysroot
diff --git a/y.rs b/y.rs
new file mode 100755
index 00000000000..7971e713082
--- /dev/null
+++ b/y.rs
@@ -0,0 +1,141 @@
+#!/usr/bin/env bash
+#![allow()] /*This line is ignored by bash
+# This block is ignored by rustc
+set -e
+echo "[BUILD] y.rs" 1>&2
+rustc $0 -o ${0/.rs/.bin} -g
+exec ${0/.rs/.bin} $@
+*/
+
+//! The build system for cg_clif
+//!
+//! # Manual compilation
+//!
+//! If your system doesn't support shell scripts you can manually compile and run this file using
+//! for example:
+//!
+//! ```shell
+//! $ rustc y.rs -o build/y.bin
+//! $ build/y.bin
+//! ```
+//!
+//! # Naming
+//!
+//! The name `y.rs` was chosen to not conflict with rustc's `x.py`.
+
+use std::env;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::process;
+
+#[path = "build_system/build_backend.rs"]
+mod build_backend;
+#[path = "build_system/build_sysroot.rs"]
+mod build_sysroot;
+#[path = "build_system/rustc_info.rs"]
+mod rustc_info;
+
+fn usage() {
+    eprintln!("Usage:");
+    eprintln!("  ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]");
+}
+
+macro_rules! arg_error {
+    ($($err:tt)*) => {{
+        eprintln!($($err)*);
+        usage();
+        std::process::exit(1);
+    }};
+}
+
+enum Command {
+    Build,
+}
+
+#[derive(Copy, Clone)]
+enum SysrootKind {
+    None,
+    Clif,
+    Llvm,
+}
+
+fn main() {
+    env::set_var("CG_CLIF_DISPLAY_CG_TIME", "1");
+    env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
+
+    let mut args = env::args().skip(1);
+    let command = match args.next().as_deref() {
+        Some("prepare") => {
+            if args.next().is_some() {
+                arg_error!("./x.rs prepare doesn't expect arguments");
+            }
+            todo!();
+        }
+        Some("build") => Command::Build,
+        Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
+        Some(command) => arg_error!("Unknown command {}", command),
+        None => {
+            usage();
+            process::exit(0);
+        }
+    };
+
+    let mut target_dir = PathBuf::from("build");
+    let mut channel = "release";
+    let mut sysroot_kind = SysrootKind::Clif;
+    while let Some(arg) = args.next().as_deref() {
+        match arg {
+            "--target-dir" => {
+                target_dir = PathBuf::from(args.next().unwrap_or_else(|| {
+                    arg_error!("--target-dir requires argument");
+                }))
+            }
+            "--debug" => channel = "debug",
+            "--sysroot" => {
+                sysroot_kind = match args.next().as_deref() {
+                    Some("none") => SysrootKind::None,
+                    Some("clif") => SysrootKind::Clif,
+                    Some("llvm") => SysrootKind::Llvm,
+                    Some(arg) => arg_error!("Unknown sysroot kind {}", arg),
+                    None => arg_error!("--sysroot requires argument"),
+                }
+            }
+            flag if flag.starts_with("-") => arg_error!("Unknown flag {}", flag),
+            arg => arg_error!("Unexpected argument {}", arg),
+        }
+    }
+
+    let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
+        host_triple
+    } else {
+        rustc_info::get_host_triple()
+    };
+    let target_triple = if let Ok(target_triple) = std::env::var("TARGET_TRIPLE") {
+        if target_triple != "" {
+            target_triple
+        } else {
+            host_triple.clone() // Empty target triple can happen on GHA
+        }
+    } else {
+        host_triple.clone()
+    };
+
+    let cg_clif_dylib = build_backend::build_backend(channel);
+    build_sysroot::build_sysroot(
+        channel,
+        sysroot_kind,
+        &target_dir,
+        cg_clif_dylib,
+        &host_triple,
+        &target_triple,
+    );
+}
+
+#[track_caller]
+fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
+    let src = src.as_ref();
+    let dst = dst.as_ref();
+    if let Err(_) = fs::hard_link(src, dst) {
+        fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed
+    }
+}

From fe6a2892a6dd285774c3b1c84a2de45209454ce6 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 11 Jun 2021 18:50:01 +0200
Subject: [PATCH 33/75] Rewrite prepare.sh in rust

---
 .cirrus.yml                   |  2 +-
 .github/workflows/main.yml    |  2 +-
 .github/workflows/rustc.yml   |  4 +-
 Readme.md                     |  8 ++--
 build_system/build_backend.rs |  6 +--
 build_system/build_sysroot.rs |  3 +-
 build_system/prepare.rs       | 74 +++++++++++++++++++++++++++++++++++
 build_system/utils.rs         | 18 +++++++++
 docs/usage.md                 |  2 +-
 prepare.sh                    | 29 --------------
 scripts/rustup.sh             |  2 +-
 y.rs                          | 20 ++++------
 12 files changed, 114 insertions(+), 56 deletions(-)
 create mode 100644 build_system/prepare.rs
 create mode 100644 build_system/utils.rs
 delete mode 100755 prepare.sh

diff --git a/.cirrus.yml b/.cirrus.yml
index e173df423a7..61da6a2491c 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -14,7 +14,7 @@ task:
     - . $HOME/.cargo/env
     - git config --global user.email "user@example.com"
     - git config --global user.name "User"
-    - ./prepare.sh
+    - ./y.rs prepare
   test_script:
     - . $HOME/.cargo/env
     - # Enable backtraces for easier debugging
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 4d45e36c956..6734920bdd6 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -53,7 +53,7 @@ jobs:
       run: |
         git config --global user.email "user@example.com"
         git config --global user.name "User"
-        ./prepare.sh
+        ./y.rs prepare
 
     - name: Test
       env:
diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml
index e01a92598ba..1c08e5ece33 100644
--- a/.github/workflows/rustc.yml
+++ b/.github/workflows/rustc.yml
@@ -34,7 +34,7 @@ jobs:
       run: |
         git config --global user.email "user@example.com"
         git config --global user.name "User"
-        ./prepare.sh
+        ./y.rs prepare
 
     - name: Test
       run: |
@@ -72,7 +72,7 @@ jobs:
       run: |
         git config --global user.email "user@example.com"
         git config --global user.name "User"
-        ./prepare.sh
+        ./y.rs prepare
 
     - name: Test
       run: |
diff --git a/Readme.md b/Readme.md
index 08f9373be62..37644b6382c 100644
--- a/Readme.md
+++ b/Readme.md
@@ -10,8 +10,8 @@ If not please open an issue.
 ```bash
 $ git clone https://github.com/bjorn3/rustc_codegen_cranelift.git
 $ cd rustc_codegen_cranelift
-$ ./prepare.sh # download and patch sysroot src and install hyperfine for benchmarking
-$ ./build.sh
+$ ./y.rs prepare # download and patch sysroot src and install hyperfine for benchmarking
+$ ./y.rs build
 ```
 
 To run the test suite replace the last command with:
@@ -20,7 +20,7 @@ To run the test suite replace the last command with:
 $ ./test.sh
 ```
 
-This will implicitly build cg_clif too. Both `build.sh` and `test.sh` accept a `--debug` argument to
+This will implicitly build cg_clif too. Both `y.rs build` and `test.sh` accept a `--debug` argument to
 build in debug mode.
 
 Alternatively you can download a pre built version from [GHA]. It is listed in the artifacts section
@@ -32,7 +32,7 @@ of workflow runs. Unfortunately due to GHA restrictions you need to be logged in
 
 rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
 
-Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`).
+Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`y.rs prepare` and `y.rs build` or `test.sh`).
 
 In the directory with your project (where you can do the usual `cargo build`), run:
 
diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
index cdddeae2a33..81c47fa8358 100644
--- a/build_system/build_backend.rs
+++ b/build_system/build_backend.rs
@@ -1,5 +1,5 @@
 use std::env;
-use std::process::{self, Command};
+use std::process::Command;
 
 pub(crate) fn build_backend(channel: &str) -> String {
     let mut cmd = Command::new("cargo");
@@ -33,9 +33,7 @@ pub(crate) fn build_backend(channel: &str) -> String {
     }
 
     eprintln!("[BUILD] rustc_codegen_cranelift");
-    if !cmd.spawn().unwrap().wait().unwrap().success() {
-        process::exit(1);
-    }
+    crate::utils::spawn_and_wait(cmd);
 
     crate::rustc_info::get_dylib_name("rustc_codegen_cranelift")
 }
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index d6ac19dd1cc..60906a8f19a 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -1,4 +1,5 @@
-use crate::{try_hard_link, SysrootKind};
+use crate::utils::try_hard_link;
+use crate::SysrootKind;
 use std::env;
 use std::fs;
 use std::path::Path;
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
new file mode 100644
index 00000000000..4aef9162594
--- /dev/null
+++ b/build_system/prepare.rs
@@ -0,0 +1,74 @@
+use std::ffi::OsStr;
+use std::ffi::OsString;
+use std::fs;
+use std::process::Command;
+
+use crate::utils::spawn_and_wait;
+
+pub(crate) fn prepare() {
+    // FIXME implement in rust
+    let prepare_sysroot_cmd = Command::new("./build_sysroot/prepare_sysroot_src.sh");
+    spawn_and_wait(prepare_sysroot_cmd);
+
+    eprintln!("[INSTALL] hyperfine");
+    Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
+
+    clone_repo(
+        "rand",
+        "https://github.com/rust-random/rand.git",
+        "0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
+    );
+
+    eprintln!("[PATCH] rand");
+    for patch in get_patches("crate_patches", "rand") {
+        let mut patch_arg = OsString::from("../crate_patches/");
+        patch_arg.push(patch);
+        let mut apply_patch_cmd = Command::new("git");
+        apply_patch_cmd.arg("am").arg(patch_arg).current_dir("rand");
+        spawn_and_wait(apply_patch_cmd);
+    }
+
+    clone_repo(
+        "regex",
+        "https://github.com/rust-lang/regex.git",
+        "341f207c1071f7290e3f228c710817c280c8dca1",
+    );
+
+    clone_repo(
+        "simple-raytracer",
+        "https://github.com/ebobby/simple-raytracer",
+        "804a7a21b9e673a482797aa289a18ed480e4d813",
+    );
+
+    eprintln!("[LLVM BUILD] simple-raytracer");
+    let mut build_cmd = Command::new("cargo");
+    build_cmd.arg("build").env_remove("CARGO_TARGET_DIR").current_dir("simple-raytracer");
+    spawn_and_wait(build_cmd);
+    fs::copy("simple-raytracer/target/debug/main", "simple-raytracer/raytracer_cg_llvm").unwrap();
+}
+
+fn clone_repo(name: &str, repo: &str, commit: &str) {
+    eprintln!("[CLONE] {}", repo);
+    // Ignore exit code as the repo may already have been checked out
+    Command::new("git").arg("clone").arg(repo).spawn().unwrap().wait().unwrap();
+
+    let mut clean_cmd = Command::new("git");
+    clean_cmd.arg("checkout").arg("--").arg(".").current_dir(name);
+    spawn_and_wait(clean_cmd);
+
+    let mut checkout_cmd = Command::new("git");
+    checkout_cmd.arg("checkout").arg(commit).current_dir(name);
+    spawn_and_wait(checkout_cmd);
+}
+
+fn get_patches(patch_dir: &str, crate_name: &str) -> Vec<OsString> {
+    let mut patches: Vec<_> = fs::read_dir(patch_dir)
+        .unwrap()
+        .map(|entry| entry.unwrap().path())
+        .filter(|path| path.extension() == Some(OsStr::new("patch")))
+        .map(|path| path.file_name().unwrap().to_owned())
+        .filter(|file_name| file_name.to_str().unwrap().split("-").nth(1).unwrap() == crate_name)
+        .collect();
+    patches.sort();
+    patches
+}
diff --git a/build_system/utils.rs b/build_system/utils.rs
new file mode 100644
index 00000000000..3eba87ee8a4
--- /dev/null
+++ b/build_system/utils.rs
@@ -0,0 +1,18 @@
+use std::fs;
+use std::path::Path;
+use std::process::{self, Command};
+
+#[track_caller]
+pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
+    let src = src.as_ref();
+    let dst = dst.as_ref();
+    if let Err(_) = fs::hard_link(src, dst) {
+        fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed
+    }
+}
+
+pub(crate) fn spawn_and_wait(mut cmd: Command) {
+    if !cmd.spawn().unwrap().wait().unwrap().success() {
+        process::exit(1);
+    }
+}
diff --git a/docs/usage.md b/docs/usage.md
index 3eee3b554e3..7e1e0a9bc9d 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -2,7 +2,7 @@
 
 rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects.
 
-Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`).
+Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`y.rs prepare` and `y.rs build` or `test.sh`).
 
 ## Cargo
 
diff --git a/prepare.sh b/prepare.sh
deleted file mode 100755
index 64c097261c9..00000000000
--- a/prepare.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/env bash
-set -e
-
-./build_sysroot/prepare_sysroot_src.sh
-cargo install hyperfine || echo "Skipping hyperfine install"
-
-git clone https://github.com/rust-random/rand.git || echo "rust-random/rand has already been cloned"
-pushd rand
-git checkout -- .
-git checkout 0f933f9c7176e53b2a3c7952ded484e1783f0bf1
-git am ../crate_patches/*-rand-*.patch
-popd
-
-git clone https://github.com/rust-lang/regex.git || echo "rust-lang/regex has already been cloned"
-pushd regex
-git checkout -- .
-git checkout 341f207c1071f7290e3f228c710817c280c8dca1
-popd
-
-git clone https://github.com/ebobby/simple-raytracer || echo "ebobby/simple-raytracer has already been cloned"
-pushd simple-raytracer
-git checkout -- .
-git checkout 804a7a21b9e673a482797aa289a18ed480e4d813
-
-# build with cg_llvm for perf comparison
-unset CARGO_TARGET_DIR
-cargo build
-mv target/debug/main raytracer_cg_llvm
-popd
diff --git a/scripts/rustup.sh b/scripts/rustup.sh
index fa7557653d8..cc34c080886 100755
--- a/scripts/rustup.sh
+++ b/scripts/rustup.sh
@@ -17,7 +17,7 @@ case $1 in
         done
 
         ./clean_all.sh
-        ./prepare.sh
+        ./y.rs prepare
 
         (cd build_sysroot && cargo update)
 
diff --git a/y.rs b/y.rs
index 7971e713082..62debc117c3 100755
--- a/y.rs
+++ b/y.rs
@@ -24,19 +24,23 @@ exec ${0/.rs/.bin} $@
 //! The name `y.rs` was chosen to not conflict with rustc's `x.py`.
 
 use std::env;
-use std::fs;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use std::process;
 
 #[path = "build_system/build_backend.rs"]
 mod build_backend;
 #[path = "build_system/build_sysroot.rs"]
 mod build_sysroot;
+#[path = "build_system/prepare.rs"]
+mod prepare;
 #[path = "build_system/rustc_info.rs"]
 mod rustc_info;
+#[path = "build_system/utils.rs"]
+mod utils;
 
 fn usage() {
     eprintln!("Usage:");
+    eprintln!("  ./y.rs prepare");
     eprintln!("  ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]");
 }
 
@@ -69,7 +73,8 @@ fn main() {
             if args.next().is_some() {
                 arg_error!("./x.rs prepare doesn't expect arguments");
             }
-            todo!();
+            prepare::prepare();
+            process::exit(0);
         }
         Some("build") => Command::Build,
         Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
@@ -130,12 +135,3 @@ fn main() {
         &target_triple,
     );
 }
-
-#[track_caller]
-fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
-    let src = src.as_ref();
-    let dst = dst.as_ref();
-    if let Err(_) = fs::hard_link(src, dst) {
-        fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed
-    }
-}

From 066d5f952cfb0c5d22d4ee31d6ac716b2d16668d Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Wed, 16 Jun 2021 18:01:19 +0200
Subject: [PATCH 34/75] Rewrite prepare_sysroot_src.sh in rust

---
 build_sysroot/prepare_sysroot_src.sh          | 39 ---------
 build_system/prepare.rs                       | 87 +++++++++++++++----
 build_system/rustc_info.rs                    | 10 +++
 build_system/utils.rs                         | 17 ++++
 ...sysroot-Disable-not-compiling-tests.patch} |  0
 ...> 0023-sysroot-Ignore-failing-tests.patch} |  0
 ...27-sysroot-128bit-atomic-operations.patch} |  0
 7 files changed, 97 insertions(+), 56 deletions(-)
 delete mode 100755 build_sysroot/prepare_sysroot_src.sh
 rename patches/{0022-core-Disable-not-compiling-tests.patch => 0022-sysroot-Disable-not-compiling-tests.patch} (100%)
 rename patches/{0023-core-Ignore-failing-tests.patch => 0023-sysroot-Ignore-failing-tests.patch} (100%)
 rename patches/{0027-Disable-128bit-atomic-operations.patch => 0027-sysroot-128bit-atomic-operations.patch} (100%)

diff --git a/build_sysroot/prepare_sysroot_src.sh b/build_sysroot/prepare_sysroot_src.sh
deleted file mode 100755
index 7032a52a3d3..00000000000
--- a/build_sysroot/prepare_sysroot_src.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-set -e
-cd "$(dirname "$0")"
-
-SRC_DIR="$(dirname "$(rustup which rustc)")/../lib/rustlib/src/rust/"
-DST_DIR="sysroot_src"
-
-if [ ! -e "$SRC_DIR" ]; then
-    echo "Please install rust-src component"
-    exit 1
-fi
-
-rm -rf $DST_DIR
-mkdir -p $DST_DIR/library
-cp -a "$SRC_DIR/library" $DST_DIR/
-
-pushd $DST_DIR
-echo "[GIT] init"
-git init
-echo "[GIT] add"
-git add .
-echo "[GIT] commit"
-git commit -m "Initial commit" -q
-for file in $(ls ../../patches/ | grep -v patcha); do
-echo "[GIT] apply" "$file"
-git apply ../../patches/"$file"
-git add -A
-git commit --no-gpg-sign -m "Patch $file"
-done
-popd
-
-git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/compiler-builtins has already been cloned"
-pushd compiler-builtins
-git checkout -- .
-git checkout 0.1.45
-git apply ../../crate_patches/000*-compiler-builtins-*.patch
-popd
-
-echo "Successfully prepared sysroot source for building"
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index 4aef9162594..b6d6457163d 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -1,14 +1,16 @@
 use std::ffi::OsStr;
 use std::ffi::OsString;
 use std::fs;
+use std::path::Path;
+use std::path::PathBuf;
 use std::process::Command;
 
+use crate::rustc_info::get_rustc_path;
+use crate::utils::copy_dir_recursively;
 use crate::utils::spawn_and_wait;
 
 pub(crate) fn prepare() {
-    // FIXME implement in rust
-    let prepare_sysroot_cmd = Command::new("./build_sysroot/prepare_sysroot_src.sh");
-    spawn_and_wait(prepare_sysroot_cmd);
+    prepare_sysroot();
 
     eprintln!("[INSTALL] hyperfine");
     Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
@@ -18,15 +20,7 @@ pub(crate) fn prepare() {
         "https://github.com/rust-random/rand.git",
         "0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
     );
-
-    eprintln!("[PATCH] rand");
-    for patch in get_patches("crate_patches", "rand") {
-        let mut patch_arg = OsString::from("../crate_patches/");
-        patch_arg.push(patch);
-        let mut apply_patch_cmd = Command::new("git");
-        apply_patch_cmd.arg("am").arg(patch_arg).current_dir("rand");
-        spawn_and_wait(apply_patch_cmd);
-    }
+    apply_patches("crate_patches", "rand", Path::new("rand"));
 
     clone_repo(
         "regex",
@@ -47,17 +41,64 @@ pub(crate) fn prepare() {
     fs::copy("simple-raytracer/target/debug/main", "simple-raytracer/raytracer_cg_llvm").unwrap();
 }
 
-fn clone_repo(name: &str, repo: &str, commit: &str) {
+fn prepare_sysroot() {
+    let rustc_path = get_rustc_path();
+    let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
+    let sysroot_src = PathBuf::from("build_sysroot").canonicalize().unwrap().join("sysroot_src");
+
+    assert!(sysroot_src_orig.exists());
+
+    if sysroot_src.exists() {
+        fs::remove_dir_all(&sysroot_src).unwrap();
+    }
+    fs::create_dir_all(sysroot_src.join("library")).unwrap();
+    eprintln!("[COPY] sysroot src");
+    copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
+
+    eprintln!("[GIT] init");
+    let mut git_init_cmd = Command::new("git");
+    git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src);
+    spawn_and_wait(git_init_cmd);
+
+    let mut git_add_cmd = Command::new("git");
+    git_add_cmd.arg("add").arg(".").current_dir(&sysroot_src);
+    spawn_and_wait(git_add_cmd);
+
+    let mut git_commit_cmd = Command::new("git");
+    git_commit_cmd
+        .arg("commit")
+        .arg("-m")
+        .arg("Initial commit")
+        .arg("-q")
+        .current_dir(&sysroot_src);
+    spawn_and_wait(git_commit_cmd);
+
+    apply_patches("patches", "sysroot", &sysroot_src);
+
+    clone_repo(
+        "build_sysroot/compiler-builtins",
+        "https://github.com/rust-lang/compiler-builtins.git",
+        "0.1.45",
+    );
+
+    apply_patches(
+        "crate_patches",
+        "compiler-builtins",
+        Path::new("build_sysroot/compiler-builtins"),
+    );
+}
+
+fn clone_repo(target_dir: &str, repo: &str, rev: &str) {
     eprintln!("[CLONE] {}", repo);
     // Ignore exit code as the repo may already have been checked out
-    Command::new("git").arg("clone").arg(repo).spawn().unwrap().wait().unwrap();
+    Command::new("git").arg("clone").arg(repo).arg(target_dir).spawn().unwrap().wait().unwrap();
 
     let mut clean_cmd = Command::new("git");
-    clean_cmd.arg("checkout").arg("--").arg(".").current_dir(name);
+    clean_cmd.arg("checkout").arg("--").arg(".").current_dir(target_dir);
     spawn_and_wait(clean_cmd);
 
     let mut checkout_cmd = Command::new("git");
-    checkout_cmd.arg("checkout").arg(commit).current_dir(name);
+    checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(target_dir);
     spawn_and_wait(checkout_cmd);
 }
 
@@ -67,8 +108,20 @@ fn get_patches(patch_dir: &str, crate_name: &str) -> Vec<OsString> {
         .map(|entry| entry.unwrap().path())
         .filter(|path| path.extension() == Some(OsStr::new("patch")))
         .map(|path| path.file_name().unwrap().to_owned())
-        .filter(|file_name| file_name.to_str().unwrap().split("-").nth(1).unwrap() == crate_name)
+        .filter(|file_name| {
+            file_name.to_str().unwrap().split_once("-").unwrap().1.starts_with(crate_name)
+        })
         .collect();
     patches.sort();
     patches
 }
+
+fn apply_patches(patch_dir: &str, crate_name: &str, target_dir: &Path) {
+    for patch in get_patches(patch_dir, crate_name) {
+        eprintln!("[PATCH] {:?} <- {:?}", target_dir.file_name().unwrap(), patch);
+        let patch_arg = Path::new(patch_dir).join(patch).canonicalize().unwrap();
+        let mut apply_patch_cmd = Command::new("git");
+        apply_patch_cmd.arg("am").arg(patch_arg).arg("-q").current_dir(target_dir);
+        spawn_and_wait(apply_patch_cmd);
+    }
+}
diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs
index 28222743022..f7f5d42fe09 100644
--- a/build_system/rustc_info.rs
+++ b/build_system/rustc_info.rs
@@ -17,6 +17,16 @@ pub(crate) fn get_host_triple() -> String {
         .to_owned()
 }
 
+pub(crate) fn get_rustc_path() -> PathBuf {
+    let rustc_path = Command::new("rustup")
+        .stderr(Stdio::inherit())
+        .args(&["which", "rustc"])
+        .output()
+        .unwrap()
+        .stdout;
+    Path::new(String::from_utf8(rustc_path).unwrap().trim()).to_owned()
+}
+
 pub(crate) fn get_default_sysroot() -> PathBuf {
     let default_sysroot = Command::new("rustc")
         .stderr(Stdio::inherit())
diff --git a/build_system/utils.rs b/build_system/utils.rs
index 3eba87ee8a4..12b5d70fad8 100644
--- a/build_system/utils.rs
+++ b/build_system/utils.rs
@@ -11,8 +11,25 @@ pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
     }
 }
 
+#[track_caller]
 pub(crate) fn spawn_and_wait(mut cmd: Command) {
     if !cmd.spawn().unwrap().wait().unwrap().success() {
         process::exit(1);
     }
 }
+
+pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
+    for entry in fs::read_dir(from).unwrap() {
+        let entry = entry.unwrap();
+        let filename = entry.file_name();
+        if filename == "." || filename == ".." {
+            continue;
+        }
+        if entry.metadata().unwrap().is_dir() {
+            fs::create_dir(to.join(&filename)).unwrap();
+            copy_dir_recursively(&from.join(&filename), &to.join(&filename));
+        } else {
+            fs::copy(from.join(&filename), to.join(&filename)).unwrap();
+        }
+    }
+}
diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-sysroot-Disable-not-compiling-tests.patch
similarity index 100%
rename from patches/0022-core-Disable-not-compiling-tests.patch
rename to patches/0022-sysroot-Disable-not-compiling-tests.patch
diff --git a/patches/0023-core-Ignore-failing-tests.patch b/patches/0023-sysroot-Ignore-failing-tests.patch
similarity index 100%
rename from patches/0023-core-Ignore-failing-tests.patch
rename to patches/0023-sysroot-Ignore-failing-tests.patch
diff --git a/patches/0027-Disable-128bit-atomic-operations.patch b/patches/0027-sysroot-128bit-atomic-operations.patch
similarity index 100%
rename from patches/0027-Disable-128bit-atomic-operations.patch
rename to patches/0027-sysroot-128bit-atomic-operations.patch

From d71b12535e84a7c242cf217af49a0366b06c8691 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Wed, 16 Jun 2021 18:28:34 +0200
Subject: [PATCH 35/75] Merge the crate_patches dir into the patches dir

---
 build_system/prepare.rs                       | 21 +++++++------------
 ...ins-Disable-128bit-atomic-operations.patch |  0
 ...1-rand-Enable-c2-chacha-simd-feature.patch |  0
 .../0002-rand-Disable-failing-test.patch      |  0
 4 files changed, 8 insertions(+), 13 deletions(-)
 rename {crate_patches => patches}/0001-compiler-builtins-Disable-128bit-atomic-operations.patch (100%)
 rename {crate_patches => patches}/0001-rand-Enable-c2-chacha-simd-feature.patch (100%)
 rename {crate_patches => patches}/0002-rand-Disable-failing-test.patch (100%)

diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index b6d6457163d..b5011ceb159 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -20,7 +20,7 @@ pub(crate) fn prepare() {
         "https://github.com/rust-random/rand.git",
         "0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
     );
-    apply_patches("crate_patches", "rand", Path::new("rand"));
+    apply_patches("rand", Path::new("rand"));
 
     clone_repo(
         "regex",
@@ -73,19 +73,14 @@ fn prepare_sysroot() {
         .current_dir(&sysroot_src);
     spawn_and_wait(git_commit_cmd);
 
-    apply_patches("patches", "sysroot", &sysroot_src);
+    apply_patches("sysroot", &sysroot_src);
 
     clone_repo(
         "build_sysroot/compiler-builtins",
         "https://github.com/rust-lang/compiler-builtins.git",
         "0.1.45",
     );
-
-    apply_patches(
-        "crate_patches",
-        "compiler-builtins",
-        Path::new("build_sysroot/compiler-builtins"),
-    );
+    apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
 }
 
 fn clone_repo(target_dir: &str, repo: &str, rev: &str) {
@@ -102,8 +97,8 @@ fn clone_repo(target_dir: &str, repo: &str, rev: &str) {
     spawn_and_wait(checkout_cmd);
 }
 
-fn get_patches(patch_dir: &str, crate_name: &str) -> Vec<OsString> {
-    let mut patches: Vec<_> = fs::read_dir(patch_dir)
+fn get_patches(crate_name: &str) -> Vec<OsString> {
+    let mut patches: Vec<_> = fs::read_dir("patches")
         .unwrap()
         .map(|entry| entry.unwrap().path())
         .filter(|path| path.extension() == Some(OsStr::new("patch")))
@@ -116,10 +111,10 @@ fn get_patches(patch_dir: &str, crate_name: &str) -> Vec<OsString> {
     patches
 }
 
-fn apply_patches(patch_dir: &str, crate_name: &str, target_dir: &Path) {
-    for patch in get_patches(patch_dir, crate_name) {
+fn apply_patches(crate_name: &str, target_dir: &Path) {
+    for patch in get_patches(crate_name) {
         eprintln!("[PATCH] {:?} <- {:?}", target_dir.file_name().unwrap(), patch);
-        let patch_arg = Path::new(patch_dir).join(patch).canonicalize().unwrap();
+        let patch_arg = Path::new("patches").join(patch).canonicalize().unwrap();
         let mut apply_patch_cmd = Command::new("git");
         apply_patch_cmd.arg("am").arg(patch_arg).arg("-q").current_dir(target_dir);
         spawn_and_wait(apply_patch_cmd);
diff --git a/crate_patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch b/patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch
similarity index 100%
rename from crate_patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch
rename to patches/0001-compiler-builtins-Disable-128bit-atomic-operations.patch
diff --git a/crate_patches/0001-rand-Enable-c2-chacha-simd-feature.patch b/patches/0001-rand-Enable-c2-chacha-simd-feature.patch
similarity index 100%
rename from crate_patches/0001-rand-Enable-c2-chacha-simd-feature.patch
rename to patches/0001-rand-Enable-c2-chacha-simd-feature.patch
diff --git a/crate_patches/0002-rand-Disable-failing-test.patch b/patches/0002-rand-Disable-failing-test.patch
similarity index 100%
rename from crate_patches/0002-rand-Disable-failing-test.patch
rename to patches/0002-rand-Disable-failing-test.patch

From ad971bbed773cad7cb446b49b07c64504e9a79fb Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 18 Jun 2021 13:27:56 +0200
Subject: [PATCH 36/75] Rewrite build_sysroot.sh in rust

---
 build_sysroot/build_sysroot.sh | 39 --------------------
 build_system/build_sysroot.rs  | 66 ++++++++++++++++++++++++++--------
 y.rs                           |  2 ++
 3 files changed, 53 insertions(+), 54 deletions(-)
 delete mode 100755 build_sysroot/build_sysroot.sh

diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh
deleted file mode 100755
index 0354304e55b..00000000000
--- a/build_sysroot/build_sysroot.sh
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env bash
-
-# Requires the CHANNEL env var to be set to `debug` or `release.`
-
-set -e
-
-source ./config.sh
-
-dir=$(pwd)
-
-# Use rustc with cg_clif as hotpluggable backend instead of the custom cg_clif driver so that
-# build scripts are still compiled using cg_llvm.
-export RUSTC=$dir"/bin/cg_clif_build_sysroot"
-export RUSTFLAGS=$RUSTFLAGS" --clif"
-
-cd "$(dirname "$0")"
-
-# Cleanup for previous run
-#     v Clean target dir except for build scripts and incremental cache
-rm -r target/*/{debug,release}/{build,deps,examples,libsysroot*,native} 2>/dev/null || true
-
-# We expect the target dir in the default location. Guard against the user changing it.
-export CARGO_TARGET_DIR=target
-
-# Build libs
-export RUSTFLAGS="$RUSTFLAGS -Zforce-unstable-if-unmarked -Cpanic=abort"
-export __CARGO_DEFAULT_LIB_METADATA="cg_clif"
-if [[ "$1" != "--debug" ]]; then
-    sysroot_channel='release'
-    # FIXME Enable incremental again once rust-lang/rust#74946 is fixed
-    CARGO_INCREMENTAL=0 RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=3" cargo build --target "$TARGET_TRIPLE" --release
-else
-    sysroot_channel='debug'
-    cargo build --target "$TARGET_TRIPLE"
-fi
-
-# Copy files to sysroot
-ln "target/$TARGET_TRIPLE/$sysroot_channel/deps/"* "$dir/lib/rustlib/$TARGET_TRIPLE/lib/"
-rm "$dir/lib/rustlib/$TARGET_TRIPLE/lib/"*.{rmeta,d}
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 60906a8f19a..9988b35b363 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -1,6 +1,6 @@
+use crate::utils::spawn_and_wait;
 use crate::utils::try_hard_link;
 use crate::SysrootKind;
-use std::env;
 use std::fs;
 use std::path::Path;
 use std::process::{self, Command};
@@ -100,24 +100,14 @@ pub(crate) fn build_sysroot(
             }
         }
         SysrootKind::Clif => {
-            let cwd = env::current_dir().unwrap();
-
-            let mut cmd = Command::new(cwd.join("build_sysroot").join("build_sysroot.sh"));
-            cmd.current_dir(target_dir).env("TARGET_TRIPLE", target_triple);
-            eprintln!("[BUILD] sysroot");
-            if !cmd.spawn().unwrap().wait().unwrap().success() {
-                process::exit(1);
-            }
+            build_clif_sysroot_for_triple(channel, target_dir, target_triple);
 
             if host_triple != target_triple {
-                let mut cmd = Command::new(cwd.join("build_sysroot").join("build_sysroot.sh"));
-                cmd.current_dir(target_dir).env("TARGET_TRIPLE", host_triple);
-                eprintln!("[BUILD] sysroot");
-                if !cmd.spawn().unwrap().wait().unwrap().success() {
-                    process::exit(1);
-                }
+                build_clif_sysroot_for_triple(channel, target_dir, host_triple);
             }
 
+            // Copy std for the host to the lib dir. This is necessary for the jit mode to find
+            // libstd.
             for file in fs::read_dir(host_rustlib_lib).unwrap() {
                 let file = file.unwrap().path();
                 if file.file_name().unwrap().to_str().unwrap().contains("std-") {
@@ -127,3 +117,49 @@ pub(crate) fn build_sysroot(
         }
     }
 }
+
+fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str) {
+    let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
+
+    // FIXME add option to skip this
+    // Cleanup the target dir with the exception of build scripts and the incremental cache
+    for dir in ["build", "deps", "examples", "native"] {
+        if build_dir.join(dir).exists() {
+            fs::remove_dir_all(build_dir.join(dir)).unwrap();
+        }
+    }
+
+    // Build sysroot
+    let mut build_cmd = Command::new("cargo");
+    build_cmd.arg("build").arg("--target").arg(triple).current_dir("build_sysroot");
+    let mut rustflags = "--clif -Zforce-unstable-if-unmarked".to_string();
+    if channel == "release" {
+        build_cmd.arg("--release");
+        rustflags.push_str(" -Zmir-opt-level=3");
+    }
+    build_cmd.env("RUSTFLAGS", rustflags);
+    build_cmd
+        .env("RUSTC", target_dir.join("bin").join("cg_clif_build_sysroot").canonicalize().unwrap());
+    // FIXME Enable incremental again once rust-lang/rust#74946 is fixed
+    build_cmd.env("CARGO_INCREMENTAL", "0").env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
+    spawn_and_wait(build_cmd);
+
+    // Copy all relevant files to the sysroot
+    for entry in
+        fs::read_dir(Path::new("build_sysroot/target").join(triple).join(channel).join("deps"))
+            .unwrap()
+    {
+        let entry = entry.unwrap();
+        if let Some(ext) = entry.path().extension() {
+            if ext == "rmeta" || ext == "d" || ext == "dSYM" {
+                continue;
+            }
+        } else {
+            continue;
+        };
+        try_hard_link(
+            entry.path(),
+            target_dir.join("lib").join("rustlib").join(triple).join("lib").join(entry.file_name()),
+        );
+    }
+}
diff --git a/y.rs b/y.rs
index 62debc117c3..27ab44f5870 100755
--- a/y.rs
+++ b/y.rs
@@ -66,6 +66,8 @@ enum SysrootKind {
 fn main() {
     env::set_var("CG_CLIF_DISPLAY_CG_TIME", "1");
     env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
+    // The target dir is expected in the default location. Guard against the user changing it.
+    env::set_var("CARGO_TARGET_DIR", "target");
 
     let mut args = env::args().skip(1);
     let command = match args.next().as_deref() {

From 0d6b3dab658d76078741cc78b0bda1682b43a7ec Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 18 Jun 2021 13:35:58 +0200
Subject: [PATCH 37/75] Allow preserving the old sysroot

---
 build_system/build_sysroot.rs | 13 ++++++++-----
 config.txt                    |  7 +++++++
 2 files changed, 15 insertions(+), 5 deletions(-)
 create mode 100644 config.txt

diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 9988b35b363..fb34875f50f 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -121,11 +121,14 @@ pub(crate) fn build_sysroot(
 fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str) {
     let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
 
-    // FIXME add option to skip this
-    // Cleanup the target dir with the exception of build scripts and the incremental cache
-    for dir in ["build", "deps", "examples", "native"] {
-        if build_dir.join(dir).exists() {
-            fs::remove_dir_all(build_dir.join(dir)).unwrap();
+    let keep_sysroot =
+        fs::read_to_string("config.txt").unwrap().lines().any(|line| line.trim() == "keep_sysroot");
+    if !keep_sysroot {
+        // Cleanup the target dir with the exception of build scripts and the incremental cache
+        for dir in ["build", "deps", "examples", "native"] {
+            if build_dir.join(dir).exists() {
+                fs::remove_dir_all(build_dir.join(dir)).unwrap();
+            }
         }
     }
 
diff --git a/config.txt b/config.txt
new file mode 100644
index 00000000000..f707b9322af
--- /dev/null
+++ b/config.txt
@@ -0,0 +1,7 @@
+# This file allows configuring the build system.
+
+# Disables cleaning of the sysroot dir. This will cause old compiled artifacts to be re-used when
+# the sysroot source hasn't changed. This is useful when the codegen backend hasn't been modified.
+# This option can be changed while the build system is already running for as long as sysroot
+# building hasn't started yet.
+#keep_sysroot

From e5563b50772e45dc2ad9111769f48d216570af71 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 18 Jun 2021 13:38:50 +0200
Subject: [PATCH 38/75] Improve windows support

---
 build_system/build_backend.rs |  2 +-
 build_system/build_sysroot.rs | 35 ++++++++++++++++++++++++-----------
 build_system/prepare.rs       | 18 +++++++++++-------
 build_system/rustc_info.rs    | 22 +++++++++++++++-------
 4 files changed, 51 insertions(+), 26 deletions(-)

diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
index 81c47fa8358..db046be1866 100644
--- a/build_system/build_backend.rs
+++ b/build_system/build_backend.rs
@@ -35,5 +35,5 @@ pub(crate) fn build_backend(channel: &str) -> String {
     eprintln!("[BUILD] rustc_codegen_cranelift");
     crate::utils::spawn_and_wait(cmd);
 
-    crate::rustc_info::get_dylib_name("rustc_codegen_cranelift")
+    crate::rustc_info::get_file_name("rustc_codegen_cranelift", "dylib")
 }
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index fb34875f50f..547159438e9 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -1,10 +1,12 @@
-use crate::utils::spawn_and_wait;
-use crate::utils::try_hard_link;
-use crate::SysrootKind;
+use std::env;
 use std::fs;
 use std::path::Path;
 use std::process::{self, Command};
 
+use crate::rustc_info::get_file_name;
+use crate::utils::{spawn_and_wait, try_hard_link};
+use crate::SysrootKind;
+
 pub(crate) fn build_sysroot(
     channel: &str,
     sysroot_kind: SysrootKind,
@@ -22,15 +24,24 @@ pub(crate) fn build_sysroot(
     // Copy the backend
     for file in ["cg_clif", "cg_clif_build_sysroot"] {
         try_hard_link(
-            Path::new("target").join(channel).join(file),
-            target_dir.join("bin").join(file),
+            Path::new("target").join(channel).join(get_file_name(file, "bin")),
+            target_dir.join("bin").join(get_file_name(file, "bin")),
         );
     }
 
-    try_hard_link(
-        Path::new("target").join(channel).join(&cg_clif_dylib),
-        target_dir.join("lib").join(cg_clif_dylib),
-    );
+    if cfg!(windows) {
+        // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
+        // binaries.
+        try_hard_link(
+            Path::new("target").join(channel).join(&cg_clif_dylib),
+            target_dir.join("bin").join(cg_clif_dylib),
+        );
+    } else {
+        try_hard_link(
+            Path::new("target").join(channel).join(&cg_clif_dylib),
+            target_dir.join("lib").join(cg_clif_dylib),
+        );
+    }
 
     // Copy supporting files
     try_hard_link("rust-toolchain", target_dir.join("rust-toolchain"));
@@ -141,8 +152,10 @@ fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str)
         rustflags.push_str(" -Zmir-opt-level=3");
     }
     build_cmd.env("RUSTFLAGS", rustflags);
-    build_cmd
-        .env("RUSTC", target_dir.join("bin").join("cg_clif_build_sysroot").canonicalize().unwrap());
+    build_cmd.env(
+        "RUSTC",
+        env::current_dir().unwrap().join(target_dir).join("bin").join("cg_clif_build_sysroot"),
+    );
     // FIXME Enable incremental again once rust-lang/rust#74946 is fixed
     build_cmd.env("CARGO_INCREMENTAL", "0").env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
     spawn_and_wait(build_cmd);
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index b5011ceb159..d26f24f8856 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -1,13 +1,12 @@
+use std::env;
 use std::ffi::OsStr;
 use std::ffi::OsString;
 use std::fs;
 use std::path::Path;
-use std::path::PathBuf;
 use std::process::Command;
 
-use crate::rustc_info::get_rustc_path;
-use crate::utils::copy_dir_recursively;
-use crate::utils::spawn_and_wait;
+use crate::rustc_info::{get_file_name, get_rustc_path};
+use crate::utils::{copy_dir_recursively, spawn_and_wait};
 
 pub(crate) fn prepare() {
     prepare_sysroot();
@@ -38,13 +37,18 @@ pub(crate) fn prepare() {
     let mut build_cmd = Command::new("cargo");
     build_cmd.arg("build").env_remove("CARGO_TARGET_DIR").current_dir("simple-raytracer");
     spawn_and_wait(build_cmd);
-    fs::copy("simple-raytracer/target/debug/main", "simple-raytracer/raytracer_cg_llvm").unwrap();
+    fs::copy(
+        Path::new("simple-raytracer/target/debug").join(get_file_name("main", "bin")),
+        // FIXME use get_file_name here too once testing is migrated to rust
+        "simple-raytracer/raytracer_cg_llvm",
+    )
+    .unwrap();
 }
 
 fn prepare_sysroot() {
     let rustc_path = get_rustc_path();
     let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
-    let sysroot_src = PathBuf::from("build_sysroot").canonicalize().unwrap().join("sysroot_src");
+    let sysroot_src = env::current_dir().unwrap().join("build_sysroot").join("sysroot_src");
 
     assert!(sysroot_src_orig.exists());
 
@@ -114,7 +118,7 @@ fn get_patches(crate_name: &str) -> Vec<OsString> {
 fn apply_patches(crate_name: &str, target_dir: &Path) {
     for patch in get_patches(crate_name) {
         eprintln!("[PATCH] {:?} <- {:?}", target_dir.file_name().unwrap(), patch);
-        let patch_arg = Path::new("patches").join(patch).canonicalize().unwrap();
+        let patch_arg = env::current_dir().unwrap().join("patches").join(patch);
         let mut apply_patch_cmd = Command::new("git");
         apply_patch_cmd.arg("am").arg(patch_arg).arg("-q").current_dir(target_dir);
         spawn_and_wait(apply_patch_cmd);
diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs
index f7f5d42fe09..3bf86d9a114 100644
--- a/build_system/rustc_info.rs
+++ b/build_system/rustc_info.rs
@@ -37,15 +37,23 @@ pub(crate) fn get_default_sysroot() -> PathBuf {
     Path::new(String::from_utf8(default_sysroot).unwrap().trim()).to_owned()
 }
 
-pub(crate) fn get_dylib_name(crate_name: &str) -> String {
-    let dylib_name = Command::new("rustc")
+pub(crate) fn get_file_name(crate_name: &str, crate_type: &str) -> String {
+    let file_name = Command::new("rustc")
         .stderr(Stdio::inherit())
-        .args(&["--crate-name", crate_name, "--crate-type", "dylib", "--print", "file-names", "-"])
+        .args(&[
+            "--crate-name",
+            crate_name,
+            "--crate-type",
+            crate_type,
+            "--print",
+            "file-names",
+            "-",
+        ])
         .output()
         .unwrap()
         .stdout;
-    let dylib_name = String::from_utf8(dylib_name).unwrap().trim().to_owned();
-    assert!(!dylib_name.contains('\n'));
-    assert!(dylib_name.contains(crate_name));
-    dylib_name
+    let file_name = String::from_utf8(file_name).unwrap().trim().to_owned();
+    assert!(!file_name.contains('\n'));
+    assert!(file_name.contains(crate_name));
+    file_name
 }

From b0d7b526d96fc428123444d8852e6ab5674f809e Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 18 Jun 2021 13:41:20 +0200
Subject: [PATCH 39/75] [CI] Test compilation on Windows

---
 .github/workflows/main.yml | 60 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 6734920bdd6..4442cbe5f94 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -87,3 +87,63 @@ jobs:
       with:
         name: cg_clif-${{ runner.os }}-cross-x86_64-mingw
         path: cg_clif.tar.xz
+
+  build_windows:
+    runs-on: windows-latest
+    timeout-minutes: 60
+
+    steps:
+    - uses: actions/checkout@v2
+
+    #- name: Cache cargo installed crates
+    #  uses: actions/cache@v2
+    #  with:
+    #    path: ~/.cargo/bin
+    #    key: ${{ runner.os }}-cargo-installed-crates
+
+    #- name: Cache cargo registry and index
+    #  uses: actions/cache@v2
+    #  with:
+    #    path: |
+    #        ~/.cargo/registry
+    #        ~/.cargo/git
+    #    key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
+
+    #- name: Cache cargo target dir
+    #  uses: actions/cache@v2
+    #  with:
+    #    path: target
+    #    key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
+
+    - name: Prepare dependencies
+      run: |
+        git config --global user.email "user@example.com"
+        git config --global user.name "User"
+        git config --global core.autocrlf false
+        rustup set default-host x86_64-pc-windows-gnu
+        rustc y.rs -o y.exe -g
+        ./y.exe prepare
+
+    - name: Build
+      #name: Test
+      run: |
+        # Enable backtraces for easier debugging
+        #export RUST_BACKTRACE=1
+
+        # Reduce amount of benchmark runs as they are slow
+        #export COMPILE_RUNS=2
+        #export RUN_RUNS=2
+
+        # Enable extra checks
+        #export CG_CLIF_ENABLE_VERIFIER=1
+
+        ./y.exe build
+
+    #- name: Package prebuilt cg_clif
+    #  run: tar cvfJ cg_clif.tar.xz build
+
+    #- name: Upload prebuilt cg_clif
+    #  uses: actions/upload-artifact@v2
+    #  with:
+    #    name: cg_clif-${{ runner.os }}
+    #    path: cg_clif.tar.xz

From bc67726882cc368e6aa382ea97c616d666d9b11d Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 18 Jun 2021 16:18:44 +0200
Subject: [PATCH 40/75] Update rust-analyzer import assist config

---
 .vscode/settings.json | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index cec110792ce..38ffef5ac99 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,7 +1,9 @@
 {
     // source for rustc_* is not included in the rust-src component; disable the errors about this
     "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
-    "rust-analyzer.assist.importMergeBehavior": "last",
+    "rust-analyzer.assist.importGranularity": "module",
+    "rust-analyzer.assist.importEnforceGranularity": true,
+    "rust-analyzer.assist.importPrefix": "by_crate",
     "rust-analyzer.cargo.runBuildScripts": true,
     "rust-analyzer.linkedProjects": [
         "./Cargo.toml",

From d571910f4dd057d26c7c2f483a4b3a813e292d00 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 19 Jun 2021 14:07:56 +0200
Subject: [PATCH 41/75] Give an error when attempting to build for MSVC

---
 y.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/y.rs b/y.rs
index 27ab44f5870..55457745d25 100755
--- a/y.rs
+++ b/y.rs
@@ -127,6 +127,14 @@ fn main() {
         host_triple.clone()
     };
 
+    if target_triple.ends_with("-msvc") {
+        eprintln!("The MSVC toolchain is not yet supported by rustc_codegen_cranelift.");
+        eprintln!("Switch to the MinGW toolchain for Windows support.");
+        eprintln!("Hint: You can use `rustup set default-host x86_64-pc-windows-gnu` to");
+        eprintln!("set the global default target to MinGW");
+        process::exit(1);
+    }
+
     let cg_clif_dylib = build_backend::build_backend(channel);
     build_sysroot::build_sysroot(
         channel,

From 9fd8fa21231e488c3f784e811b9f7c7548561594 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 19 Jun 2021 14:51:48 +0200
Subject: [PATCH 42/75] Move some things from config.sh to ext_config.sh

---
 scripts/config.sh     | 5 -----
 scripts/ext_config.sh | 5 +++++
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/scripts/config.sh b/scripts/config.sh
index 99b302ee1d9..1aeed266d9a 100644
--- a/scripts/config.sh
+++ b/scripts/config.sh
@@ -18,10 +18,5 @@ export RUSTC=$dir"/bin/cg_clif"
 export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\
 '-Zcodegen-backend='$dir'/lib/'$dylib' --sysroot '$dir
 
-# FIXME fix `#[linkage = "extern_weak"]` without this
-if [[ "$(uname)" == 'Darwin' ]]; then
-   export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup"
-fi
-
 export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:"$dir"/lib"
 export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
diff --git a/scripts/ext_config.sh b/scripts/ext_config.sh
index 3f98d77d76c..9f8331865ce 100644
--- a/scripts/ext_config.sh
+++ b/scripts/ext_config.sh
@@ -25,3 +25,8 @@ if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then
       echo "Unknown non-native platform"
    fi
 fi
+
+# FIXME fix `#[linkage = "extern_weak"]` without this
+if [[ "$(uname)" == 'Darwin' ]]; then
+   export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup"
+fi

From b497c7d9549ebb576d0212d53088ab9d48aa9cef Mon Sep 17 00:00:00 2001
From: Camille GILLOT <gillot.camille@gmail.com>
Date: Tue, 11 May 2021 22:05:54 +0200
Subject: [PATCH 43/75] Make allocator_kind a query.

---
 src/allocator.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/allocator.rs b/src/allocator.rs
index 357a9f2daf7..d39486c2f10 100644
--- a/src/allocator.rs
+++ b/src/allocator.rs
@@ -19,7 +19,7 @@ pub(crate) fn codegen(
     });
     if any_dynamic_crate {
         false
-    } else if let Some(kind) = tcx.allocator_kind() {
+    } else if let Some(kind) = tcx.allocator_kind(()) {
         codegen_inner(module, unwind_context, kind);
         true
     } else {

From 80e9188fb1a404427513e080b8a27ac262769614 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 20 Jun 2021 12:41:40 +0200
Subject: [PATCH 44/75] Rewrite cargo.sh in rust

---
 Readme.md                     |  2 +-
 build_system/build_sysroot.rs | 12 +++--
 docs/usage.md                 |  6 +--
 scripts/cargo.rs              | 85 +++++++++++++++++++++++++++++++++++
 scripts/cargo.sh              | 18 --------
 scripts/config.sh             | 17 +------
 scripts/ext_config.sh         |  2 +-
 scripts/filter_profile.rs     |  5 ++-
 scripts/setup_rust_fork.sh    |  2 +-
 scripts/tests.sh              | 35 ++++++++-------
 10 files changed, 121 insertions(+), 63 deletions(-)
 create mode 100644 scripts/cargo.rs
 delete mode 100755 scripts/cargo.sh

diff --git a/Readme.md b/Readme.md
index 37644b6382c..dad8ed90b53 100644
--- a/Readme.md
+++ b/Readme.md
@@ -37,7 +37,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
 In the directory with your project (where you can do the usual `cargo build`), run:
 
 ```bash
-$ $cg_clif_dir/build/cargo.sh build
+$ $cg_clif_dir/build/cargo build
 ```
 
 This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 547159438e9..507af3f9aa7 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -43,10 +43,14 @@ pub(crate) fn build_sysroot(
         );
     }
 
-    // Copy supporting files
-    try_hard_link("rust-toolchain", target_dir.join("rust-toolchain"));
-    try_hard_link("scripts/config.sh", target_dir.join("config.sh"));
-    try_hard_link("scripts/cargo.sh", target_dir.join("cargo.sh"));
+    // Build and copy cargo wrapper
+    let mut build_cargo_wrapper_cmd = Command::new("rustc");
+    build_cargo_wrapper_cmd
+        .arg("scripts/cargo.rs")
+        .arg("-o")
+        .arg(target_dir.join("cargo"))
+        .arg("-g");
+    spawn_and_wait(build_cargo_wrapper_cmd);
 
     let default_sysroot = crate::rustc_info::get_default_sysroot();
 
diff --git a/docs/usage.md b/docs/usage.md
index 7e1e0a9bc9d..aac44b62d01 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -9,7 +9,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
 In the directory with your project (where you can do the usual `cargo build`), run:
 
 ```bash
-$ $cg_clif_dir/build/cargo.sh build
+$ $cg_clif_dir/build/cargo build
 ```
 
 This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
@@ -30,7 +30,7 @@ In jit mode cg_clif will immediately execute your code without creating an execu
 > The jit mode will probably need cargo integration to make this possible.
 
 ```bash
-$ $cg_clif_dir/build/cargo.sh jit
+$ $cg_clif_dir/build/cargo jit
 ```
 
 or
@@ -44,7 +44,7 @@ first called. It currently does not work with multi-threaded programs. When a no
 function is called from another thread than the main thread, you will get an ICE.
 
 ```bash
-$ $cg_clif_dir/build/cargo.sh lazy-jit
+$ $cg_clif_dir/build/cargo lazy-jit
 ```
 
 ## Shell
diff --git a/scripts/cargo.rs b/scripts/cargo.rs
new file mode 100644
index 00000000000..543e7c19276
--- /dev/null
+++ b/scripts/cargo.rs
@@ -0,0 +1,85 @@
+use std::env;
+use std::os::unix::process::CommandExt;
+use std::path::PathBuf;
+use std::process::{Command, Stdio};
+
+fn main() {
+    if env::var("RUSTC_WRAPPER").map_or(false, |wrapper| wrapper.contains("sccache")) {
+        eprintln!(
+            "\x1b[1;93m=== Warning: Unsetting RUSTC_WRAPPER to prevent interference with sccache ===\x1b[0m"
+        );
+        env::remove_var("RUSTC_WRAPPER");
+    }
+
+    let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap());
+
+    env::set_var("RUSTC", sysroot.join("bin/cg_clif".to_string() + env::consts::EXE_SUFFIX));
+
+    let mut rustdoc_flags = env::var("RUSTDOCFLAGS").unwrap_or(String::new());
+    rustdoc_flags.push_str(" -Cpanic=abort -Zpanic-abort-tests -Zcodegen-backend=");
+    rustdoc_flags.push_str(
+        sysroot
+            .join(if cfg!(windows) { "bin" } else { "lib" })
+            .join(
+                env::consts::DLL_PREFIX.to_string()
+                    + "rustc_codegen_cranelift"
+                    + env::consts::DLL_SUFFIX,
+            )
+            .to_str()
+            .unwrap(),
+    );
+    rustdoc_flags.push_str(" --sysroot ");
+    rustdoc_flags.push_str(sysroot.to_str().unwrap());
+    env::set_var("RUSTDOCFLAGS", rustdoc_flags);
+
+    let default_sysroot = Command::new("rustc")
+        .stderr(Stdio::inherit())
+        .args(&["--print", "sysroot"])
+        .output()
+        .unwrap()
+        .stdout;
+    let default_sysroot = std::str::from_utf8(&default_sysroot).unwrap().trim();
+
+    let extra_ld_lib_path =
+        default_sysroot.to_string() + ":" + sysroot.join("lib").to_str().unwrap();
+    if cfg!(target_os = "macos") {
+        env::set_var(
+            "DYLD_LIBRARY_PATH",
+            env::var("DYLD_LIBRARY_PATH").unwrap_or(String::new()) + ":" + &extra_ld_lib_path,
+        );
+    } else if cfg!(unix) {
+        env::set_var(
+            "LD_LIBRARY_PATH",
+            env::var("LD_LIBRARY_PATH").unwrap_or(String::new()) + ":" + &extra_ld_lib_path,
+        );
+    }
+
+    // Ensure that the right toolchain is used
+    env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN"));
+
+    let args: Vec<_> = match env::args().nth(1).as_deref() {
+        Some("jit") => {
+            env::set_var(
+                "RUSTFLAGS",
+                env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
+            );
+            std::array::IntoIter::new(["rustc".to_string()])
+                .chain(env::args().skip(2))
+                .chain(["--".to_string(), "-Cllvm-args=mode=jit".to_string()])
+                .collect()
+        }
+        Some("lazy-jit") => {
+            env::set_var(
+                "RUSTFLAGS",
+                env::var("RUSTFLAGS").unwrap_or(String::new()) + " -Cprefer-dynamic",
+            );
+            std::array::IntoIter::new(["rustc".to_string()])
+                .chain(env::args().skip(2))
+                .chain(["--".to_string(), "-Cllvm-args=mode=jit-lazy".to_string()])
+                .collect()
+        }
+        _ => env::args().skip(1).collect(),
+    };
+
+    Command::new("cargo").args(args).exec();
+}
diff --git a/scripts/cargo.sh b/scripts/cargo.sh
deleted file mode 100755
index 267b5d99a08..00000000000
--- a/scripts/cargo.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env bash
-
-dir=$(dirname "$0")
-source "$dir/config.sh"
-
-# read nightly compiler from rust-toolchain file
-TOOLCHAIN=$(cat "$dir/rust-toolchain" | grep channel | sed "s/channel = \"\(.*\)\"/\1/")
-
-cmd=$1
-shift || true
-
-if [[ "$cmd" = "jit" ]]; then
-RUSTFLAGS="-Cprefer-dynamic" cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit
-elif [[ "$cmd" = "lazy-jit" ]]; then
-RUSTFLAGS="-Cprefer-dynamic" cargo "+${TOOLCHAIN}" rustc "$@" -- -Cllvm-args=mode=jit-lazy
-else
-cargo "+${TOOLCHAIN}" "$cmd" "$@"
-fi
diff --git a/scripts/config.sh b/scripts/config.sh
index 1aeed266d9a..cf325ab574e 100644
--- a/scripts/config.sh
+++ b/scripts/config.sh
@@ -2,21 +2,6 @@
 
 set -e
 
-dylib=$(echo "" | rustc --print file-names --crate-type dylib --crate-name rustc_codegen_cranelift -)
-
-if echo "$RUSTC_WRAPPER" | grep sccache; then
-echo
-echo -e "\x1b[1;93m=== Warning: Unset RUSTC_WRAPPER to prevent interference with sccache ===\x1b[0m"
-echo
-export RUSTC_WRAPPER=
-fi
-
-dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd)
-
-export RUSTC=$dir"/bin/cg_clif"
-
-export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\
-'-Zcodegen-backend='$dir'/lib/'$dylib' --sysroot '$dir
-
+dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../build"; pwd)
 export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:"$dir"/lib"
 export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
diff --git a/scripts/ext_config.sh b/scripts/ext_config.sh
index 9f8331865ce..11d6c4c8318 100644
--- a/scripts/ext_config.sh
+++ b/scripts/ext_config.sh
@@ -1,6 +1,6 @@
 # Note to people running shellcheck: this file should only be sourced, not executed directly.
 
-# Various env vars that should only be set for the build system but not for cargo.sh
+# Various env vars that should only be set for the build system
 
 set -e
 
diff --git a/scripts/filter_profile.rs b/scripts/filter_profile.rs
index 15388926ec9..9e196afbe4f 100755
--- a/scripts/filter_profile.rs
+++ b/scripts/filter_profile.rs
@@ -2,9 +2,10 @@
 #![forbid(unsafe_code)]/* This line is ignored by bash
 # This block is ignored by rustc
 pushd $(dirname "$0")/../
-source build/config.sh
+source scripts/config.sh
+RUSTC="$(pwd)/build/bin/cg_clif"
 popd
-PROFILE=$1 OUTPUT=$2 exec $RUSTC $RUSTFLAGS -Cllvm-args=mode=jit -Cprefer-dynamic $0
+PROFILE=$1 OUTPUT=$2 exec $RUSTC -Cllvm-args=mode=jit -Cprefer-dynamic $0
 #*/
 
 //! This program filters away uninteresting samples and trims uninteresting frames for stackcollapse
diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh
index c494e78050a..52adaaa8de6 100644
--- a/scripts/setup_rust_fork.sh
+++ b/scripts/setup_rust_fork.sh
@@ -2,7 +2,7 @@
 set -e
 
 ./y.rs build
-source build/config.sh
+source scripts/config.sh
 
 echo "[SETUP] Rust fork"
 git clone https://github.com/rust-lang/rust.git || true
diff --git a/scripts/tests.sh b/scripts/tests.sh
index 243a0ef2851..c875aad2849 100755
--- a/scripts/tests.sh
+++ b/scripts/tests.sh
@@ -2,9 +2,10 @@
 
 set -e
 
-source build/config.sh
+source scripts/config.sh
 source scripts/ext_config.sh
-MY_RUSTC="$RUSTC $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2"
+export RUSTC=false # ensure that cg_llvm isn't accidentally used
+MY_RUSTC="$(pwd)/build/bin/cg_clif $RUSTFLAGS -L crate=target/out --out-dir target/out -Cdebuginfo=2"
 
 function no_sysroot_tests() {
     echo "[BUILD] mini_core"
@@ -75,64 +76,64 @@ function base_sysroot_tests() {
 
 function extended_sysroot_tests() {
     pushd rand
-    cargo clean
+    ../build/cargo clean
     if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
         echo "[TEST] rust-random/rand"
-        ../build/cargo.sh test --workspace
+        ../build/cargo test --workspace
     else
         echo "[AOT] rust-random/rand"
-        ../build/cargo.sh build --workspace --target $TARGET_TRIPLE --tests
+        ../build/cargo build --workspace --target $TARGET_TRIPLE --tests
     fi
     popd
 
     pushd simple-raytracer
     if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
         echo "[BENCH COMPILE] ebobby/simple-raytracer"
-        hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "cargo clean" \
+        hyperfine --runs "${RUN_RUNS:-10}" --warmup 1 --prepare "../build/cargo clean" \
         "RUSTC=rustc RUSTFLAGS='' cargo build" \
-        "../build/cargo.sh build"
+        "../build/cargo build"
 
         echo "[BENCH RUN] ebobby/simple-raytracer"
         cp ./target/debug/main ./raytracer_cg_clif
         hyperfine --runs "${RUN_RUNS:-10}" ./raytracer_cg_llvm ./raytracer_cg_clif
     else
-        cargo clean
+        ../build/cargo clean
         echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)"
         echo "[COMPILE] ebobby/simple-raytracer"
-        ../build/cargo.sh build --target $TARGET_TRIPLE
+        ../build/cargo build --target $TARGET_TRIPLE
         echo "[BENCH RUN] ebobby/simple-raytracer (skipped)"
     fi
     popd
 
     pushd build_sysroot/sysroot_src/library/core/tests
     echo "[TEST] libcore"
-    cargo clean
+    ../../../../../build/cargo clean
     if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
-        ../../../../../build/cargo.sh test
+        ../../../../../build/cargo test
     else
-        ../../../../../build/cargo.sh build --target $TARGET_TRIPLE --tests
+        ../../../../../build/cargo build --target $TARGET_TRIPLE --tests
     fi
     popd
 
     pushd regex
     echo "[TEST] rust-lang/regex example shootout-regex-dna"
-    cargo clean
+    ../build/cargo clean
     export RUSTFLAGS="$RUSTFLAGS --cap-lints warn" # newer aho_corasick versions throw a deprecation warning
     # Make sure `[codegen mono items] start` doesn't poison the diff
-    ../build/cargo.sh build --example shootout-regex-dna --target $TARGET_TRIPLE
+    ../build/cargo build --example shootout-regex-dna --target $TARGET_TRIPLE
     if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
         cat examples/regexdna-input.txt \
-            | ../build/cargo.sh run --example shootout-regex-dna --target $TARGET_TRIPLE \
+            | ../build/cargo run --example shootout-regex-dna --target $TARGET_TRIPLE \
             | grep -v "Spawned thread" > res.txt
         diff -u res.txt examples/regexdna-output.txt
     fi
 
     if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then
         echo "[TEST] rust-lang/regex tests"
-        ../build/cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
+        ../build/cargo test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q
     else
         echo "[AOT] rust-lang/regex tests"
-        ../build/cargo.sh build --tests --target $TARGET_TRIPLE
+        ../build/cargo build --tests --target $TARGET_TRIPLE
     fi
     popd
 }

From 62e49c5b61c196c942e644c0b81b0f4b232bd461 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 20 Jun 2021 13:20:51 +0200
Subject: [PATCH 45/75] Fix compiling cargo.rs on windows

---
 scripts/cargo.rs | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/scripts/cargo.rs b/scripts/cargo.rs
index 543e7c19276..fdb9bcf6dbc 100644
--- a/scripts/cargo.rs
+++ b/scripts/cargo.rs
@@ -1,4 +1,5 @@
 use std::env;
+#[cfg(unix)]
 use std::os::unix::process::CommandExt;
 use std::path::PathBuf;
 use std::process::{Command, Stdio};
@@ -81,5 +82,11 @@ fn main() {
         _ => env::args().skip(1).collect(),
     };
 
+    #[cfg(unix)]
     Command::new("cargo").args(args).exec();
+
+    #[cfg(not(unix))]
+    std::process::exit(
+        Command::new("cargo").args(args).spawn().unwrap().wait().unwrap().code().unwrap_or(1),
+    );
 }

From 03c9ecfb306f00fa39595c63d062f7ab98d6f19f Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 20 Jun 2021 14:40:49 +0200
Subject: [PATCH 46/75] Remove unnecessary LD_LIBRARY_PATH parts

---
 scripts/cargo.rs  | 14 --------------
 scripts/config.sh |  3 +--
 2 files changed, 1 insertion(+), 16 deletions(-)

diff --git a/scripts/cargo.rs b/scripts/cargo.rs
index fdb9bcf6dbc..5cb352a1aff 100644
--- a/scripts/cargo.rs
+++ b/scripts/cargo.rs
@@ -41,20 +41,6 @@ fn main() {
         .stdout;
     let default_sysroot = std::str::from_utf8(&default_sysroot).unwrap().trim();
 
-    let extra_ld_lib_path =
-        default_sysroot.to_string() + ":" + sysroot.join("lib").to_str().unwrap();
-    if cfg!(target_os = "macos") {
-        env::set_var(
-            "DYLD_LIBRARY_PATH",
-            env::var("DYLD_LIBRARY_PATH").unwrap_or(String::new()) + ":" + &extra_ld_lib_path,
-        );
-    } else if cfg!(unix) {
-        env::set_var(
-            "LD_LIBRARY_PATH",
-            env::var("LD_LIBRARY_PATH").unwrap_or(String::new()) + ":" + &extra_ld_lib_path,
-        );
-    }
-
     // Ensure that the right toolchain is used
     env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN"));
 
diff --git a/scripts/config.sh b/scripts/config.sh
index cf325ab574e..d316a7c6981 100644
--- a/scripts/config.sh
+++ b/scripts/config.sh
@@ -2,6 +2,5 @@
 
 set -e
 
-dir=$(cd "$(dirname "${BASH_SOURCE[0]}")/../build"; pwd)
-export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:"$dir"/lib"
+export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib"
 export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH

From 089d986c5c9ce6237013a4842f3093e721d4f589 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 20 Jun 2021 18:26:17 +0200
Subject: [PATCH 47/75] Remove unused variable

---
 scripts/cargo.rs | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/scripts/cargo.rs b/scripts/cargo.rs
index 5cb352a1aff..b7e8dd44974 100644
--- a/scripts/cargo.rs
+++ b/scripts/cargo.rs
@@ -2,7 +2,7 @@ use std::env;
 #[cfg(unix)]
 use std::os::unix::process::CommandExt;
 use std::path::PathBuf;
-use std::process::{Command, Stdio};
+use std::process::Command;
 
 fn main() {
     if env::var("RUSTC_WRAPPER").map_or(false, |wrapper| wrapper.contains("sccache")) {
@@ -33,14 +33,6 @@ fn main() {
     rustdoc_flags.push_str(sysroot.to_str().unwrap());
     env::set_var("RUSTDOCFLAGS", rustdoc_flags);
 
-    let default_sysroot = Command::new("rustc")
-        .stderr(Stdio::inherit())
-        .args(&["--print", "sysroot"])
-        .output()
-        .unwrap()
-        .stdout;
-    let default_sysroot = std::str::from_utf8(&default_sysroot).unwrap().trim();
-
     // Ensure that the right toolchain is used
     env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN"));
 

From 57c6eb7b2ba4375039d289e84e51e9e784b08f31 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 25 Jun 2021 17:49:43 +0200
Subject: [PATCH 48/75] Test multithreading support in lazy-jit

---
 example/std_example.rs | 2 --
 scripts/tests.sh       | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/example/std_example.rs b/example/std_example.rs
index 7d608df9253..5bc51a541b5 100644
--- a/example/std_example.rs
+++ b/example/std_example.rs
@@ -15,8 +15,6 @@ fn main() {
     let stderr = ::std::io::stderr();
     let mut stderr = stderr.lock();
 
-    // FIXME support lazy jit when multi threading
-    #[cfg(not(lazy_jit))]
     std::thread::spawn(move || {
         println!("Hello from another thread!");
     });
diff --git a/scripts/tests.sh b/scripts/tests.sh
index 243a0ef2851..9bbda6b8059 100755
--- a/scripts/tests.sh
+++ b/scripts/tests.sh
@@ -46,7 +46,7 @@ function base_sysroot_tests() {
         $MY_RUSTC -Cllvm-args=mode=jit -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
 
         echo "[JIT-lazy] std_example"
-        $MY_RUSTC -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/std_example.rs --cfg lazy_jit --target "$HOST_TRIPLE"
+        $MY_RUSTC -Cllvm-args=mode=jit-lazy -Cprefer-dynamic example/std_example.rs --target "$HOST_TRIPLE"
     else
         echo "[JIT] std_example (skipped)"
     fi

From 4d289dba2ea409672600c571004fee64ec931a10 Mon Sep 17 00:00:00 2001
From: Charles Lew <crlf0710@gmail.com>
Date: Sun, 20 Jun 2021 17:43:25 +0800
Subject: [PATCH 49/75] Update other codegens to use tcx managed vtable
 allocations.

---
 src/common.rs   |   2 +-
 src/constant.rs |   2 +-
 src/lib.rs      |   2 +-
 src/unsize.rs   |   4 +-
 src/vtable.rs   | 108 +++++-------------------------------------------
 5 files changed, 15 insertions(+), 103 deletions(-)

diff --git a/src/common.rs b/src/common.rs
index 488ff6e1349..a8a0bb52a24 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -233,7 +233,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
     pub(crate) module: &'m mut dyn Module,
     pub(crate) tcx: TyCtxt<'tcx>,
     pub(crate) pointer_type: Type, // Cached from module
-    pub(crate) vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
+    pub(crate) vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Pointer>,
     pub(crate) constants_cx: ConstantCx,
 
     pub(crate) instance: Instance<'tcx>,
diff --git a/src/constant.rs b/src/constant.rs
index 3ba12c4e96d..a87b3703949 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -249,7 +249,7 @@ pub(crate) fn codegen_const_value<'tcx>(
     }
 }
 
-fn pointer_for_allocation<'tcx>(
+pub(crate) fn pointer_for_allocation<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     alloc: &'tcx Allocation,
 ) -> crate::pointer::Pointer {
diff --git a/src/lib.rs b/src/lib.rs
index 6aadaf8a7ca..b817bf4aff7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -98,7 +98,7 @@ mod prelude {
     pub(crate) use cranelift_codegen::isa::{self, CallConv};
     pub(crate) use cranelift_codegen::Context;
     pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
-    pub(crate) use cranelift_module::{self, DataContext, DataId, FuncId, Linkage, Module};
+    pub(crate) use cranelift_module::{self, DataContext, FuncId, Linkage, Module};
 
     pub(crate) use crate::abi::*;
     pub(crate) use crate::base::{codegen_operand, codegen_place};
diff --git a/src/unsize.rs b/src/unsize.rs
index 042583cd572..b9d379c6117 100644
--- a/src/unsize.rs
+++ b/src/unsize.rs
@@ -31,9 +31,7 @@ pub(crate) fn unsized_info<'tcx>(
             // change to the vtable.
             old_info.expect("unsized_info: missing old info for trait upcast")
         }
-        (_, &ty::Dynamic(ref data, ..)) => {
-            crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal())
-        }
+        (_, &ty::Dynamic(ref data, ..)) => crate::vtable::get_vtable(fx, source, data.principal()),
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
     }
 }
diff --git a/src/vtable.rs b/src/vtable.rs
index 4d1ee47b41e..12f7092d935 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -4,7 +4,7 @@
 // FIXME dedup this logic between miri, cg_llvm and cg_clif
 
 use crate::prelude::*;
-use ty::VtblEntry;
+use super::constant::pointer_for_allocation;
 
 fn vtable_memflags() -> MemFlags {
     let mut flags = MemFlags::trusted(); // A vtable access is always aligned and will never trap.
@@ -66,105 +66,19 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
 
 pub(crate) fn get_vtable<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
-    layout: TyAndLayout<'tcx>,
+    ty: Ty<'tcx>,
     trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
 ) -> Value {
-    let data_id = if let Some(data_id) = fx.vtables.get(&(layout.ty, trait_ref)) {
-        *data_id
+    let vtable_ptr = if let Some(vtable_ptr) = fx.vtables.get(&(ty, trait_ref)) {
+        *vtable_ptr
     } else {
-        let data_id = build_vtable(fx, layout, trait_ref);
-        fx.vtables.insert((layout.ty, trait_ref), data_id);
-        data_id
+        let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
+        let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
+        let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
+
+        fx.vtables.insert((ty, trait_ref), vtable_ptr);
+        vtable_ptr
     };
 
-    let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
-    fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
-}
-
-fn build_vtable<'tcx>(
-    fx: &mut FunctionCx<'_, '_, 'tcx>,
-    layout: TyAndLayout<'tcx>,
-    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
-) -> DataId {
-    let tcx = fx.tcx;
-    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
-
-    let drop_in_place_fn = import_function(
-        tcx,
-        fx.module,
-        Instance::resolve_drop_in_place(tcx, layout.ty).polymorphize(fx.tcx),
-    );
-
-    let vtable_entries = if let Some(trait_ref) = trait_ref {
-        tcx.vtable_entries(trait_ref.with_self_ty(tcx, layout.ty))
-    } else {
-        ty::COMMON_VTABLE_ENTRIES
-    };
-
-    let mut data_ctx = DataContext::new();
-    let mut data = ::std::iter::repeat(0u8)
-        .take(vtable_entries.len() * usize_size)
-        .collect::<Vec<u8>>()
-        .into_boxed_slice();
-
-    for (idx, entry) in vtable_entries.iter().enumerate() {
-        match entry {
-            VtblEntry::MetadataSize => {
-                write_usize(fx.tcx, &mut data, idx, layout.size.bytes());
-            }
-            VtblEntry::MetadataAlign => {
-                write_usize(fx.tcx, &mut data, idx, layout.align.abi.bytes());
-            }
-            VtblEntry::MetadataDropInPlace | VtblEntry::Vacant | VtblEntry::Method(_, _) => {}
-        }
-    }
-    data_ctx.define(data);
-
-    for (idx, entry) in vtable_entries.iter().enumerate() {
-        match entry {
-            VtblEntry::MetadataDropInPlace => {
-                let func_ref = fx.module.declare_func_in_data(drop_in_place_fn, &mut data_ctx);
-                data_ctx.write_function_addr((idx * usize_size) as u32, func_ref);
-            }
-            VtblEntry::Method(def_id, substs) => {
-                let func_id = import_function(
-                    tcx,
-                    fx.module,
-                    Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), *def_id, substs)
-                        .unwrap()
-                        .polymorphize(fx.tcx),
-                );
-                let func_ref = fx.module.declare_func_in_data(func_id, &mut data_ctx);
-                data_ctx.write_function_addr((idx * usize_size) as u32, func_ref);
-            }
-            VtblEntry::MetadataSize | VtblEntry::MetadataAlign | VtblEntry::Vacant => {}
-        }
-    }
-
-    data_ctx.set_align(fx.tcx.data_layout.pointer_align.pref.bytes());
-
-    let data_id = fx.module.declare_anonymous_data(false, false).unwrap();
-
-    fx.module.define_data(data_id, &data_ctx).unwrap();
-
-    data_id
-}
-
-fn write_usize(tcx: TyCtxt<'_>, buf: &mut [u8], idx: usize, num: u64) {
-    let pointer_size =
-        tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.usize)).unwrap().size.bytes() as usize;
-    let target = &mut buf[idx * pointer_size..(idx + 1) * pointer_size];
-
-    match tcx.data_layout.endian {
-        rustc_target::abi::Endian::Little => match pointer_size {
-            4 => target.copy_from_slice(&(num as u32).to_le_bytes()),
-            8 => target.copy_from_slice(&(num as u64).to_le_bytes()),
-            _ => todo!("pointer size {} is not yet supported", pointer_size),
-        },
-        rustc_target::abi::Endian::Big => match pointer_size {
-            4 => target.copy_from_slice(&(num as u32).to_be_bytes()),
-            8 => target.copy_from_slice(&(num as u64).to_be_bytes()),
-            _ => todo!("pointer size {} is not yet supported", pointer_size),
-        },
-    }
+    vtable_ptr.get_addr(fx)
 }

From 6048adc8b1cc5db39af736cf4531c46059b6966d Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Sat, 12 Jun 2021 19:49:48 -0400
Subject: [PATCH 50/75] Support allocation failures when interperting MIR

Note that this breaks Miri.

Closes #79601
---
 src/vtable.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/vtable.rs b/src/vtable.rs
index 12f7092d935..5788aabaadc 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -72,7 +72,10 @@ pub(crate) fn get_vtable<'tcx>(
     let vtable_ptr = if let Some(vtable_ptr) = fx.vtables.get(&(ty, trait_ref)) {
         *vtable_ptr
     } else {
-        let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
+        let vtable_alloc_id = match fx.tcx.vtable_allocation(ty, trait_ref) {
+            Ok(alloc) => alloc,
+            Err(_) => fx.tcx.sess().fatal("allocation of constant vtable failed"),
+        };
         let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
         let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
 

From 17373a94018ee37365cc1c1c48e88372bb7c4283 Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Tue, 29 Jun 2021 19:17:14 -0400
Subject: [PATCH 51/75] fix sess error

This passed x.py check locally, not sure why it wasn't rebased right...
---
 src/vtable.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/vtable.rs b/src/vtable.rs
index 5788aabaadc..7ee34b23e46 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -74,7 +74,7 @@ pub(crate) fn get_vtable<'tcx>(
     } else {
         let vtable_alloc_id = match fx.tcx.vtable_allocation(ty, trait_ref) {
             Ok(alloc) => alloc,
-            Err(_) => fx.tcx.sess().fatal("allocation of constant vtable failed"),
+            Err(_) => fx.tcx.sess.fatal("allocation of constant vtable failed"),
         };
         let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
         let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);

From 4cbba98420b27af2c56df1878ff1992c7993a7bc Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Wed, 30 Jun 2021 21:21:06 +0200
Subject: [PATCH 52/75] Rustup to rustc 1.55.0-nightly (6d820866a 2021-06-29)

---
 build_sysroot/Cargo.lock | 10 +++++-----
 build_system/prepare.rs  |  2 +-
 rust-toolchain           |  2 +-
 src/base.rs              |  6 +++++-
 src/common.rs            |  1 -
 src/lib.rs               | 10 ++--------
 src/vtable.rs            | 16 ++++------------
 7 files changed, 18 insertions(+), 29 deletions(-)

diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock
index bcf692f1dc6..46f661107e7 100644
--- a/build_sysroot/Cargo.lock
+++ b/build_sysroot/Cargo.lock
@@ -56,7 +56,7 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.45"
+version = "0.1.46"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -121,9 +121,9 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.18"
+version = "0.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
 dependencies = [
  "compiler_builtins",
  "libc",
@@ -195,9 +195,9 @@ dependencies = [
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.19"
+version = "0.1.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "410f7acf3cb3a44527c5d9546bad4bf4e6c460915d5f9f2fc524498bfe8f70ce"
+checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49"
 dependencies = [
  "compiler_builtins",
  "rustc-std-workspace-core",
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index d26f24f8856..1f4ec825e1e 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -82,7 +82,7 @@ fn prepare_sysroot() {
     clone_repo(
         "build_sysroot/compiler-builtins",
         "https://github.com/rust-lang/compiler-builtins.git",
-        "0.1.45",
+        "0.1.46",
     );
     apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
 }
diff --git a/rust-toolchain b/rust-toolchain
index 6cb05bef6d3..c1b2d71ebc7 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-06-17"
+channel = "nightly-2021-06-30"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/src/base.rs b/src/base.rs
index ec3e17e5b75..f44ab276590 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -21,6 +21,11 @@ pub(crate) fn codegen_fn<'tcx>(
     debug_assert!(!instance.substs.needs_infer());
 
     let mir = tcx.instance_mir(instance.def);
+    let _mir_guard = crate::PrintOnPanic(|| {
+        let mut buf = Vec::new();
+        rustc_mir::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut buf).unwrap();
+        String::from_utf8_lossy(&buf).into_owned()
+    });
 
     // Declare function
     let symbol_name = tcx.symbol_name(instance);
@@ -52,7 +57,6 @@ pub(crate) fn codegen_fn<'tcx>(
         module,
         tcx,
         pointer_type,
-        vtables: FxHashMap::default(),
         constants_cx: ConstantCx::new(),
 
         instance,
diff --git a/src/common.rs b/src/common.rs
index a8a0bb52a24..892ccf27f6d 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -233,7 +233,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
     pub(crate) module: &'m mut dyn Module,
     pub(crate) tcx: TyCtxt<'tcx>,
     pub(crate) pointer_type: Type, // Cached from module
-    pub(crate) vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Pointer>,
     pub(crate) constants_cx: ConstantCx,
 
     pub(crate) instance: Instance<'tcx>,
diff --git a/src/lib.rs b/src/lib.rs
index 49d9dd2bb5e..6e127ce23dc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,11 +1,4 @@
-#![feature(
-    rustc_private,
-    decl_macro,
-    never_type,
-    hash_drain_filter,
-    vec_into_raw_parts,
-    once_cell,
-)]
+#![feature(rustc_private, decl_macro, never_type, hash_drain_filter, vec_into_raw_parts, once_cell)]
 #![warn(rust_2018_idioms)]
 #![warn(unused_lifetimes)]
 #![warn(unreachable_pub)]
@@ -23,6 +16,7 @@ extern crate rustc_incremental;
 extern crate rustc_index;
 extern crate rustc_interface;
 extern crate rustc_metadata;
+extern crate rustc_mir;
 extern crate rustc_session;
 extern crate rustc_span;
 extern crate rustc_target;
diff --git a/src/vtable.rs b/src/vtable.rs
index 1c3cd431fb4..1e1e3683877 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -1,10 +1,9 @@
 //! Codegen vtables and vtable accesses.
 //!
 //! See `rustc_codegen_ssa/src/meth.rs` for reference.
-// FIXME dedup this logic between miri, cg_llvm and cg_clif
 
-use crate::prelude::*;
 use super::constant::pointer_for_allocation;
+use crate::prelude::*;
 
 fn vtable_memflags() -> MemFlags {
     let mut flags = MemFlags::trusted(); // A vtable access is always aligned and will never trap.
@@ -69,16 +68,9 @@ pub(crate) fn get_vtable<'tcx>(
     ty: Ty<'tcx>,
     trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
 ) -> Value {
-    let vtable_ptr = if let Some(vtable_ptr) = fx.vtables.get(&(ty, trait_ref)) {
-        *vtable_ptr
-    } else {
-        let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
-        let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
-        let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
-
-        fx.vtables.insert((ty, trait_ref), vtable_ptr);
-        vtable_ptr
-    };
+    let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
+    let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
+    let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
 
     vtable_ptr.get_addr(fx)
 }

From f5a16339562a2e6f597fc94e82ec8f7d67902e2e Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 1 Jul 2021 12:05:10 +0200
Subject: [PATCH 53/75] Reduce duplication of vtables

---
 src/constant.rs | 17 +++++++++++------
 src/vtable.rs   | 19 +++++++++++++------
 2 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/src/constant.rs b/src/constant.rs
index a87b3703949..d22ebd5e2ff 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -190,7 +190,6 @@ pub(crate) fn codegen_const_value<'tcx>(
                     let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
                     let base_addr = match alloc_kind {
                         Some(GlobalAlloc::Memory(alloc)) => {
-                            fx.constants_cx.todo.push(TodoItem::Alloc(ptr.alloc_id));
                             let data_id = data_id_for_alloc_id(
                                 &mut fx.constants_cx,
                                 fx.module,
@@ -249,12 +248,11 @@ pub(crate) fn codegen_const_value<'tcx>(
     }
 }
 
-pub(crate) fn pointer_for_allocation<'tcx>(
+fn pointer_for_allocation<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     alloc: &'tcx Allocation,
 ) -> crate::pointer::Pointer {
     let alloc_id = fx.tcx.create_memory_alloc(alloc);
-    fx.constants_cx.todo.push(TodoItem::Alloc(alloc_id));
     let data_id =
         data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, alloc.mutability);
 
@@ -266,12 +264,13 @@ pub(crate) fn pointer_for_allocation<'tcx>(
     crate::pointer::Pointer::new(global_ptr)
 }
 
-fn data_id_for_alloc_id(
+pub(crate) fn data_id_for_alloc_id(
     cx: &mut ConstantCx,
     module: &mut dyn Module,
     alloc_id: AllocId,
     mutability: rustc_hir::Mutability,
 ) -> DataId {
+    cx.todo.push(TodoItem::Alloc(alloc_id));
     *cx.anon_allocs.entry(alloc_id).or_insert_with(|| {
         module.declare_anonymous_data(mutability == rustc_hir::Mutability::Mut, false).unwrap()
     })
@@ -352,7 +351,14 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                     GlobalAlloc::Memory(alloc) => alloc,
                     GlobalAlloc::Function(_) | GlobalAlloc::Static(_) => unreachable!(),
                 };
-                let data_id = data_id_for_alloc_id(cx, module, alloc_id, alloc.mutability);
+                let data_id = *cx.anon_allocs.entry(alloc_id).or_insert_with(|| {
+                    module
+                        .declare_anonymous_data(
+                            alloc.mutability == rustc_hir::Mutability::Mut,
+                            false,
+                        )
+                        .unwrap()
+                });
                 (data_id, alloc, None)
             }
             TodoItem::Static(def_id) => {
@@ -415,7 +421,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
                     continue;
                 }
                 GlobalAlloc::Memory(target_alloc) => {
-                    cx.todo.push(TodoItem::Alloc(reloc));
                     data_id_for_alloc_id(cx, module, reloc, target_alloc.mutability)
                 }
                 GlobalAlloc::Static(def_id) => {
diff --git a/src/vtable.rs b/src/vtable.rs
index 1e1e3683877..021686544eb 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -2,7 +2,7 @@
 //!
 //! See `rustc_codegen_ssa/src/meth.rs` for reference.
 
-use super::constant::pointer_for_allocation;
+use crate::constant::data_id_for_alloc_id;
 use crate::prelude::*;
 
 fn vtable_memflags() -> MemFlags {
@@ -68,9 +68,16 @@ pub(crate) fn get_vtable<'tcx>(
     ty: Ty<'tcx>,
     trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
 ) -> Value {
-    let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
-    let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
-    let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
-
-    vtable_ptr.get_addr(fx)
+    let alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
+    let data_id = data_id_for_alloc_id(
+        &mut fx.constants_cx,
+        &mut *fx.module,
+        alloc_id,
+        Mutability::Not,
+    );
+    let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+    if fx.clif_comments.enabled() {
+        fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id));
+    }
+    fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
 }

From e0f3ad21188f82f98de1cbaf679828dafa66b7a4 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 2 Jul 2021 11:32:27 +0200
Subject: [PATCH 54/75] Disable new rustc test requiring unwinding support

---
 scripts/test_rustc_tests.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh
index 428c2480684..2f5c2cf737b 100755
--- a/scripts/test_rustc_tests.sh
+++ b/scripts/test_rustc_tests.sh
@@ -38,7 +38,8 @@ rm src/test/ui/threads-sendsync/task-stderr.rs
 rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
 rm src/test/ui/drop/drop-trait-enum.rs
 rm src/test/ui/numbers-arithmetic/issue-8460.rs
-rm src/test/incremental/change_crate_dep_kind.rs # requires -Cpanic=unwind
+rm src/test/ui/rt-explody-panic-payloads.rs
+rm src/test/incremental/change_crate_dep_kind.rs
 
 rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
 rm src/test/ui/init-large-type.rs # same

From ae98d5a78dfe5f9d45d69d49f4f0776bdf8afab5 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 2 Jul 2021 12:07:08 +0200
Subject: [PATCH 55/75] Don't use data object for non-primitive scalars

Fixes #1041
---
 src/constant.rs | 128 +++++++++++++++++++++++++-----------------------
 1 file changed, 67 insertions(+), 61 deletions(-)

diff --git a/src/constant.rs b/src/constant.rs
index d22ebd5e2ff..481ba38f74d 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -1,16 +1,13 @@
 //! Handling of `static`s, `const`s and promoted allocations
 
-use rustc_span::DUMMY_SP;
-
-use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::ErrorReported;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir::interpret::{
-    alloc_range, read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc,
-    Scalar,
+    read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Scalar,
 };
 use rustc_middle::ty::ConstKind;
+use rustc_span::DUMMY_SP;
 
 use cranelift_codegen::ir::GlobalValueData;
 use cranelift_module::*;
@@ -171,65 +168,74 @@ pub(crate) fn codegen_const_value<'tcx>(
     }
 
     match const_val {
-        ConstValue::Scalar(x) => {
-            if fx.clif_type(layout.ty).is_none() {
-                let (size, align) = (layout.size, layout.align.pref);
-                let mut alloc = Allocation::from_bytes(
-                    std::iter::repeat(0).take(size.bytes_usize()).collect::<Vec<u8>>(),
-                    align,
-                    Mutability::Not,
-                );
-                alloc.write_scalar(fx, alloc_range(Size::ZERO, size), x.into()).unwrap();
-                let alloc = fx.tcx.intern_const_alloc(alloc);
-                return CValue::by_ref(pointer_for_allocation(fx, alloc), layout);
-            }
+        ConstValue::Scalar(x) => match x {
+            Scalar::Int(int) => {
+                if fx.clif_type(layout.ty).is_some() {
+                    return CValue::const_val(fx, layout, int);
+                } else {
+                    let raw_val = int.to_bits(int.size()).unwrap();
+                    let val = match int.size().bytes() {
+                        1 => fx.bcx.ins().iconst(types::I8, raw_val as i64),
+                        2 => fx.bcx.ins().iconst(types::I16, raw_val as i64),
+                        4 => fx.bcx.ins().iconst(types::I32, raw_val as i64),
+                        8 => fx.bcx.ins().iconst(types::I64, raw_val as i64),
+                        16 => {
+                            let lsb = fx.bcx.ins().iconst(types::I64, raw_val as u64 as i64);
+                            let msb =
+                                fx.bcx.ins().iconst(types::I64, (raw_val >> 64) as u64 as i64);
+                            fx.bcx.ins().iconcat(lsb, msb)
+                        }
+                        _ => unreachable!(),
+                    };
 
-            match x {
-                Scalar::Int(int) => CValue::const_val(fx, layout, int),
-                Scalar::Ptr(ptr) => {
-                    let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
-                    let base_addr = match alloc_kind {
-                        Some(GlobalAlloc::Memory(alloc)) => {
-                            let data_id = data_id_for_alloc_id(
-                                &mut fx.constants_cx,
-                                fx.module,
-                                ptr.alloc_id,
-                                alloc.mutability,
-                            );
-                            let local_data_id =
-                                fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
-                            if fx.clif_comments.enabled() {
-                                fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
-                            }
-                            fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
-                        }
-                        Some(GlobalAlloc::Function(instance)) => {
-                            let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
-                            let local_func_id =
-                                fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
-                            fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
-                        }
-                        Some(GlobalAlloc::Static(def_id)) => {
-                            assert!(fx.tcx.is_static(def_id));
-                            let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false);
-                            let local_data_id =
-                                fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
-                            if fx.clif_comments.enabled() {
-                                fx.add_comment(local_data_id, format!("{:?}", def_id));
-                            }
-                            fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
-                        }
-                        None => bug!("missing allocation {:?}", ptr.alloc_id),
-                    };
-                    let val = if ptr.offset.bytes() != 0 {
-                        fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
-                    } else {
-                        base_addr
-                    };
-                    CValue::by_val(val, layout)
+                    let place = CPlace::new_stack_slot(fx, layout);
+                    place.to_ptr().store(fx, val, MemFlags::trusted());
+                    place.to_cvalue(fx)
                 }
             }
-        }
+            Scalar::Ptr(ptr) => {
+                let alloc_kind = fx.tcx.get_global_alloc(ptr.alloc_id);
+                let base_addr = match alloc_kind {
+                    Some(GlobalAlloc::Memory(alloc)) => {
+                        let data_id = data_id_for_alloc_id(
+                            &mut fx.constants_cx,
+                            fx.module,
+                            ptr.alloc_id,
+                            alloc.mutability,
+                        );
+                        let local_data_id =
+                            fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+                        if fx.clif_comments.enabled() {
+                            fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id));
+                        }
+                        fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
+                    }
+                    Some(GlobalAlloc::Function(instance)) => {
+                        let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
+                        let local_func_id =
+                            fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
+                        fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
+                    }
+                    Some(GlobalAlloc::Static(def_id)) => {
+                        assert!(fx.tcx.is_static(def_id));
+                        let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false);
+                        let local_data_id =
+                            fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+                        if fx.clif_comments.enabled() {
+                            fx.add_comment(local_data_id, format!("{:?}", def_id));
+                        }
+                        fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
+                    }
+                    None => bug!("missing allocation {:?}", ptr.alloc_id),
+                };
+                let val = if ptr.offset.bytes() != 0 {
+                    fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap())
+                } else {
+                    base_addr
+                };
+                CValue::by_val(val, layout)
+            }
+        },
         ConstValue::ByRef { alloc, offset } => CValue::by_ref(
             pointer_for_allocation(fx, alloc)
                 .offset_i64(fx, i64::try_from(offset.bytes()).unwrap()),

From dd1419a1c4843ef306f7c5955b93f601d8da2341 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 25 Jun 2021 19:18:17 +0200
Subject: [PATCH 56/75] Update Cranelift and object

This adds AArch64 support for unixes using ELF object files like Linux
---
 Cargo.lock | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 964a002d92e..748faeaffbf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -34,7 +34,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 [[package]]
 name = "cranelift-bforest"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "cranelift-entity",
 ]
@@ -42,7 +42,7 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "cranelift-bforest",
  "cranelift-codegen-meta",
@@ -58,7 +58,7 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
@@ -67,17 +67,17 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen-shared"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 
 [[package]]
 name = "cranelift-entity"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 
 [[package]]
 name = "cranelift-frontend"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -88,7 +88,7 @@ dependencies = [
 [[package]]
 name = "cranelift-jit"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -105,7 +105,7 @@ dependencies = [
 [[package]]
 name = "cranelift-module"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -116,16 +116,17 @@ dependencies = [
 [[package]]
 name = "cranelift-native"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "cranelift-codegen",
+ "libc",
  "target-lexicon",
 ]
 
 [[package]]
 name = "cranelift-object"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#3d56728b8698d538a00d9f1c295149bbf5e8b78b"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -171,9 +172,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.86"
+version = "0.2.97"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
+checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6"
 
 [[package]]
 name = "libloading"
@@ -211,9 +212,9 @@ checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
 
 [[package]]
 name = "object"
-version = "0.25.2"
+version = "0.25.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8bc1d42047cf336f0f939c99e97183cf31551bf0f2865a2ec9c8d91fd4ffb5e"
+checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7"
 dependencies = [
  "crc32fast",
  "indexmap",

From 1bd9a132f6111b77348b8014b849b056a4f6759a Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 25 Jun 2021 19:18:53 +0200
Subject: [PATCH 57/75] Only test global_asm on x86_64

---
 example/mini_core_hello_world.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs
index 6570f2bf9f2..d997ce6d1b3 100644
--- a/example/mini_core_hello_world.rs
+++ b/example/mini_core_hello_world.rs
@@ -292,7 +292,7 @@ fn main() {
     #[cfg(not(any(jit, windows)))]
     test_tls();
 
-    #[cfg(all(not(jit), target_os = "linux"))]
+    #[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
     unsafe {
         global_asm_test();
     }
@@ -303,12 +303,12 @@ fn main() {
     assert_eq!(*REF1, *REF2);
 }
 
-#[cfg(all(not(jit), target_os = "linux"))]
+#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
 extern "C" {
     fn global_asm_test();
 }
 
-#[cfg(all(not(jit), target_os = "linux"))]
+#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
 global_asm! {
     "
     .global global_asm_test

From cda811173e5862ecf75a19df5e8c69fd5d8a4ead Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Tue, 29 Jun 2021 20:37:06 +0200
Subject: [PATCH 58/75] Fix compilation for AArch64

---
 build_system/build_sysroot.rs | 21 ++++++++++++++++++---
 src/lib.rs                    | 10 ++++++----
 2 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 507af3f9aa7..72d6a0265ef 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -115,10 +115,16 @@ pub(crate) fn build_sysroot(
             }
         }
         SysrootKind::Clif => {
-            build_clif_sysroot_for_triple(channel, target_dir, target_triple);
+            build_clif_sysroot_for_triple(channel, target_dir, host_triple, None);
 
             if host_triple != target_triple {
-                build_clif_sysroot_for_triple(channel, target_dir, host_triple);
+                // When cross-compiling it is often necessary to manually pick the right linker
+                let linker = if target_triple == "aarch64-unknown-linux-gnu" {
+                    Some("aarch64-linux-gnu-gcc")
+                } else {
+                    None
+                };
+                build_clif_sysroot_for_triple(channel, target_dir, target_triple, linker);
             }
 
             // Copy std for the host to the lib dir. This is necessary for the jit mode to find
@@ -133,7 +139,12 @@ pub(crate) fn build_sysroot(
     }
 }
 
-fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str) {
+fn build_clif_sysroot_for_triple(
+    channel: &str,
+    target_dir: &Path,
+    triple: &str,
+    linker: Option<&str>,
+) {
     let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
 
     let keep_sysroot =
@@ -155,6 +166,10 @@ fn build_clif_sysroot_for_triple(channel: &str, target_dir: &Path, triple: &str)
         build_cmd.arg("--release");
         rustflags.push_str(" -Zmir-opt-level=3");
     }
+    if let Some(linker) = linker {
+        use std::fmt::Write;
+        write!(rustflags, " -Clinker={}", linker).unwrap();
+    }
     build_cmd.env("RUSTFLAGS", rustflags);
     build_cmd.env(
         "RUSTC",
diff --git a/src/lib.rs b/src/lib.rs
index 6e127ce23dc..50317b192ed 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -287,10 +287,12 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
         }
         None => {
             let mut builder =
-                cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
-            // Don't use "haswell" as the default, as it implies `has_lzcnt`.
-            // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
-            builder.enable("nehalem").unwrap();
+                cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant).unwrap();
+            if target_triple.architecture == target_lexicon::Architecture::X86_64 {
+                // Don't use "haswell" as the default, as it implies `has_lzcnt`.
+                // macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.
+                builder.enable("nehalem").unwrap();
+            }
             builder
         }
     };

From e8ff364493e6be9bee1e065221fcd88da319647e Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 2 Jul 2021 12:39:34 +0200
Subject: [PATCH 59/75] Fix rust-analyzer setting

---
 .vscode/settings.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.vscode/settings.json b/.vscode/settings.json
index 38ffef5ac99..f62e59cefc2 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -3,7 +3,7 @@
     "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "unresolved-macro-call"],
     "rust-analyzer.assist.importGranularity": "module",
     "rust-analyzer.assist.importEnforceGranularity": true,
-    "rust-analyzer.assist.importPrefix": "by_crate",
+    "rust-analyzer.assist.importPrefix": "crate",
     "rust-analyzer.cargo.runBuildScripts": true,
     "rust-analyzer.linkedProjects": [
         "./Cargo.toml",

From 42f9ad56e9ebc92725fec0b704184e1c09059133 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 2 Jul 2021 12:54:09 +0200
Subject: [PATCH 60/75] [CI] Split build and test steps

---
 .github/workflows/main.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 4442cbe5f94..c8593498057 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -55,6 +55,9 @@ jobs:
         git config --global user.name "User"
         ./y.rs prepare
 
+    - name: Build
+      run: ./y.rs build --sysroot none
+
     - name: Test
       env:
         TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }}

From 3dc9ec246c4eabd9907636ccd1bca85b3df56d53 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 2 Jul 2021 14:43:01 +0200
Subject: [PATCH 61/75] [CI] Cross compile to aarch64-unknown-linux-gnu

---
 .github/workflows/main.yml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index c8593498057..f81ac877260 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -19,6 +19,9 @@ jobs:
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: x86_64-pc-windows-gnu
+          - os: ubuntu-latest
+            env:
+              TARGET_TRIPLE: aarch64-unknown-linux-gnu
 
     steps:
     - uses: actions/checkout@v2
@@ -49,6 +52,11 @@ jobs:
         sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable
         rustup target add x86_64-pc-windows-gnu
 
+    - name: Install AArch64 toolchain and qemu
+      if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu'
+      run: |
+        sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user
+
     - name: Prepare dependencies
       run: |
         git config --global user.email "user@example.com"

From 55e077970891c33122ed34f7f8a061709ba01dc3 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 2 Jul 2021 19:14:02 +0200
Subject: [PATCH 62/75] Check if the patched sysroot source is up to date
 before using it

Fixes #1181
---
 .gitignore                    |  1 +
 build_system/build_sysroot.rs | 20 +++++++++++++++++++-
 build_system/prepare.rs       |  9 ++++++++-
 build_system/rustc_info.rs    |  6 ++++++
 clean_all.sh                  |  3 ++-
 5 files changed, 36 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index 3e010204655..12e779fe7c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,7 @@ perf.data.old
 /build
 /build_sysroot/sysroot_src
 /build_sysroot/compiler-builtins
+/build_sysroot/rustc_version
 /rust
 /rand
 /regex
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 72d6a0265ef..e7946aa36ad 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -3,7 +3,7 @@ use std::fs;
 use std::path::Path;
 use std::process::{self, Command};
 
-use crate::rustc_info::get_file_name;
+use crate::rustc_info::{get_file_name, get_rustc_version};
 use crate::utils::{spawn_and_wait, try_hard_link};
 use crate::SysrootKind;
 
@@ -145,6 +145,24 @@ fn build_clif_sysroot_for_triple(
     triple: &str,
     linker: Option<&str>,
 ) {
+    match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) {
+        Err(e) => {
+            eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
+            eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
+            process::exit(1);
+        }
+        Ok(source_version) => {
+            let rustc_version = get_rustc_version();
+            if source_version != rustc_version {
+                eprintln!("The patched sysroot source is outdated");
+                eprintln!("Source version: {}", source_version.trim());
+                eprintln!("Rustc version:  {}", rustc_version.trim());
+                eprintln!("Hint: Try `./y.rs prepare` to update the patched sysroot source");
+                process::exit(1);
+            }
+        }
+    }
+
     let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
 
     let keep_sysroot =
diff --git a/build_system/prepare.rs b/build_system/prepare.rs
index 1f4ec825e1e..401b8271abc 100644
--- a/build_system/prepare.rs
+++ b/build_system/prepare.rs
@@ -5,7 +5,7 @@ use std::fs;
 use std::path::Path;
 use std::process::Command;
 
-use crate::rustc_info::{get_file_name, get_rustc_path};
+use crate::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
 use crate::utils::{copy_dir_recursively, spawn_and_wait};
 
 pub(crate) fn prepare() {
@@ -59,6 +59,13 @@ fn prepare_sysroot() {
     eprintln!("[COPY] sysroot src");
     copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
 
+    let rustc_version = get_rustc_version();
+    fs::write(
+        Path::new("build_sysroot").join("rustc_version"),
+        &rustc_version,
+    )
+    .unwrap();
+
     eprintln!("[GIT] init");
     let mut git_init_cmd = Command::new("git");
     git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src);
diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs
index 3bf86d9a114..9206bb02bd3 100644
--- a/build_system/rustc_info.rs
+++ b/build_system/rustc_info.rs
@@ -1,6 +1,12 @@
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
 
+pub(crate) fn get_rustc_version() -> String {
+    let version_info =
+        Command::new("rustc").stderr(Stdio::inherit()).args(&["-V"]).output().unwrap().stdout;
+    String::from_utf8(version_info).unwrap()
+}
+
 pub(crate) fn get_host_triple() -> String {
     let version_info =
         Command::new("rustc").stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout;
diff --git a/clean_all.sh b/clean_all.sh
index a7bbeb05cac..f4f8c82d69f 100755
--- a/clean_all.sh
+++ b/clean_all.sh
@@ -1,5 +1,6 @@
 #!/usr/bin/env bash
 set -e
 
-rm -rf target/ build/ build_sysroot/{sysroot_src/,target/,compiler-builtins/} perf.data{,.old}
+rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
+rm -rf target/ build/ perf.data{,.old}
 rm -rf rand/ regex/ simple-raytracer/

From 6a31385363f26f5324b2e125a96541efec88f60c Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 3 Jul 2021 14:28:53 +0200
Subject: [PATCH 63/75] Misc target related improvements

---
 src/base.rs         | 19 ++++++++++++++++---
 src/driver/aot.rs   |  4 +++-
 src/driver/jit.rs   |  2 +-
 src/optimize/mod.rs |  5 ++++-
 src/pretty_clif.rs  |  9 +++------
 5 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/base.rs b/src/base.rs
index f44ab276590..3d78eed77b9 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -109,7 +109,14 @@ pub(crate) fn codegen_fn<'tcx>(
     let context = &mut cx.cached_context;
     context.func = func;
 
-    crate::pretty_clif::write_clif_file(tcx, "unopt", None, instance, &context, &clif_comments);
+    crate::pretty_clif::write_clif_file(
+        tcx,
+        "unopt",
+        module.isa(),
+        instance,
+        &context,
+        &clif_comments,
+    );
 
     // Verify function
     verify_func(tcx, &clif_comments, &context.func);
@@ -126,7 +133,13 @@ pub(crate) fn codegen_fn<'tcx>(
 
     // Perform rust specific optimizations
     tcx.sess.time("optimize clif ir", || {
-        crate::optimize::optimize_function(tcx, instance, context, &mut clif_comments);
+        crate::optimize::optimize_function(
+            tcx,
+            module.isa(),
+            instance,
+            context,
+            &mut clif_comments,
+        );
     });
 
     // Define function
@@ -141,7 +154,7 @@ pub(crate) fn codegen_fn<'tcx>(
     crate::pretty_clif::write_clif_file(
         tcx,
         "opt",
-        Some(module.isa()),
+        module.isa(),
         instance,
         &context,
         &clif_comments,
diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 6676d88602c..5d2c79e3e87 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -290,13 +290,15 @@ pub(crate) fn run_aot(
         None
     };
 
+    // FIXME handle `-Ctarget-cpu=native`
+    let target_cpu = tcx.sess.opts.cg.target_cpu.as_ref().unwrap_or(&tcx.sess.target.cpu).to_owned();
     Box::new((
         CodegenResults {
             modules,
             allocator_module,
             metadata_module,
             metadata,
-            linker_info: LinkerInfo::new(tcx, crate::target_triple(tcx.sess).to_string()),
+            linker_info: LinkerInfo::new(tcx, target_cpu),
             crate_info: CrateInfo::new(tcx),
         },
         work_products,
diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index 39a39e764cb..f454d0efab8 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -159,7 +159,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
             AbiParam::new(jit_module.target_config().pointer_type()),
         ],
         returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)],
-        call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)),
+        call_conv: jit_module.target_config().default_call_conv,
     };
     let start_func_id = jit_module.declare_function("main", Linkage::Import, &start_sig).unwrap();
     let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id);
diff --git a/src/optimize/mod.rs b/src/optimize/mod.rs
index 137fb5f7731..61033d85a12 100644
--- a/src/optimize/mod.rs
+++ b/src/optimize/mod.rs
@@ -1,17 +1,20 @@
 //! Various optimizations specific to cg_clif
 
+use cranelift_codegen::isa::TargetIsa;
+
 use crate::prelude::*;
 
 pub(crate) mod peephole;
 
 pub(crate) fn optimize_function<'tcx>(
     tcx: TyCtxt<'tcx>,
+    isa: &dyn TargetIsa,
     instance: Instance<'tcx>,
     ctx: &mut Context,
     clif_comments: &mut crate::pretty_clif::CommentWriter,
 ) {
     // FIXME classify optimizations over opt levels once we have more
 
-    crate::pretty_clif::write_clif_file(tcx, "preopt", None, instance, &ctx, &*clif_comments);
+    crate::pretty_clif::write_clif_file(tcx, "preopt", isa, instance, &ctx, &*clif_comments);
     crate::base::verify_func(tcx, &*clif_comments, &ctx.func);
 }
diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs
index cd8c5b51608..2f278134d5b 100644
--- a/src/pretty_clif.rs
+++ b/src/pretty_clif.rs
@@ -233,7 +233,7 @@ pub(crate) fn write_ir_file(
 pub(crate) fn write_clif_file<'tcx>(
     tcx: TyCtxt<'tcx>,
     postfix: &str,
-    isa: Option<&dyn cranelift_codegen::isa::TargetIsa>,
+    isa: &dyn cranelift_codegen::isa::TargetIsa,
     instance: Instance<'tcx>,
     context: &cranelift_codegen::Context,
     mut clif_comments: &CommentWriter,
@@ -242,22 +242,19 @@ pub(crate) fn write_clif_file<'tcx>(
         tcx,
         || format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix),
         |file| {
-            let value_ranges = isa
-                .map(|isa| context.build_value_labels_ranges(isa).expect("value location ranges"));
-
             let mut clif = String::new();
             cranelift_codegen::write::decorate_function(
                 &mut clif_comments,
                 &mut clif,
                 &context.func,
-                &DisplayFunctionAnnotations { isa, value_ranges: value_ranges.as_ref() },
+                &DisplayFunctionAnnotations { isa: Some(isa), value_ranges: None },
             )
             .unwrap();
 
             writeln!(file, "test compile")?;
             writeln!(file, "set is_pic")?;
             writeln!(file, "set enable_simd")?;
-            writeln!(file, "target {} haswell", crate::target_triple(tcx.sess))?;
+            writeln!(file, "target {} nehalem", crate::target_triple(tcx.sess))?;
             writeln!(file)?;
             file.write_all(clif.as_bytes())?;
             Ok(())

From 751ae51044510f7f047a2cbd278eb42a380ff886 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sat, 3 Jul 2021 14:41:33 +0200
Subject: [PATCH 64/75] Update Cranelift

---
 Cargo.lock                 | 20 ++++++++++----------
 src/debuginfo/line_info.rs |  2 +-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 748faeaffbf..a406dbee8bd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -34,7 +34,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 [[package]]
 name = "cranelift-bforest"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "cranelift-entity",
 ]
@@ -42,7 +42,7 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "cranelift-bforest",
  "cranelift-codegen-meta",
@@ -58,7 +58,7 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
@@ -67,17 +67,17 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen-shared"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 
 [[package]]
 name = "cranelift-entity"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 
 [[package]]
 name = "cranelift-frontend"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -88,7 +88,7 @@ dependencies = [
 [[package]]
 name = "cranelift-jit"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -105,7 +105,7 @@ dependencies = [
 [[package]]
 name = "cranelift-module"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -116,7 +116,7 @@ dependencies = [
 [[package]]
 name = "cranelift-native"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -126,7 +126,7 @@ dependencies = [
 [[package]]
 name = "cranelift-object"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#f2d2f3a841f4da8188df0a5f1033b5bdeaf02bcd"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs
index 9eb06770630..c7e15f81e03 100644
--- a/src/debuginfo/line_info.rs
+++ b/src/debuginfo/line_info.rs
@@ -10,7 +10,7 @@ use rustc_span::{
 };
 
 use cranelift_codegen::binemit::CodeOffset;
-use cranelift_codegen::machinst::MachSrcLoc;
+use cranelift_codegen::MachSrcLoc;
 
 use gimli::write::{
     Address, AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable,

From 913c0bc01dbab632d1512f703c026aac7acfa197 Mon Sep 17 00:00:00 2001
From: Smitty <me@smitop.com>
Date: Sat, 3 Jul 2021 11:14:19 -0400
Subject: [PATCH 65/75] Make vtable_allocation always succeed

---
 src/vtable.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/vtable.rs b/src/vtable.rs
index 7ee34b23e46..12f7092d935 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -72,10 +72,7 @@ pub(crate) fn get_vtable<'tcx>(
     let vtable_ptr = if let Some(vtable_ptr) = fx.vtables.get(&(ty, trait_ref)) {
         *vtable_ptr
     } else {
-        let vtable_alloc_id = match fx.tcx.vtable_allocation(ty, trait_ref) {
-            Ok(alloc) => alloc,
-            Err(_) => fx.tcx.sess.fatal("allocation of constant vtable failed"),
-        };
+        let vtable_alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
         let vtable_allocation = fx.tcx.global_alloc(vtable_alloc_id).unwrap_memory();
         let vtable_ptr = pointer_for_allocation(fx, vtable_allocation);
 

From ac730b4464ae1a9b6c4a8a2da1f260e72e3c2603 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 4 Jul 2021 12:37:00 +0200
Subject: [PATCH 66/75] Update Cranelift

This has a fix for a miscompilation on AArch64

cc #1184
---
 Cargo.lock | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index a406dbee8bd..56d0974b253 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -34,7 +34,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 [[package]]
 name = "cranelift-bforest"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "cranelift-entity",
 ]
@@ -42,7 +42,7 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "cranelift-bforest",
  "cranelift-codegen-meta",
@@ -58,7 +58,7 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen-meta"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "cranelift-codegen-shared",
  "cranelift-entity",
@@ -67,17 +67,17 @@ dependencies = [
 [[package]]
 name = "cranelift-codegen-shared"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 
 [[package]]
 name = "cranelift-entity"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 
 [[package]]
 name = "cranelift-frontend"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "cranelift-codegen",
  "log",
@@ -88,7 +88,7 @@ dependencies = [
 [[package]]
 name = "cranelift-jit"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -105,7 +105,7 @@ dependencies = [
 [[package]]
 name = "cranelift-module"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "anyhow",
  "cranelift-codegen",
@@ -116,7 +116,7 @@ dependencies = [
 [[package]]
 name = "cranelift-native"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "cranelift-codegen",
  "libc",
@@ -126,7 +126,7 @@ dependencies = [
 [[package]]
 name = "cranelift-object"
 version = "0.75.0"
-source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#93b7cdd6a267ab445864ad8e5bc8b384b0e676ca"
+source = "git+https://github.com/bytecodealliance/wasmtime.git?branch=main#c71ad9490e7f3e19bbcae7e28bbe50f8a0b4a5d8"
 dependencies = [
  "anyhow",
  "cranelift-codegen",

From 83cca1b03c808998032295ab845589d4a4316908 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 4 Jul 2021 12:39:22 +0200
Subject: [PATCH 67/75] Write better clif ir header

---
 src/pretty_clif.rs | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs
index 2f278134d5b..05db74745a1 100644
--- a/src/pretty_clif.rs
+++ b/src/pretty_clif.rs
@@ -251,10 +251,14 @@ pub(crate) fn write_clif_file<'tcx>(
             )
             .unwrap();
 
-            writeln!(file, "test compile")?;
-            writeln!(file, "set is_pic")?;
-            writeln!(file, "set enable_simd")?;
-            writeln!(file, "target {} nehalem", crate::target_triple(tcx.sess))?;
+            for flag in isa.flags().iter() {
+                writeln!(file, "set {}", flag)?;
+            }
+            write!(file, "target {}", isa.triple().architecture.to_string())?;
+            for isa_flag in isa.isa_flags().iter() {
+                write!(file, " {}", isa_flag)?;
+            }
+            writeln!(file, "\n")?;
             writeln!(file)?;
             file.write_all(clif.as_bytes())?;
             Ok(())

From 0d531c37375006917a151ed3932fb09d3e6a431d Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 4 Jul 2021 15:10:06 +0200
Subject: [PATCH 68/75] Better config parsing and allow specifying host and
 target triple in config

---
 build_system/build_sysroot.rs |  4 +--
 build_system/config.rs        | 55 +++++++++++++++++++++++++++++++++++
 config.txt                    |  6 ++++
 y.rs                          |  6 ++++
 4 files changed, 68 insertions(+), 3 deletions(-)
 create mode 100644 build_system/config.rs

diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index e7946aa36ad..00735ac1493 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -165,9 +165,7 @@ fn build_clif_sysroot_for_triple(
 
     let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
 
-    let keep_sysroot =
-        fs::read_to_string("config.txt").unwrap().lines().any(|line| line.trim() == "keep_sysroot");
-    if !keep_sysroot {
+    if !crate::config::get_bool("keep_sysroot") {
         // Cleanup the target dir with the exception of build scripts and the incremental cache
         for dir in ["build", "deps", "examples", "native"] {
             if build_dir.join(dir).exists() {
diff --git a/build_system/config.rs b/build_system/config.rs
new file mode 100644
index 00000000000..ef540cf1f82
--- /dev/null
+++ b/build_system/config.rs
@@ -0,0 +1,55 @@
+use std::{fs, process};
+
+fn load_config_file() -> Vec<(String, Option<String>)> {
+    fs::read_to_string("config.txt")
+        .unwrap()
+        .lines()
+        .map(|line| if let Some((line, _comment)) = line.split_once('#') { line } else { line })
+        .map(|line| line.trim())
+        .filter(|line| !line.is_empty())
+        .map(|line| {
+            if let Some((key, val)) = line.split_once('=') {
+                (key.trim().to_owned(), Some(val.trim().to_owned()))
+            } else {
+                (line.to_owned(), None)
+            }
+        })
+        .collect()
+}
+
+pub(crate) fn get_bool(name: &str) -> bool {
+    let values = load_config_file()
+        .into_iter()
+        .filter(|(key, _)| key == name)
+        .map(|(_, val)| val)
+        .collect::<Vec<_>>();
+    if values.is_empty() {
+        false
+    } else {
+        if values.iter().any(|val| val.is_some()) {
+            eprintln!("Boolean config `{}` has a value", name);
+            process::exit(1);
+        }
+        true
+    }
+}
+
+pub(crate) fn get_value(name: &str) -> Option<String> {
+    let values = load_config_file()
+        .into_iter()
+        .filter(|(key, _)| key == name)
+        .map(|(_, val)| val)
+        .collect::<Vec<_>>();
+    if values.is_empty() {
+        None
+    } else if values.len() == 1 {
+        if values[0].is_none() {
+            eprintln!("Config `{}` missing value", name);
+            process::exit(1);
+        }
+        values.into_iter().next().unwrap()
+    } else {
+        eprintln!("Config `{}` given multiple values: {:?}", name, values);
+        process::exit(1);
+    }
+}
diff --git a/config.txt b/config.txt
index f707b9322af..c5fd7beb747 100644
--- a/config.txt
+++ b/config.txt
@@ -1,5 +1,11 @@
 # This file allows configuring the build system.
 
+# The host triple
+#host = x86_64-unknown-linux-gnu
+
+# The target triple
+#target = x86_64-unknown-linux-gnu
+
 # Disables cleaning of the sysroot dir. This will cause old compiled artifacts to be re-used when
 # the sysroot source hasn't changed. This is useful when the codegen backend hasn't been modified.
 # This option can be changed while the build system is already running for as long as sysroot
diff --git a/y.rs b/y.rs
index 55457745d25..aeaac59fff0 100755
--- a/y.rs
+++ b/y.rs
@@ -31,6 +31,8 @@ use std::process;
 mod build_backend;
 #[path = "build_system/build_sysroot.rs"]
 mod build_sysroot;
+#[path = "build_system/config.rs"]
+mod config;
 #[path = "build_system/prepare.rs"]
 mod prepare;
 #[path = "build_system/rustc_info.rs"]
@@ -114,6 +116,8 @@ fn main() {
 
     let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
         host_triple
+    } else if let Some(host_triple) = crate::config::get_value("host") {
+        host_triple
     } else {
         rustc_info::get_host_triple()
     };
@@ -123,6 +127,8 @@ fn main() {
         } else {
             host_triple.clone() // Empty target triple can happen on GHA
         }
+    } else if let Some(target_triple) = crate::config::get_value("target") {
+        target_triple
     } else {
         host_triple.clone()
     };

From 53478823e42d4172cec837d6bbedf1d090402a64 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 4 Jul 2021 18:15:13 +0200
Subject: [PATCH 69/75] Refactor cg_clif building

---
 build_system/build_backend.rs |  7 ++++---
 build_system/build_sysroot.rs | 32 ++++++++++++++++----------------
 config.txt                    |  8 ++++++--
 y.rs                          |  4 ++--
 4 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
index db046be1866..1df2bcc4541 100644
--- a/build_system/build_backend.rs
+++ b/build_system/build_backend.rs
@@ -1,9 +1,10 @@
 use std::env;
+use std::path::{Path, PathBuf};
 use std::process::Command;
 
-pub(crate) fn build_backend(channel: &str) -> String {
+pub(crate) fn build_backend(channel: &str, host_triple: &str) -> PathBuf {
     let mut cmd = Command::new("cargo");
-    cmd.arg("build");
+    cmd.arg("build").arg("--target").arg(host_triple);
 
     match channel {
         "debug" => {}
@@ -35,5 +36,5 @@ pub(crate) fn build_backend(channel: &str) -> String {
     eprintln!("[BUILD] rustc_codegen_cranelift");
     crate::utils::spawn_and_wait(cmd);
 
-    crate::rustc_info::get_file_name("rustc_codegen_cranelift", "dylib")
+    Path::new("target").join(host_triple).join(channel)
 }
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 00735ac1493..9fb88c27961 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -1,6 +1,6 @@
 use std::env;
 use std::fs;
-use std::path::Path;
+use std::path::{Path, PathBuf};
 use std::process::{self, Command};
 
 use crate::rustc_info::{get_file_name, get_rustc_version};
@@ -11,7 +11,7 @@ pub(crate) fn build_sysroot(
     channel: &str,
     sysroot_kind: SysrootKind,
     target_dir: &Path,
-    cg_clif_dylib: String,
+    cg_clif_build_dir: PathBuf,
     host_triple: &str,
     target_triple: &str,
 ) {
@@ -24,24 +24,24 @@ pub(crate) fn build_sysroot(
     // Copy the backend
     for file in ["cg_clif", "cg_clif_build_sysroot"] {
         try_hard_link(
-            Path::new("target").join(channel).join(get_file_name(file, "bin")),
+            cg_clif_build_dir.join(get_file_name(file, "bin")),
             target_dir.join("bin").join(get_file_name(file, "bin")),
         );
     }
 
-    if cfg!(windows) {
-        // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
-        // binaries.
-        try_hard_link(
-            Path::new("target").join(channel).join(&cg_clif_dylib),
-            target_dir.join("bin").join(cg_clif_dylib),
-        );
-    } else {
-        try_hard_link(
-            Path::new("target").join(channel).join(&cg_clif_dylib),
-            target_dir.join("lib").join(cg_clif_dylib),
-        );
-    }
+    let cg_clif_dylib = get_file_name("rustc_codegen_cranelift", "dylib");
+    try_hard_link(
+        cg_clif_build_dir.join(&cg_clif_dylib),
+        target_dir
+            .join(if cfg!(windows) {
+                // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
+                // binaries.
+                "bin"
+            } else {
+                "lib"
+            })
+            .join(cg_clif_dylib),
+    );
 
     // Build and copy cargo wrapper
     let mut build_cargo_wrapper_cmd = Command::new("rustc");
diff --git a/config.txt b/config.txt
index c5fd7beb747..b14db27d620 100644
--- a/config.txt
+++ b/config.txt
@@ -1,9 +1,13 @@
 # This file allows configuring the build system.
 
-# The host triple
+# Which triple to produce a compiler toolchain for.
+#
+# Defaults to the default triple of rustc on the host system.
 #host = x86_64-unknown-linux-gnu
 
-# The target triple
+# Which triple to build libraries (core/alloc/std/test/proc_macro) for.
+#
+# Defaults to `host`.
 #target = x86_64-unknown-linux-gnu
 
 # Disables cleaning of the sysroot dir. This will cause old compiled artifacts to be re-used when
diff --git a/y.rs b/y.rs
index aeaac59fff0..43937588b48 100755
--- a/y.rs
+++ b/y.rs
@@ -141,12 +141,12 @@ fn main() {
         process::exit(1);
     }
 
-    let cg_clif_dylib = build_backend::build_backend(channel);
+    let cg_clif_build_dir = build_backend::build_backend(channel, &host_triple);
     build_sysroot::build_sysroot(
         channel,
         sysroot_kind,
         &target_dir,
-        cg_clif_dylib,
+        cg_clif_build_dir,
         &host_triple,
         &target_triple,
     );

From 38585b3f01a3e11d47bb61d83d915c0c6f302ded Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 4 Jul 2021 18:17:26 +0200
Subject: [PATCH 70/75] Don't overwrite LD_LIBRARY_PATH in config.sh

---
 scripts/config.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/scripts/config.sh b/scripts/config.sh
index d316a7c6981..53ada369b08 100644
--- a/scripts/config.sh
+++ b/scripts/config.sh
@@ -2,5 +2,5 @@
 
 set -e
 
-export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib"
-export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib:$LD_LIBRARY_PATH"
+export DYLD_LIBRARY_PATH="$(rustc --print sysroot)/lib:$DYLD_LIBRARY_PATH"

From 6b3a061e947fcb928b94cd5a7db3bdfd225f87b4 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Mon, 7 Jun 2021 12:18:28 +0200
Subject: [PATCH 71/75] Remove LibSource

The information is stored in used_crate_source too anyway
---
 src/driver/jit.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index 4a99cb727c8..3f96e741d35 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -185,7 +185,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
         .find(|(crate_type, _data)| *crate_type == rustc_session::config::CrateType::Executable)
         .unwrap()
         .1;
-    for &(cnum, _) in &crate_info.used_crates_dynamic {
+    for &cnum in &crate_info.used_crates {
         let src = &crate_info.used_crate_source[&cnum];
         match data[cnum.as_usize() - 1] {
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}

From a0cdbd1aa61e47fed13e84cbbda9460ea88b7100 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Mon, 5 Jul 2021 18:44:37 +0200
Subject: [PATCH 72/75] Rustfmt

---
 src/bin/cg_clif.rs     |  2 +-
 src/driver/aot.rs      |  3 ++-
 src/driver/jit.rs      | 13 ++++++++-----
 src/intrinsics/llvm.rs | 28 +++++++++++++---------------
 src/vtable.rs          |  8 ++------
 5 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs
index 2643fae0a81..a044b43b864 100644
--- a/src/bin/cg_clif.rs
+++ b/src/bin/cg_clif.rs
@@ -6,8 +6,8 @@ extern crate rustc_interface;
 extern crate rustc_session;
 extern crate rustc_target;
 
-use std::panic;
 use std::lazy::SyncLazy;
+use std::panic;
 
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 use rustc_interface::interface;
diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 5d2c79e3e87..74cb665d061 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -291,7 +291,8 @@ pub(crate) fn run_aot(
     };
 
     // FIXME handle `-Ctarget-cpu=native`
-    let target_cpu = tcx.sess.opts.cg.target_cpu.as_ref().unwrap_or(&tcx.sess.target.cpu).to_owned();
+    let target_cpu =
+        tcx.sess.opts.cg.target_cpu.as_ref().unwrap_or(&tcx.sess.target.cpu).to_owned();
     Box::new((
         CodegenResults {
             modules,
diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index f454d0efab8..8ab94336432 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -26,7 +26,8 @@ thread_local! {
 }
 
 /// The Sender owned by the rustc thread
-static GLOBAL_MESSAGE_SENDER: SyncOnceCell<Mutex<mpsc::Sender<UnsafeMessage>>> = SyncOnceCell::new();
+static GLOBAL_MESSAGE_SENDER: SyncOnceCell<Mutex<mpsc::Sender<UnsafeMessage>>> =
+    SyncOnceCell::new();
 
 /// A message that is sent from the jitted runtime to the rustc thread.
 /// Senders are responsible for upholding `Send` semantics.
@@ -195,14 +196,17 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
             // lazy JIT compilation request - compile requested instance and return pointer to result
             UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx } => {
                 tx.send(jit_fn(instance_ptr, trampoline_ptr))
-                  .expect("jitted runtime hung up before response to lazy JIT request was sent");
+                    .expect("jitted runtime hung up before response to lazy JIT request was sent");
             }
         }
     }
 }
 
 #[no_mangle]
-extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> *const u8 {
+extern "C" fn __clif_jit_fn(
+    instance_ptr: *const Instance<'static>,
+    trampoline_ptr: *const u8,
+) -> *const u8 {
     // send the JIT request to the rustc thread, with a channel for the response
     let (tx, rx) = mpsc::channel();
     UnsafeMessage::JitFn { instance_ptr, trampoline_ptr, tx }
@@ -210,8 +214,7 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>, trampoline_p
         .expect("rustc thread hung up before lazy JIT request was sent");
 
     // block on JIT compilation result
-    rx.recv()
-      .expect("rustc thread hung up before responding to sent lazy JIT request")
+    rx.recv().expect("rustc thread hung up before responding to sent lazy JIT request")
 }
 
 fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) -> *const u8 {
diff --git a/src/intrinsics/llvm.rs b/src/intrinsics/llvm.rs
index 0b5435285b4..be3704ca276 100644
--- a/src/intrinsics/llvm.rs
+++ b/src/intrinsics/llvm.rs
@@ -148,30 +148,28 @@ fn llvm_add_sub<'tcx>(
     ret: CPlace<'tcx>,
     cb_in: Value,
     a: CValue<'tcx>,
-    b: CValue<'tcx>
+    b: CValue<'tcx>,
 ) {
-    assert_eq!(a.layout().ty, fx.tcx.types.u64, "llvm.x86.addcarry.64/llvm.x86.subborrow.64 second operand must be u64");
-    assert_eq!(b.layout().ty, fx.tcx.types.u64, "llvm.x86.addcarry.64/llvm.x86.subborrow.64 third operand must be u64");
+    assert_eq!(
+        a.layout().ty,
+        fx.tcx.types.u64,
+        "llvm.x86.addcarry.64/llvm.x86.subborrow.64 second operand must be u64"
+    );
+    assert_eq!(
+        b.layout().ty,
+        fx.tcx.types.u64,
+        "llvm.x86.addcarry.64/llvm.x86.subborrow.64 third operand must be u64"
+    );
 
     // c + carry -> c + first intermediate carry or borrow respectively
-    let int0 = crate::num::codegen_checked_int_binop(
-        fx,
-        bin_op,
-        a,
-        b,
-    );
+    let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
     let c = int0.value_field(fx, mir::Field::new(0));
     let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx);
 
     // c + carry -> c + second intermediate carry or borrow respectively
     let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in);
     let cb_in_as_u64 = CValue::by_val(cb_in_as_u64, fx.layout_of(fx.tcx.types.u64));
-    let int1 = crate::num::codegen_checked_int_binop(
-        fx,
-        bin_op,
-        c,
-        cb_in_as_u64,
-    );
+    let int1 = crate::num::codegen_checked_int_binop(fx, bin_op, c, cb_in_as_u64);
     let (c, cb1) = int1.load_scalar_pair(fx);
 
     // carry0 | carry1 -> carry or borrow respectively
diff --git a/src/vtable.rs b/src/vtable.rs
index 021686544eb..4a5f9f133a2 100644
--- a/src/vtable.rs
+++ b/src/vtable.rs
@@ -69,12 +69,8 @@ pub(crate) fn get_vtable<'tcx>(
     trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
 ) -> Value {
     let alloc_id = fx.tcx.vtable_allocation(ty, trait_ref);
-    let data_id = data_id_for_alloc_id(
-        &mut fx.constants_cx,
-        &mut *fx.module,
-        alloc_id,
-        Mutability::Not,
-    );
+    let data_id =
+        data_id_for_alloc_id(&mut fx.constants_cx, &mut *fx.module, alloc_id, Mutability::Not);
     let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
     if fx.clif_comments.enabled() {
         fx.add_comment(local_data_id, format!("vtable: {:?}", alloc_id));

From fed71e344818dd2b1f2e48005b6d3da21cda30f5 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Mon, 5 Jul 2021 18:46:13 +0200
Subject: [PATCH 73/75] Pass CrateInfo instead of TyCtxt to
 load_imported_symbols_for_jit

---
 src/driver/jit.rs | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index 8ab94336432..a53d281303f 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -10,6 +10,7 @@ use std::sync::{mpsc, Mutex};
 use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
 use rustc_codegen_ssa::CrateInfo;
 use rustc_middle::mir::mono::MonoItem;
+use rustc_session::Session;
 
 use cranelift_jit::{JITBuilder, JITModule};
 
@@ -65,7 +66,8 @@ fn create_jit_module<'tcx>(
     backend_config: &BackendConfig,
     hotswap: bool,
 ) -> (JITModule, CodegenCx<'tcx>) {
-    let imported_symbols = load_imported_symbols_for_jit(tcx);
+    let crate_info = CrateInfo::new(tcx);
+    let imported_symbols = load_imported_symbols_for_jit(tcx.sess, crate_info);
 
     let isa = crate::build_isa(tcx.sess, backend_config);
     let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
@@ -255,14 +257,16 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
     })
 }
 
-fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
+fn load_imported_symbols_for_jit(
+    sess: &Session,
+    crate_info: CrateInfo,
+) -> Vec<(String, *const u8)> {
     use rustc_middle::middle::dependency_format::Linkage;
 
     let mut dylib_paths = Vec::new();
 
-    let crate_info = CrateInfo::new(tcx);
-    let formats = tcx.dependency_formats(());
-    let data = &formats
+    let data = &crate_info
+        .dependency_formats
         .iter()
         .find(|(crate_type, _data)| *crate_type == rustc_session::config::CrateType::Executable)
         .unwrap()
@@ -272,9 +276,8 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
         match data[cnum.as_usize() - 1] {
             Linkage::NotLinked | Linkage::IncludedFromDylib => {}
             Linkage::Static => {
-                let name = tcx.crate_name(cnum);
-                let mut err =
-                    tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
+                let name = &crate_info.crate_name[&cnum];
+                let mut err = sess.struct_err(&format!("Can't load static lib {}", name.as_str()));
                 err.note("rustc_codegen_cranelift can only load dylibs in JIT mode.");
                 err.emit();
             }
@@ -314,7 +317,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> {
         std::mem::forget(lib)
     }
 
-    tcx.sess.abort_if_errors();
+    sess.abort_if_errors();
 
     imported_symbols
 }

From 3a31c6d8272c14388a34622193baf553636fe470 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Wed, 7 Jul 2021 11:08:52 +0200
Subject: [PATCH 74/75] Rustup to rustc 1.55.0-nightly (885399992 2021-07-06)

---
 rust-toolchain | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rust-toolchain b/rust-toolchain
index c1b2d71ebc7..f806f7bdcd9 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-06-30"
+channel = "nightly-2021-07-07"
 components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

From 00b2f56bc6f9add36b8616f369e2d169261eaeab Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Wed, 7 Jul 2021 11:39:29 +0200
Subject: [PATCH 75/75] Add memchr to list of permitted cg_clif deps

Object started depending on it
---
 src/tools/tidy/src/deps.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index ea587210b4f..799d685ce5c 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -254,6 +254,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[
     "libloading",
     "log",
     "mach",
+    "memchr",
     "object",
     "regalloc",
     "region",