summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_cranelift
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:13 +0000
commit218caa410aa38c29984be31a5229b9fa717560ee (patch)
treec54bd55eeb6e4c508940a30e94c0032fbd45d677 /compiler/rustc_codegen_cranelift
parentReleasing progress-linux version 1.67.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-218caa410aa38c29984be31a5229b9fa717560ee.tar.xz
rustc-218caa410aa38c29984be31a5229b9fa717560ee.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_codegen_cranelift')
-rw-r--r--compiler/rustc_codegen_cranelift/.cirrus.yml2
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/main.yml52
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml2
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml16
-rw-r--r--compiler/rustc_codegen_cranelift/.vscode/settings.json35
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.lock125
-rw-r--r--compiler/rustc_codegen_cranelift/Cargo.toml20
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md2
-rw-r--r--compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock57
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_backend.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs98
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/mod.rs91
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/path.rs70
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs154
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/rustc_info.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs553
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/utils.rs145
-rwxr-xr-xcompiler/rustc_codegen_cranelift/clean_all.sh2
-rw-r--r--compiler/rustc_codegen_cranelift/config.txt1
-rw-r--r--compiler/rustc_codegen_cranelift/docs/usage.md12
-rw-r--r--compiler/rustc_codegen_cranelift/example/issue-72793.rs24
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/example/std_example.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rw-r--r--compiler/rustc_codegen_cranelift/rustfmt.toml2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/filter_profile.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs36
-rw-r--r--compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh22
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh124
-rw-r--r--compiler/rustc_codegen_cranelift/src/abi/mod.rs36
-rw-r--r--compiler/rustc_codegen_cranelift/src/allocator.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/src/cast.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs11
-rw-r--r--compiler/rustc_codegen_cranelift/src/constant.rs84
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/discriminant.rs207
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/jit.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/mod.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs176
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs222
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs197
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs102
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/main_shim.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/num.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/optimize/peephole.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs15
-rwxr-xr-xcompiler/rustc_codegen_cranelift/test.sh2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/y.rs2
53 files changed, 1758 insertions, 1093 deletions
diff --git a/compiler/rustc_codegen_cranelift/.cirrus.yml b/compiler/rustc_codegen_cranelift/.cirrus.yml
index 732edd661..d627c2ee0 100644
--- a/compiler/rustc_codegen_cranelift/.cirrus.yml
+++ b/compiler/rustc_codegen_cranelift/.cirrus.yml
@@ -12,8 +12,6 @@ task:
folder: target
prepare_script:
- . $HOME/.cargo/env
- - git config --global user.email "user@example.com"
- - git config --global user.name "User"
- ./y.rs prepare
test_script:
- . $HOME/.cargo/env
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index 5061010c8..a6bb12a66 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -19,6 +19,7 @@ jobs:
- name: Rustfmt
run: |
cargo fmt --check
+ rustfmt --check build_system/mod.rs
build:
runs-on: ${{ matrix.os }}
@@ -28,7 +29,7 @@ jobs:
fail-fast: false
matrix:
include:
- - os: ubuntu-latest
+ - os: ubuntu-20.04 # FIXME switch to ubuntu-22.04 once #1303 is fixed
env:
TARGET_TRIPLE: x86_64-unknown-linux-gnu
- os: macos-latest
@@ -41,18 +42,22 @@ jobs:
- os: ubuntu-latest
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
+ # s390x requires QEMU 6.1 or greater, we could build it from source, but ubuntu 22.04 comes with 6.2 by default
+ - os: ubuntu-latest
+ env:
+ TARGET_TRIPLE: s390x-unknown-linux-gnu
steps:
- uses: actions/checkout@v3
- name: Cache cargo installed crates
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-installed-crates
- name: Cache cargo registry and index
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: |
~/.cargo/registry
@@ -60,9 +65,9 @@ jobs:
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
- path: target
+ path: build/cg_clif
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Install MinGW toolchain and wine
@@ -78,11 +83,14 @@ jobs:
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user
- - name: Prepare dependencies
+ - name: Install s390x toolchain and qemu
+ if: matrix.env.TARGET_TRIPLE == 's390x-unknown-linux-gnu'
run: |
- git config --global user.email "user@example.com"
- git config --global user.name "User"
- ./y.rs prepare
+ sudo apt-get update
+ sudo apt-get install -y gcc-s390x-linux-gnu qemu-user
+
+ - name: Prepare dependencies
+ run: ./y.rs prepare
- name: Build without unstable features
env:
@@ -110,7 +118,7 @@ jobs:
./y.rs test
- name: Package prebuilt cg_clif
- run: tar cvfJ cg_clif.tar.xz build
+ run: tar cvfJ cg_clif.tar.xz dist
- name: Upload prebuilt cg_clif
if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu'
@@ -121,7 +129,7 @@ jobs:
- name: Upload prebuilt cg_clif (cross compile)
if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: cg_clif-${{ runner.os }}-cross-x86_64-mingw
path: cg_clif.tar.xz
@@ -147,13 +155,13 @@ jobs:
- uses: actions/checkout@v3
- name: Cache cargo installed crates
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-installed-crates
- name: Cache cargo registry and index
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: |
~/.cargo/registry
@@ -161,9 +169,9 @@ jobs:
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
- path: target
+ path: build/cg_clif
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Set MinGW as the default toolchain
@@ -172,8 +180,6 @@ jobs:
- name: Prepare dependencies
run: |
- git config --global user.email "user@example.com"
- git config --global user.name "User"
git config --global core.autocrlf false
rustc y.rs -o y.exe -g
./y.exe prepare
@@ -198,24 +204,24 @@ jobs:
# Enable extra checks
$Env:CG_CLIF_ENABLE_VERIFIER=1
-
+
# WIP Disable some tests
-
+
# This fails due to some weird argument handling by hyperfine, not an actual regression
# more of a build system issue
(Get-Content config.txt) -replace '(bench.simple-raytracer)', '# $1' | Out-File config.txt
-
- # This fails with a different output than expected
+
+ # This fails with a different output than expected
(Get-Content config.txt) -replace '(test.regex-shootout-regex-dna)', '# $1' | Out-File config.txt
./y.exe test
- name: Package prebuilt cg_clif
# don't use compression as xzip isn't supported by tar on windows and bzip2 hangs
- run: tar cvf cg_clif.tar build
+ run: tar cvf cg_clif.tar dist
- name: Upload prebuilt cg_clif
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: cg_clif-${{ matrix.env.TARGET_TRIPLE }}
path: cg_clif.tar
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml b/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
index 0a3e7ca07..d0d58d2a7 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/nightly-cranelift.yml
@@ -14,7 +14,7 @@ jobs:
- uses: actions/checkout@v3
- name: Cache cargo installed crates
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cargo/bin
key: ubuntu-latest-cargo-installed-crates
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
index b8a98b83e..bef806318 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
@@ -11,13 +11,13 @@ jobs:
- uses: actions/checkout@v3
- name: Cache cargo installed crates
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-installed-crates
- name: Cache cargo registry and index
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: |
~/.cargo/registry
@@ -25,9 +25,9 @@ jobs:
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
- path: target
+ path: build/cg_clif
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Prepare dependencies
@@ -49,13 +49,13 @@ jobs:
- uses: actions/checkout@v3
- name: Cache cargo installed crates
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-installed-crates
- name: Cache cargo registry and index
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
path: |
~/.cargo/registry
@@ -63,9 +63,9 @@ jobs:
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo target dir
- uses: actions/cache@v2
+ uses: actions/cache@v3
with:
- path: target
+ path: build/cg_clif
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Prepare dependencies
diff --git a/compiler/rustc_codegen_cranelift/.vscode/settings.json b/compiler/rustc_codegen_cranelift/.vscode/settings.json
index 13301bf20..bc914e37d 100644
--- a/compiler/rustc_codegen_cranelift/.vscode/settings.json
+++ b/compiler/rustc_codegen_cranelift/.vscode/settings.json
@@ -4,16 +4,10 @@
"rust-analyzer.imports.granularity.enforce": true,
"rust-analyzer.imports.granularity.group": "module",
"rust-analyzer.imports.prefix": "crate",
- "rust-analyzer.cargo.features": ["unstable-features"],
+ "rust-analyzer.cargo.features": ["unstable-features", "__check_build_system_using_ra"],
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
- //"./build_sysroot/sysroot_src/library/std/Cargo.toml",
{
- "roots": [
- "./example/mini_core.rs",
- "./example/mini_core_hello_world.rs",
- "./example/mod_bench.rs"
- ],
"crates": [
{
"root_module": "./example/mini_core.rs",
@@ -36,34 +30,11 @@
]
},
{
- "roots": ["./example/std_example.rs"],
+ "sysroot_src": "./build_sysroot/sysroot_src/library",
"crates": [
{
"root_module": "./example/std_example.rs",
- "edition": "2018",
- "deps": [{ "crate": 1, "name": "std" }],
- "cfg": [],
- },
- {
- "root_module": "./build_sysroot/sysroot_src/library/std/src/lib.rs",
- "edition": "2018",
- "deps": [],
- "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",
+ "edition": "2015",
"deps": [],
"cfg": [],
},
diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock
index 3b406036c..e4d3e9ca5 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/Cargo.lock
@@ -15,9 +15,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.60"
+version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
+checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
[[package]]
name = "arrayvec"
@@ -39,9 +39,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
-version = "3.11.0"
+version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "byteorder"
@@ -57,24 +57,25 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44409ccf2d0f663920cab563d2b79fcd6b2e9a2bcc6e929fef76c8f82ad6c17a"
+checksum = "b62c772976416112fa4484cbd688cb6fb35fd430005c1c586224fc014018abad"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98de2018ad96eb97f621f7d6b900a0cc661aec8d02ea4a50e56ecb48e5a2fcaf"
+checksum = "9b40ed2dd13c2ac7e24f88a3090c68ad3414eb1d066a95f8f1f7b3b819cb4e46"
dependencies = [
"arrayvec",
"bumpalo",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
+ "cranelift-egraph",
"cranelift-entity",
"cranelift-isle",
"gimli",
@@ -86,30 +87,44 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5287ce36e6c4758fbaf298bd1a8697ad97a4f2375a3d1b61142ea538db4877e5"
+checksum = "bb927a8f1c27c34ee3759b6b0ffa528d2330405d5cc4511f0cab33fe2279f4b5"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2855c24219e2f08827f3f4ffb2da92e134ae8d8ecc185b11ec8f9878cf5f588e"
+checksum = "43dfa417b884a9ab488d95fd6b93b25e959321fe7bfd7a0a960ba5d7fb7ab927"
+
+[[package]]
+name = "cranelift-egraph"
+version = "0.90.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a66b39785efd8513d2cca967ede56d6cc57c8d7986a595c7c47d0c78de8dce"
+dependencies = [
+ "cranelift-entity",
+ "fxhash",
+ "hashbrown",
+ "indexmap",
+ "log",
+ "smallvec",
+]
[[package]]
name = "cranelift-entity"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b65673279d75d34bf11af9660ae2dbd1c22e6d28f163f5c72f4e1dc56d56103"
+checksum = "0637ffde963cb5d759bc4d454cfa364b6509e6c74cdaa21298add0ed9276f346"
[[package]]
name = "cranelift-frontend"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ed2b3d7a4751163f6c4a349205ab1b7d9c00eecf19dcea48592ef1f7688eefc"
+checksum = "fb72b8342685e850cb037350418f62cc4fc55d6c2eb9c7ca01b82f9f1a6f3d56"
dependencies = [
"cranelift-codegen",
"log",
@@ -119,15 +134,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3be64cecea9d90105fc6a2ba2d003e98c867c1d6c4c86cc878f97ad9fb916293"
+checksum = "850579cb9e4b448f7c301f1e6e6cbad99abe3f1f1d878a4994cb66e33c6db8cd"
[[package]]
name = "cranelift-jit"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f98ed42a70a0c9c388e34ec9477f57fc7300f541b1e5136a0e2ea02b1fac6015"
+checksum = "9add822ad66dcbe152b5ab57de10240a2df4505099f2f6c27159acb711890bd4"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -138,14 +153,15 @@ dependencies = [
"log",
"region",
"target-lexicon",
+ "wasmtime-jit-icache-coherence",
"windows-sys",
]
[[package]]
name = "cranelift-module"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d658ac7f156708bfccb647216cc8b9387469f50d352ba4ad80150541e4ae2d49"
+checksum = "406b772626fc2664864cf947f3895a23b619895c7fff635f3622e2d857f4492f"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -153,9 +169,9 @@ dependencies = [
[[package]]
name = "cranelift-native"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4a03a6ac1b063e416ca4b93f6247978c991475e8271465340caa6f92f3c16a4"
+checksum = "2d0a279e5bcba3e0466c734d8d8eb6bfc1ad29e95c37f3e4955b492b5616335e"
dependencies = [
"cranelift-codegen",
"libc",
@@ -164,9 +180,9 @@ dependencies = [
[[package]]
name = "cranelift-object"
-version = "0.88.1"
+version = "0.90.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eef0b4119b645b870a43a036d76c0ada3a076b1f82e8b8487659304c8b09049b"
+checksum = "39793c550f0c1d7db96c2fc1324583670c8143befe6edbfbaf1c68aba53be983"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -186,6 +202,12 @@ dependencies = [
]
[[package]]
+name = "fallible-iterator"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
+
+[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -196,9 +218,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.7"
+version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
@@ -211,7 +233,9 @@ version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
dependencies = [
+ "fallible-iterator",
"indexmap",
+ "stable_deref_trait",
]
[[package]]
@@ -225,9 +249,9 @@ dependencies = [
[[package]]
name = "indexmap"
-version = "1.9.1"
+version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
dependencies = [
"autocfg",
"hashbrown",
@@ -235,15 +259,15 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.127"
+version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
name = "libloading"
-version = "0.7.3"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
@@ -287,15 +311,15 @@ dependencies = [
[[package]]
name = "once_cell"
-version = "1.13.0"
+version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
[[package]]
name = "regalloc2"
-version = "0.3.2"
+version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779"
+checksum = "91b2eab54204ea0117fe9a060537e0b07a4e72f7c7d182361ecc346cab2240e5"
dependencies = [
"fxhash",
"log",
@@ -342,15 +366,21 @@ checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
[[package]]
name = "smallvec"
-version = "1.9.0"
+version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "target-lexicon"
-version = "0.12.4"
+version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
+checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d"
[[package]]
name = "version_check"
@@ -365,6 +395,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
+name = "wasmtime-jit-icache-coherence"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6bbabb309c06cc238ee91b1455b748c45f0bdcab0dda2c2db85b0a1e69fcb66"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml
index 0fdd5de11..2b216ca07 100644
--- a/compiler/rustc_codegen_cranelift/Cargo.toml
+++ b/compiler/rustc_codegen_cranelift/Cargo.toml
@@ -3,17 +3,24 @@ name = "rustc_codegen_cranelift"
version = "0.1.0"
edition = "2021"
+[[bin]]
+# This is used just to teach rust-analyzer how to check the build system. required-features is used
+# to disable it for regular builds.
+name = "y"
+path = "./y.rs"
+required-features = ["__check_build_system_using_ra"]
+
[lib]
crate-type = ["dylib"]
[dependencies]
# These have to be in sync with each other
-cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
-cranelift-frontend = "0.88.1"
-cranelift-module = "0.88.1"
-cranelift-native = "0.88.1"
-cranelift-jit = { version = "0.88.1", optional = true }
-cranelift-object = "0.88.1"
+cranelift-codegen = { version = "0.90.1", features = ["unwind", "all-arch"] }
+cranelift-frontend = "0.90.1"
+cranelift-module = "0.90.1"
+cranelift-native = "0.90.1"
+cranelift-jit = { version = "0.90.1", optional = true }
+cranelift-object = "0.90.1"
target-lexicon = "0.12.0"
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
@@ -39,6 +46,7 @@ smallvec = "1.8.1"
unstable-features = ["jit", "inline_asm"]
jit = ["cranelift-jit", "libloading"]
inline_asm = []
+__check_build_system_using_ra = []
[package.metadata.rust-analyzer]
rustc_private = true
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index 1e84c7fa3..0e9c77244 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/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-clif build
+$ $cg_clif_dir/dist/cargo-clif build
```
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
diff --git a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
index f6a9cb672..bba321053 100644
--- a/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
+++ b/compiler/rustc_codegen_cranelift/build_sysroot/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
-version = "0.16.0"
+version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
+checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
dependencies = [
"compiler_builtins",
"gimli",
@@ -33,26 +33,10 @@ dependencies = [
]
[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
name = "cc"
-version = "1.0.73"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
-
-[[package]]
-name = "cfg-if"
-version = "0.1.10"
+version = "1.0.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
-dependencies = [
- "compiler_builtins",
- "rustc-std-workspace-core",
-]
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
[[package]]
name = "cfg-if"
@@ -66,9 +50,9 @@ dependencies = [
[[package]]
name = "compiler_builtins"
-version = "0.1.82"
+version = "0.1.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "18cd7635fea7bb481ea543b392789844c1ad581299da70184c7175ce3af76603"
+checksum = "13e81c6cd7ab79f51a0c927d22858d61ad12bd0b3865f0b13ece02a4486aeabb"
dependencies = [
"rustc-std-workspace-core",
]
@@ -111,9 +95,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.25.0"
+version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
+checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-alloc",
@@ -145,9 +129,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.135"
+version = "0.2.138"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
dependencies = [
"rustc-std-workspace-core",
]
@@ -164,12 +148,11 @@ dependencies = [
[[package]]
name = "miniz_oxide"
-version = "0.4.4"
+version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
+checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
dependencies = [
"adler",
- "autocfg",
"compiler_builtins",
"rustc-std-workspace-alloc",
"rustc-std-workspace-core",
@@ -177,9 +160,9 @@ dependencies = [
[[package]]
name = "object"
-version = "0.26.2"
+version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
+checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
dependencies = [
"compiler_builtins",
"memchr",
@@ -192,7 +175,7 @@ name = "panic_abort"
version = "0.0.0"
dependencies = [
"alloc",
- "cfg-if 0.1.10",
+ "cfg-if",
"compiler_builtins",
"core",
"libc",
@@ -203,7 +186,7 @@ name = "panic_unwind"
version = "0.0.0"
dependencies = [
"alloc",
- "cfg-if 0.1.10",
+ "cfg-if",
"compiler_builtins",
"core",
"libc",
@@ -255,7 +238,7 @@ version = "0.0.0"
dependencies = [
"addr2line",
"alloc",
- "cfg-if 1.0.0",
+ "cfg-if",
"compiler_builtins",
"core",
"dlmalloc",
@@ -277,7 +260,7 @@ dependencies = [
name = "std_detect"
version = "0.1.5"
dependencies = [
- "cfg-if 1.0.0",
+ "cfg-if",
"compiler_builtins",
"libc",
"rustc-std-workspace-alloc",
@@ -299,7 +282,7 @@ dependencies = [
name = "test"
version = "0.0.0"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if",
"core",
"getopts",
"libc",
@@ -325,7 +308,7 @@ name = "unwind"
version = "0.0.0"
dependencies = [
"cc",
- "cfg-if 0.1.10",
+ "cfg-if",
"compiler_builtins",
"core",
"libc",
diff --git a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs
index fae5b2716..a081fdaa1 100644
--- a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs
@@ -1,16 +1,21 @@
-use std::env;
use std::path::Path;
use super::build_sysroot;
use super::config;
-use super::prepare;
-use super::utils::{cargo_command, spawn_and_wait};
+use super::path::Dirs;
+use super::prepare::GitRepo;
+use super::utils::{spawn_and_wait, CargoProject, Compiler};
use super::SysrootKind;
+pub(crate) static ABI_CAFE_REPO: GitRepo =
+ GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
+
+static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe");
+
pub(crate) fn run(
channel: &str,
sysroot_kind: SysrootKind,
- target_dir: &Path,
+ dirs: &Dirs,
cg_clif_dylib: &Path,
host_triple: &str,
target_triple: &str,
@@ -27,26 +32,25 @@ pub(crate) fn run(
eprintln!("Building sysroot for abi-cafe");
build_sysroot::build_sysroot(
+ dirs,
channel,
sysroot_kind,
- target_dir,
cg_clif_dylib,
host_triple,
target_triple,
);
eprintln!("Running abi-cafe");
- let abi_cafe_path = prepare::ABI_CAFE.source_dir();
- env::set_current_dir(abi_cafe_path.clone()).unwrap();
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
- let mut cmd = cargo_command("cargo", "run", Some(target_triple), &abi_cafe_path);
+ let mut cmd = ABI_CAFE.run(&Compiler::host(), dirs);
cmd.arg("--");
cmd.arg("--pairs");
cmd.args(pairs);
cmd.arg("--add-rustc-codegen-backend");
cmd.arg(format!("cgclif:{}", cg_clif_dylib.display()));
+ cmd.current_dir(ABI_CAFE.source_dir(dirs));
spawn_and_wait(cmd);
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
index cda468bcf..fde8ef424 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
@@ -1,16 +1,19 @@
use std::env;
use std::path::PathBuf;
+use super::path::{Dirs, RelPath};
use super::rustc_info::get_file_name;
-use super::utils::{cargo_command, is_ci};
+use super::utils::{is_ci, CargoProject, Compiler};
+
+static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
pub(crate) fn build_backend(
+ dirs: &Dirs,
channel: &str,
host_triple: &str,
use_unstable_features: bool,
) -> PathBuf {
- let source_dir = std::env::current_dir().unwrap();
- let mut cmd = cargo_command("cargo", "build", Some(host_triple), &source_dir);
+ let mut cmd = CG_CLIF.build(&Compiler::host(), dirs);
cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode
@@ -41,8 +44,8 @@ pub(crate) fn build_backend(
eprintln!("[BUILD] rustc_codegen_cranelift");
super::utils::spawn_and_wait(cmd);
- source_dir
- .join("target")
+ CG_CLIF
+ .target_dir(dirs)
.join(host_triple)
.join(channel)
.join(get_file_name("rustc_codegen_cranelift", "dylib"))
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
index 856aecc49..cbbf09b9b 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
@@ -1,57 +1,60 @@
use std::fs;
-use std::path::{Path, PathBuf};
+use std::path::Path;
use std::process::{self, Command};
+use super::path::{Dirs, RelPath};
use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
-use super::utils::{cargo_command, spawn_and_wait, try_hard_link};
+use super::utils::{spawn_and_wait, try_hard_link, CargoProject, Compiler};
use super::SysrootKind;
+static DIST_DIR: RelPath = RelPath::DIST;
+static BIN_DIR: RelPath = RelPath::DIST.join("bin");
+static LIB_DIR: RelPath = RelPath::DIST.join("lib");
+static RUSTLIB_DIR: RelPath = LIB_DIR.join("rustlib");
+
pub(crate) fn build_sysroot(
+ dirs: &Dirs,
channel: &str,
sysroot_kind: SysrootKind,
- target_dir: &Path,
cg_clif_dylib_src: &Path,
host_triple: &str,
target_triple: &str,
) {
eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
- 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();
+ DIST_DIR.ensure_fresh(dirs);
+ BIN_DIR.ensure_exists(dirs);
+ LIB_DIR.ensure_exists(dirs);
// Copy the backend
- let cg_clif_dylib_path = 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(get_file_name("rustc_codegen_cranelift", "dylib"));
+ let cg_clif_dylib_path = if cfg!(windows) {
+ // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
+ // binaries.
+ BIN_DIR
+ } else {
+ LIB_DIR
+ }
+ .to_path(dirs)
+ .join(get_file_name("rustc_codegen_cranelift", "dylib"));
try_hard_link(cg_clif_dylib_src, &cg_clif_dylib_path);
// Build and copy rustc and cargo wrappers
- for wrapper in ["rustc-clif", "cargo-clif"] {
+ for wrapper in ["rustc-clif", "rustdoc-clif", "cargo-clif"] {
let wrapper_name = get_wrapper_file_name(wrapper, "bin");
let mut build_cargo_wrapper_cmd = Command::new("rustc");
build_cargo_wrapper_cmd
- .arg(PathBuf::from("scripts").join(format!("{wrapper}.rs")))
+ .arg(RelPath::SCRIPTS.to_path(dirs).join(&format!("{wrapper}.rs")))
.arg("-o")
- .arg(target_dir.join(wrapper_name))
+ .arg(DIST_DIR.to_path(dirs).join(wrapper_name))
.arg("-g");
spawn_and_wait(build_cargo_wrapper_cmd);
}
let default_sysroot = super::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");
+ let host_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(host_triple).join("lib");
+ let target_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(target_triple).join("lib");
fs::create_dir_all(&host_rustlib_lib).unwrap();
fs::create_dir_all(&target_rustlib_lib).unwrap();
@@ -112,24 +115,18 @@ pub(crate) fn build_sysroot(
}
}
SysrootKind::Clif => {
- build_clif_sysroot_for_triple(
- channel,
- target_dir,
- host_triple,
- &cg_clif_dylib_path,
- None,
- );
+ build_clif_sysroot_for_triple(dirs, channel, host_triple, &cg_clif_dylib_path, None);
if host_triple != target_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
+ let linker = match target_triple {
+ "aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu-gcc"),
+ "s390x-unknown-linux-gnu" => Some("s390x-linux-gnu-gcc"),
+ _ => None,
};
build_clif_sysroot_for_triple(
+ dirs,
channel,
- target_dir,
target_triple,
&cg_clif_dylib_path,
linker,
@@ -142,21 +139,26 @@ pub(crate) fn build_sysroot(
let file = file.unwrap().path();
let filename = file.file_name().unwrap().to_str().unwrap();
if filename.contains("std-") && !filename.contains(".rlib") {
- try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap()));
+ try_hard_link(&file, LIB_DIR.to_path(dirs).join(file.file_name().unwrap()));
}
}
}
}
}
+// FIXME move to download/ or dist/
+pub(crate) static SYSROOT_RUSTC_VERSION: RelPath = RelPath::BUILD_SYSROOT.join("rustc_version");
+pub(crate) static SYSROOT_SRC: RelPath = RelPath::BUILD_SYSROOT.join("sysroot_src");
+static STANDARD_LIBRARY: CargoProject = CargoProject::new(&RelPath::BUILD_SYSROOT, "build_sysroot");
+
fn build_clif_sysroot_for_triple(
+ dirs: &Dirs,
channel: &str,
- target_dir: &Path,
triple: &str,
cg_clif_dylib_path: &Path,
linker: Option<&str>,
) {
- match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) {
+ match fs::read_to_string(SYSROOT_RUSTC_VERSION.to_path(dirs)) {
Err(e) => {
eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
@@ -174,7 +176,7 @@ fn build_clif_sysroot_for_triple(
}
}
- let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
+ let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(triple).join(channel);
if !super::config::get_bool("keep_sysroot") {
// Cleanup the deps dir, but keep build scripts and the incremental cache for faster
@@ -185,27 +187,27 @@ fn build_clif_sysroot_for_triple(
}
// Build sysroot
- let mut build_cmd = cargo_command("cargo", "build", Some(triple), Path::new("build_sysroot"));
let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
- rustflags.push_str(&format!(" --sysroot={}", target_dir.to_str().unwrap()));
+ rustflags.push_str(&format!(" --sysroot={}", DIST_DIR.to_path(dirs).to_str().unwrap()));
if channel == "release" {
- 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);
+ let mut compiler = Compiler::with_triple(triple.to_owned());
+ compiler.rustflags = rustflags;
+ let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs);
+ if channel == "release" {
+ build_cmd.arg("--release");
+ }
build_cmd.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()
- {
+ for entry in fs::read_dir(build_dir.join("deps")).unwrap() {
let entry = entry.unwrap();
if let Some(ext) = entry.path().extension() {
if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
@@ -216,7 +218,7 @@ fn build_clif_sysroot_for_triple(
};
try_hard_link(
entry.path(),
- target_dir.join("lib").join("rustlib").join(triple).join("lib").join(entry.file_name()),
+ RUSTLIB_DIR.to_path(dirs).join(triple).join("lib").join(entry.file_name()),
);
}
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/mod.rs b/compiler/rustc_codegen_cranelift/build_system/mod.rs
index b25270d83..1afc9a55c 100644
--- a/compiler/rustc_codegen_cranelift/build_system/mod.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/mod.rs
@@ -8,20 +8,37 @@ mod abi_cafe;
mod build_backend;
mod build_sysroot;
mod config;
+mod path;
mod prepare;
mod rustc_info;
mod tests;
mod utils;
+const USAGE: &str = r#"The build system of cg_clif.
+
+USAGE:
+ ./y.rs prepare [--out-dir DIR]
+ ./y.rs build [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
+ ./y.rs test [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
+
+OPTIONS:
+ --sysroot none|clif|llvm
+ Which sysroot libraries to use:
+ `none` will not include any standard library in the sysroot.
+ `clif` will build the standard library using Cranelift.
+ `llvm` will use the pre-compiled standard library of rustc which is compiled with LLVM.
+
+ --out-dir DIR
+ Specify the directory in which the download, build and dist directories are stored.
+ By default this is the working directory.
+
+ --no-unstable-features
+ fSome features are not yet ready for production usage. This option will disable these
+ features. This includes the JIT mode and inline assembly support.
+"#;
+
fn usage() {
- eprintln!("Usage:");
- eprintln!(" ./y.rs prepare");
- eprintln!(
- " ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
- );
- eprintln!(
- " ./y.rs test [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
- );
+ eprintln!("{USAGE}");
}
macro_rules! arg_error {
@@ -34,6 +51,7 @@ macro_rules! arg_error {
#[derive(PartialEq, Debug)]
enum Command {
+ Prepare,
Build,
Test,
}
@@ -48,8 +66,6 @@ pub(crate) enum SysrootKind {
pub 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");
if is_ci() {
// Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
@@ -58,13 +74,7 @@ pub fn main() {
let mut args = env::args().skip(1);
let command = match args.next().as_deref() {
- Some("prepare") => {
- if args.next().is_some() {
- arg_error!("./y.rs prepare doesn't expect arguments");
- }
- prepare::prepare();
- process::exit(0);
- }
+ Some("prepare") => Command::Prepare,
Some("build") => Command::Build,
Some("test") => Command::Test,
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
@@ -75,15 +85,15 @@ pub fn main() {
}
};
- let mut target_dir = PathBuf::from("build");
+ let mut out_dir = PathBuf::from(".");
let mut channel = "release";
let mut sysroot_kind = SysrootKind::Clif;
let mut use_unstable_features = true;
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");
+ "--out-dir" => {
+ out_dir = PathBuf::from(args.next().unwrap_or_else(|| {
+ arg_error!("--out-dir requires argument");
}))
}
"--debug" => channel = "debug",
@@ -101,7 +111,6 @@ pub fn main() {
arg => arg_error!("Unexpected argument {}", arg),
}
}
- target_dir = std::env::current_dir().unwrap().join(target_dir);
let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
host_triple
@@ -122,13 +131,43 @@ pub fn main() {
host_triple.clone()
};
- let cg_clif_dylib = build_backend::build_backend(channel, &host_triple, use_unstable_features);
+ // FIXME allow changing the location of these dirs using cli arguments
+ let current_dir = std::env::current_dir().unwrap();
+ out_dir = current_dir.join(out_dir);
+ let dirs = path::Dirs {
+ source_dir: current_dir.clone(),
+ download_dir: out_dir.join("download"),
+ build_dir: out_dir.join("build"),
+ dist_dir: out_dir.join("dist"),
+ };
+
+ path::RelPath::BUILD.ensure_exists(&dirs);
+
+ {
+ // Make sure we always explicitly specify the target dir
+ let target =
+ path::RelPath::BUILD.join("target_dir_should_be_set_explicitly").to_path(&dirs);
+ env::set_var("CARGO_TARGET_DIR", &target);
+ let _ = std::fs::remove_file(&target);
+ std::fs::File::create(target).unwrap();
+ }
+
+ if command == Command::Prepare {
+ prepare::prepare(&dirs);
+ process::exit(0);
+ }
+
+ let cg_clif_dylib =
+ build_backend::build_backend(&dirs, channel, &host_triple, use_unstable_features);
match command {
+ Command::Prepare => {
+ // Handled above
+ }
Command::Test => {
tests::run_tests(
+ &dirs,
channel,
sysroot_kind,
- &target_dir,
&cg_clif_dylib,
&host_triple,
&target_triple,
@@ -137,7 +176,7 @@ pub fn main() {
abi_cafe::run(
channel,
sysroot_kind,
- &target_dir,
+ &dirs,
&cg_clif_dylib,
&host_triple,
&target_triple,
@@ -145,9 +184,9 @@ pub fn main() {
}
Command::Build => {
build_sysroot::build_sysroot(
+ &dirs,
channel,
sysroot_kind,
- &target_dir,
&cg_clif_dylib,
&host_triple,
&target_triple,
diff --git a/compiler/rustc_codegen_cranelift/build_system/path.rs b/compiler/rustc_codegen_cranelift/build_system/path.rs
new file mode 100644
index 000000000..e93981f1d
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/build_system/path.rs
@@ -0,0 +1,70 @@
+use std::fs;
+use std::path::PathBuf;
+
+#[derive(Debug, Clone)]
+pub(crate) struct Dirs {
+ pub(crate) source_dir: PathBuf,
+ pub(crate) download_dir: PathBuf,
+ pub(crate) build_dir: PathBuf,
+ pub(crate) dist_dir: PathBuf,
+}
+
+#[doc(hidden)]
+#[derive(Debug, Copy, Clone)]
+pub(crate) enum PathBase {
+ Source,
+ Download,
+ Build,
+ Dist,
+}
+
+impl PathBase {
+ fn to_path(self, dirs: &Dirs) -> PathBuf {
+ match self {
+ PathBase::Source => dirs.source_dir.clone(),
+ PathBase::Download => dirs.download_dir.clone(),
+ PathBase::Build => dirs.build_dir.clone(),
+ PathBase::Dist => dirs.dist_dir.clone(),
+ }
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub(crate) enum RelPath {
+ Base(PathBase),
+ Join(&'static RelPath, &'static str),
+}
+
+impl RelPath {
+ pub(crate) const SOURCE: RelPath = RelPath::Base(PathBase::Source);
+ pub(crate) const DOWNLOAD: RelPath = RelPath::Base(PathBase::Download);
+ pub(crate) const BUILD: RelPath = RelPath::Base(PathBase::Build);
+ pub(crate) const DIST: RelPath = RelPath::Base(PathBase::Dist);
+
+ pub(crate) const SCRIPTS: RelPath = RelPath::SOURCE.join("scripts");
+ pub(crate) const BUILD_SYSROOT: RelPath = RelPath::SOURCE.join("build_sysroot");
+ pub(crate) const PATCHES: RelPath = RelPath::SOURCE.join("patches");
+
+ pub(crate) const fn join(&'static self, suffix: &'static str) -> RelPath {
+ RelPath::Join(self, suffix)
+ }
+
+ pub(crate) fn to_path(&self, dirs: &Dirs) -> PathBuf {
+ match self {
+ RelPath::Base(base) => base.to_path(dirs),
+ RelPath::Join(base, suffix) => base.to_path(dirs).join(suffix),
+ }
+ }
+
+ pub(crate) fn ensure_exists(&self, dirs: &Dirs) {
+ fs::create_dir_all(self.to_path(dirs)).unwrap();
+ }
+
+ pub(crate) fn ensure_fresh(&self, dirs: &Dirs) {
+ let path = self.to_path(dirs);
+ if path.exists() {
+ fs::remove_dir_all(&path).unwrap();
+ }
+ fs::create_dir_all(path).unwrap();
+ }
+}
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index 3111f62f6..8ac67e8f9 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -1,92 +1,75 @@
-use std::env;
use std::ffi::OsStr;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::Command;
+use super::build_sysroot::{SYSROOT_RUSTC_VERSION, SYSROOT_SRC};
+use super::path::{Dirs, RelPath};
use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
-use super::utils::{cargo_command, copy_dir_recursively, spawn_and_wait};
-
-pub(crate) const ABI_CAFE: GitRepo =
- GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
-
-pub(crate) const RAND: GitRepo =
- GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
-
-pub(crate) const REGEX: GitRepo =
- GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex");
-
-pub(crate) const PORTABLE_SIMD: GitRepo = GitRepo::github(
- "rust-lang",
- "portable-simd",
- "d5cd4a8112d958bd3a252327e0d069a6363249bd",
- "portable-simd",
-);
-
-pub(crate) const SIMPLE_RAYTRACER: GitRepo = GitRepo::github(
- "ebobby",
- "simple-raytracer",
- "804a7a21b9e673a482797aa289a18ed480e4d813",
- "<none>",
-);
-
-pub(crate) fn prepare() {
- if Path::new("download").exists() {
- std::fs::remove_dir_all(Path::new("download")).unwrap();
+use super::utils::{copy_dir_recursively, spawn_and_wait, Compiler};
+
+pub(crate) fn prepare(dirs: &Dirs) {
+ if RelPath::DOWNLOAD.to_path(dirs).exists() {
+ std::fs::remove_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
}
- std::fs::create_dir_all(Path::new("download")).unwrap();
+ std::fs::create_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
- prepare_sysroot();
+ prepare_sysroot(dirs);
// FIXME maybe install this only locally?
eprintln!("[INSTALL] hyperfine");
- Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
+ Command::new("cargo")
+ .arg("install")
+ .arg("hyperfine")
+ .env_remove("CARGO_TARGET_DIR")
+ .spawn()
+ .unwrap()
+ .wait()
+ .unwrap();
- ABI_CAFE.fetch();
- RAND.fetch();
- REGEX.fetch();
- PORTABLE_SIMD.fetch();
- SIMPLE_RAYTRACER.fetch();
+ super::abi_cafe::ABI_CAFE_REPO.fetch(dirs);
+ super::tests::RAND_REPO.fetch(dirs);
+ super::tests::REGEX_REPO.fetch(dirs);
+ super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
+ super::tests::SIMPLE_RAYTRACER_REPO.fetch(dirs);
eprintln!("[LLVM BUILD] simple-raytracer");
- let build_cmd = cargo_command("cargo", "build", None, &SIMPLE_RAYTRACER.source_dir());
+ let host_compiler = Compiler::host();
+ let build_cmd = super::tests::SIMPLE_RAYTRACER.build(&host_compiler, dirs);
spawn_and_wait(build_cmd);
fs::copy(
- SIMPLE_RAYTRACER
- .source_dir()
- .join("target")
+ super::tests::SIMPLE_RAYTRACER
+ .target_dir(dirs)
+ .join(&host_compiler.triple)
.join("debug")
.join(get_file_name("main", "bin")),
- SIMPLE_RAYTRACER.source_dir().join(get_file_name("raytracer_cg_llvm", "bin")),
+ RelPath::BUILD.to_path(dirs).join(get_file_name("raytracer_cg_llvm", "bin")),
)
.unwrap();
}
-fn prepare_sysroot() {
+fn prepare_sysroot(dirs: &Dirs) {
let rustc_path = get_rustc_path();
let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
- let sysroot_src = env::current_dir().unwrap().join("build_sysroot").join("sysroot_src");
+ let sysroot_src = 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();
+ sysroot_src.ensure_fresh(dirs);
+ fs::create_dir_all(sysroot_src.to_path(dirs).join("library")).unwrap();
eprintln!("[COPY] sysroot src");
- copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
+ copy_dir_recursively(
+ &sysroot_src_orig.join("library"),
+ &sysroot_src.to_path(dirs).join("library"),
+ );
let rustc_version = get_rustc_version();
- fs::write(Path::new("build_sysroot").join("rustc_version"), &rustc_version).unwrap();
+ fs::write(SYSROOT_RUSTC_VERSION.to_path(dirs), &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);
- spawn_and_wait(git_init_cmd);
-
- init_git_repo(&sysroot_src);
+ init_git_repo(&sysroot_src.to_path(dirs));
- apply_patches("sysroot", &sysroot_src);
+ apply_patches(dirs, "sysroot", &sysroot_src.to_path(dirs));
}
pub(crate) struct GitRepo {
@@ -100,7 +83,7 @@ enum GitRepoUrl {
}
impl GitRepo {
- const fn github(
+ pub(crate) const fn github(
user: &'static str,
repo: &'static str,
rev: &'static str,
@@ -109,21 +92,25 @@ impl GitRepo {
GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
}
- pub(crate) fn source_dir(&self) -> PathBuf {
+ pub(crate) const fn source_dir(&self) -> RelPath {
match self.url {
- GitRepoUrl::Github { user: _, repo } => {
- std::env::current_dir().unwrap().join("download").join(repo)
- }
+ GitRepoUrl::Github { user: _, repo } => RelPath::DOWNLOAD.join(repo),
}
}
- fn fetch(&self) {
+ fn fetch(&self, dirs: &Dirs) {
match self.url {
GitRepoUrl::Github { user, repo } => {
- clone_repo_shallow_github(&self.source_dir(), user, repo, self.rev);
+ clone_repo_shallow_github(
+ dirs,
+ &self.source_dir().to_path(dirs),
+ user,
+ repo,
+ self.rev,
+ );
}
}
- apply_patches(self.patch_name, &self.source_dir());
+ apply_patches(dirs, self.patch_name, &self.source_dir().to_path(dirs));
}
}
@@ -142,18 +129,16 @@ fn clone_repo(download_dir: &Path, repo: &str, rev: &str) {
spawn_and_wait(checkout_cmd);
}
-fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &str) {
+fn clone_repo_shallow_github(dirs: &Dirs, download_dir: &Path, user: &str, repo: &str, rev: &str) {
if cfg!(windows) {
// Older windows doesn't have tar or curl by default. Fall back to using git.
clone_repo(download_dir, &format!("https://github.com/{}/{}.git", user, repo), rev);
return;
}
- let downloads_dir = std::env::current_dir().unwrap().join("download");
-
let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", user, repo, rev);
- let archive_file = downloads_dir.join(format!("{}.tar.gz", rev));
- let archive_dir = downloads_dir.join(format!("{}-{}", repo, rev));
+ let archive_file = RelPath::DOWNLOAD.to_path(dirs).join(format!("{}.tar.gz", rev));
+ let archive_dir = RelPath::DOWNLOAD.to_path(dirs).join(format!("{}-{}", repo, rev));
eprintln!("[DOWNLOAD] {}/{} from {}", user, repo, archive_url);
@@ -169,7 +154,7 @@ fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &
// Unpack tar archive
let mut unpack_cmd = Command::new("tar");
- unpack_cmd.arg("xf").arg(&archive_file).current_dir(downloads_dir);
+ unpack_cmd.arg("xf").arg(&archive_file).current_dir(RelPath::DOWNLOAD.to_path(dirs));
spawn_and_wait(unpack_cmd);
// Rename unpacked dir to the expected name
@@ -191,12 +176,21 @@ fn init_git_repo(repo_dir: &Path) {
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(repo_dir);
+ git_commit_cmd
+ .arg("-c")
+ .arg("user.name=Dummy")
+ .arg("-c")
+ .arg("user.email=dummy@example.com")
+ .arg("commit")
+ .arg("-m")
+ .arg("Initial commit")
+ .arg("-q")
+ .current_dir(repo_dir);
spawn_and_wait(git_commit_cmd);
}
-fn get_patches(source_dir: &Path, crate_name: &str) -> Vec<PathBuf> {
- let mut patches: Vec<_> = fs::read_dir(source_dir.join("patches"))
+fn get_patches(dirs: &Dirs, crate_name: &str) -> Vec<PathBuf> {
+ let mut patches: Vec<_> = fs::read_dir(RelPath::PATCHES.to_path(dirs))
.unwrap()
.map(|entry| entry.unwrap().path())
.filter(|path| path.extension() == Some(OsStr::new("patch")))
@@ -215,19 +209,27 @@ fn get_patches(source_dir: &Path, crate_name: &str) -> Vec<PathBuf> {
patches
}
-fn apply_patches(crate_name: &str, target_dir: &Path) {
+fn apply_patches(dirs: &Dirs, crate_name: &str, target_dir: &Path) {
if crate_name == "<none>" {
return;
}
- for patch in get_patches(&std::env::current_dir().unwrap(), crate_name) {
+ for patch in get_patches(dirs, crate_name) {
eprintln!(
"[PATCH] {:?} <- {:?}",
target_dir.file_name().unwrap(),
patch.file_name().unwrap()
);
let mut apply_patch_cmd = Command::new("git");
- apply_patch_cmd.arg("am").arg(patch).arg("-q").current_dir(target_dir);
+ apply_patch_cmd
+ .arg("-c")
+ .arg("user.name=Dummy")
+ .arg("-c")
+ .arg("user.email=dummy@example.com")
+ .arg("am")
+ .arg(patch)
+ .arg("-q")
+ .current_dir(target_dir);
spawn_and_wait(apply_patch_cmd);
}
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs b/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs
index 3c08b6fa3..8e5ab688e 100644
--- a/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs
@@ -23,6 +23,16 @@ pub(crate) fn get_host_triple() -> String {
.to_owned()
}
+pub(crate) fn get_cargo_path() -> PathBuf {
+ let cargo_path = Command::new("rustup")
+ .stderr(Stdio::inherit())
+ .args(&["which", "cargo"])
+ .output()
+ .unwrap()
+ .stdout;
+ Path::new(String::from_utf8(cargo_path).unwrap().trim()).to_owned()
+}
+
pub(crate) fn get_rustc_path() -> PathBuf {
let rustc_path = Command::new("rustup")
.stderr(Stdio::inherit())
@@ -33,6 +43,16 @@ pub(crate) fn get_rustc_path() -> PathBuf {
Path::new(String::from_utf8(rustc_path).unwrap().trim()).to_owned()
}
+pub(crate) fn get_rustdoc_path() -> PathBuf {
+ let rustc_path = Command::new("rustup")
+ .stderr(Stdio::inherit())
+ .args(&["which", "rustdoc"])
+ .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/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index a414b60f4..1c372736e 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -1,15 +1,20 @@
use super::build_sysroot;
use super::config;
-use super::prepare;
-use super::rustc_info::get_wrapper_file_name;
-use super::utils::{cargo_command, hyperfine_command, spawn_and_wait, spawn_and_wait_with_input};
-use build_system::SysrootKind;
+use super::path::{Dirs, RelPath};
+use super::prepare::GitRepo;
+use super::rustc_info::{get_cargo_path, get_wrapper_file_name};
+use super::utils::{
+ hyperfine_command, spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler,
+};
+use super::SysrootKind;
use std::env;
use std::ffi::OsStr;
use std::fs;
-use std::path::{Path, PathBuf};
+use std::path::Path;
use std::process::Command;
+static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example");
+
struct TestCase {
config: &'static str,
func: &'static dyn Fn(&TestRunner),
@@ -30,7 +35,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"lib,dylib",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
}),
TestCase::new("build.example", &|runner| {
@@ -39,7 +44,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"lib",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
}),
TestCase::new("jit.mini_core_hello_world", &|runner| {
@@ -51,7 +56,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
"--cfg",
"jit",
"--target",
- &runner.host_triple,
+ &runner.target_compiler.triple,
]);
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
spawn_and_wait(jit_cmd);
@@ -65,7 +70,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
"--cfg",
"jit",
"--target",
- &runner.host_triple,
+ &runner.target_compiler.triple,
]);
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
spawn_and_wait(jit_cmd);
@@ -79,7 +84,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
"bin",
"-g",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]);
}),
@@ -94,7 +99,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"bin",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []);
}),
@@ -106,7 +111,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"bin",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("issue_91827_extern_types", []);
}),
@@ -116,7 +121,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"lib",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
}),
TestCase::new("aot.alloc_example", &|runner| {
@@ -125,7 +130,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"bin",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("alloc_example", []);
}),
@@ -136,7 +141,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"-Cprefer-dynamic",
"example/std_example.rs",
"--target",
- &runner.host_triple,
+ &runner.target_compiler.triple,
]);
eprintln!("[JIT-lazy] std_example");
@@ -146,7 +151,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"-Cprefer-dynamic",
"example/std_example.rs",
"--target",
- &runner.host_triple,
+ &runner.target_compiler.triple,
]);
}),
TestCase::new("aot.std_example", &|runner| {
@@ -155,7 +160,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"bin",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("std_example", ["arg"]);
}),
@@ -167,7 +172,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"bin",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("dst_field_align", []);
}),
@@ -178,7 +183,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"bin",
"-Cpanic=abort",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("subslice-patterns-const-eval", []);
}),
@@ -189,7 +194,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"bin",
"-Cpanic=abort",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("track-caller-attribute", []);
}),
@@ -200,7 +205,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"bin",
"-Cpanic=abort",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("float-minmax-pass", []);
}),
@@ -210,205 +215,252 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
"--crate-type",
"bin",
"--target",
- &runner.target_triple,
+ &runner.target_compiler.triple,
]);
runner.run_out_command("mod_bench", []);
}),
+ TestCase::new("aot.issue-72793", &|runner| {
+ runner.run_rustc([
+ "example/issue-72793.rs",
+ "--crate-type",
+ "bin",
+ "--target",
+ &runner.target_compiler.triple,
+ ]);
+ runner.run_out_command("issue-72793", []);
+ }),
];
+pub(crate) static RAND_REPO: GitRepo =
+ GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
+
+static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand");
+
+pub(crate) static REGEX_REPO: GitRepo =
+ GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex");
+
+static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir(), "regex");
+
+pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
+ "rust-lang",
+ "portable-simd",
+ "d5cd4a8112d958bd3a252327e0d069a6363249bd",
+ "portable-simd",
+);
+
+static PORTABLE_SIMD: CargoProject =
+ CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable_simd");
+
+pub(crate) static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
+ "ebobby",
+ "simple-raytracer",
+ "804a7a21b9e673a482797aa289a18ed480e4d813",
+ "<none>",
+);
+
+pub(crate) static SIMPLE_RAYTRACER: CargoProject =
+ CargoProject::new(&SIMPLE_RAYTRACER_REPO.source_dir(), "simple_raytracer");
+
+static LIBCORE_TESTS: CargoProject =
+ CargoProject::new(&RelPath::BUILD_SYSROOT.join("sysroot_src/library/core/tests"), "core_tests");
+
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
TestCase::new("test.rust-random/rand", &|runner| {
- runner.in_dir(prepare::RAND.source_dir(), |runner| {
- runner.run_cargo("clean", []);
-
- if runner.host_triple == runner.target_triple {
- eprintln!("[TEST] rust-random/rand");
- runner.run_cargo("test", ["--workspace"]);
- } else {
- eprintln!("[AOT] rust-random/rand");
- runner.run_cargo("build", ["--workspace", "--tests"]);
- }
- });
+ spawn_and_wait(RAND.clean(&runner.target_compiler.cargo, &runner.dirs));
+
+ if runner.is_native {
+ eprintln!("[TEST] rust-random/rand");
+ let mut test_cmd = RAND.test(&runner.target_compiler, &runner.dirs);
+ test_cmd.arg("--workspace");
+ spawn_and_wait(test_cmd);
+ } else {
+ eprintln!("[AOT] rust-random/rand");
+ let mut build_cmd = RAND.build(&runner.target_compiler, &runner.dirs);
+ build_cmd.arg("--workspace").arg("--tests");
+ spawn_and_wait(build_cmd);
+ }
}),
TestCase::new("bench.simple-raytracer", &|runner| {
- runner.in_dir(prepare::SIMPLE_RAYTRACER.source_dir(), |runner| {
- let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()).parse().unwrap();
-
- if runner.host_triple == runner.target_triple {
- eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
- let prepare = runner.cargo_command("clean", []);
-
- let llvm_build_cmd = cargo_command("cargo", "build", None, Path::new("."));
-
- let cargo_clif = runner
- .root_dir
- .clone()
- .join("build")
- .join(get_wrapper_file_name("cargo-clif", "bin"));
- let clif_build_cmd = cargo_command(cargo_clif, "build", None, Path::new("."));
-
- let bench_compile =
- hyperfine_command(1, run_runs, Some(prepare), llvm_build_cmd, clif_build_cmd);
-
- spawn_and_wait(bench_compile);
-
- eprintln!("[BENCH RUN] ebobby/simple-raytracer");
- fs::copy(PathBuf::from("./target/debug/main"), PathBuf::from("raytracer_cg_clif"))
- .unwrap();
-
- let bench_run = hyperfine_command(
- 0,
- run_runs,
- None,
- Command::new("./raytracer_cg_llvm"),
- Command::new("./raytracer_cg_clif"),
- );
- spawn_and_wait(bench_run);
- } else {
- runner.run_cargo("clean", []);
- eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
- eprintln!("[COMPILE] ebobby/simple-raytracer");
- runner.run_cargo("build", []);
- eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
- }
- });
+ let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()).parse().unwrap();
+
+ if runner.is_native {
+ eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
+ let cargo_clif = RelPath::DIST
+ .to_path(&runner.dirs)
+ .join(get_wrapper_file_name("cargo-clif", "bin"));
+ let manifest_path = SIMPLE_RAYTRACER.manifest_path(&runner.dirs);
+ let target_dir = SIMPLE_RAYTRACER.target_dir(&runner.dirs);
+
+ let clean_cmd = format!(
+ "cargo clean --manifest-path {manifest_path} --target-dir {target_dir}",
+ manifest_path = manifest_path.display(),
+ target_dir = target_dir.display(),
+ );
+ let llvm_build_cmd = format!(
+ "cargo build --manifest-path {manifest_path} --target-dir {target_dir}",
+ manifest_path = manifest_path.display(),
+ target_dir = target_dir.display(),
+ );
+ let clif_build_cmd = format!(
+ "{cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir}",
+ cargo_clif = cargo_clif.display(),
+ manifest_path = manifest_path.display(),
+ target_dir = target_dir.display(),
+ );
+
+ let bench_compile =
+ hyperfine_command(1, run_runs, Some(&clean_cmd), &llvm_build_cmd, &clif_build_cmd);
+
+ spawn_and_wait(bench_compile);
+
+ eprintln!("[BENCH RUN] ebobby/simple-raytracer");
+ fs::copy(
+ target_dir.join("debug").join("main"),
+ RelPath::BUILD.to_path(&runner.dirs).join("raytracer_cg_clif"),
+ )
+ .unwrap();
+
+ let mut bench_run =
+ hyperfine_command(0, run_runs, None, "./raytracer_cg_llvm", "./raytracer_cg_clif");
+ bench_run.current_dir(RelPath::BUILD.to_path(&runner.dirs));
+ spawn_and_wait(bench_run);
+ } else {
+ spawn_and_wait(SIMPLE_RAYTRACER.clean(&runner.target_compiler.cargo, &runner.dirs));
+ eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
+ eprintln!("[COMPILE] ebobby/simple-raytracer");
+ spawn_and_wait(SIMPLE_RAYTRACER.build(&runner.target_compiler, &runner.dirs));
+ eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
+ }
}),
TestCase::new("test.libcore", &|runner| {
- runner.in_dir(
- std::env::current_dir()
- .unwrap()
- .join("build_sysroot")
- .join("sysroot_src")
- .join("library")
- .join("core")
- .join("tests"),
- |runner| {
- runner.run_cargo("clean", []);
-
- if runner.host_triple == runner.target_triple {
- runner.run_cargo("test", []);
- } else {
- eprintln!("Cross-Compiling: Not running tests");
- runner.run_cargo("build", ["--tests"]);
- }
- },
- );
+ spawn_and_wait(LIBCORE_TESTS.clean(&runner.host_compiler.cargo, &runner.dirs));
+
+ if runner.is_native {
+ spawn_and_wait(LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs));
+ } else {
+ eprintln!("Cross-Compiling: Not running tests");
+ let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs);
+ build_cmd.arg("--tests");
+ spawn_and_wait(build_cmd);
+ }
}),
TestCase::new("test.regex-shootout-regex-dna", &|runner| {
- runner.in_dir(prepare::REGEX.source_dir(), |runner| {
- runner.run_cargo("clean", []);
-
- // newer aho_corasick versions throw a deprecation warning
- let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
-
- let mut build_cmd = runner.cargo_command("build", ["--example", "shootout-regex-dna"]);
- build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
- spawn_and_wait(build_cmd);
-
- if runner.host_triple == runner.target_triple {
- let mut run_cmd = runner.cargo_command("run", ["--example", "shootout-regex-dna"]);
- run_cmd.env("RUSTFLAGS", lint_rust_flags);
-
- let input =
- fs::read_to_string(PathBuf::from("examples/regexdna-input.txt")).unwrap();
- let expected_path = PathBuf::from("examples/regexdna-output.txt");
- let expected = fs::read_to_string(&expected_path).unwrap();
-
- let output = spawn_and_wait_with_input(run_cmd, input);
- // Make sure `[codegen mono items] start` doesn't poison the diff
- let output = output
- .lines()
- .filter(|line| !line.contains("codegen mono items"))
- .chain(Some("")) // This just adds the trailing newline
- .collect::<Vec<&str>>()
- .join("\r\n");
-
- let output_matches = expected.lines().eq(output.lines());
- if !output_matches {
- let res_path = PathBuf::from("res.txt");
- fs::write(&res_path, &output).unwrap();
-
- if cfg!(windows) {
- println!("Output files don't match!");
- println!("Expected Output:\n{}", expected);
- println!("Actual Output:\n{}", output);
- } else {
- let mut diff = Command::new("diff");
- diff.arg("-u");
- diff.arg(res_path);
- diff.arg(expected_path);
- spawn_and_wait(diff);
- }
-
- std::process::exit(1);
+ spawn_and_wait(REGEX.clean(&runner.target_compiler.cargo, &runner.dirs));
+
+ // newer aho_corasick versions throw a deprecation warning
+ let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags);
+
+ let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs);
+ build_cmd.arg("--example").arg("shootout-regex-dna");
+ build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
+ spawn_and_wait(build_cmd);
+
+ if runner.is_native {
+ let mut run_cmd = REGEX.run(&runner.target_compiler, &runner.dirs);
+ run_cmd.arg("--example").arg("shootout-regex-dna");
+ run_cmd.env("RUSTFLAGS", lint_rust_flags);
+
+ let input = fs::read_to_string(
+ REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-input.txt"),
+ )
+ .unwrap();
+ let expected_path =
+ REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-output.txt");
+ let expected = fs::read_to_string(&expected_path).unwrap();
+
+ let output = spawn_and_wait_with_input(run_cmd, input);
+ // Make sure `[codegen mono items] start` doesn't poison the diff
+ let output = output
+ .lines()
+ .filter(|line| !line.contains("codegen mono items"))
+ .chain(Some("")) // This just adds the trailing newline
+ .collect::<Vec<&str>>()
+ .join("\r\n");
+
+ let output_matches = expected.lines().eq(output.lines());
+ if !output_matches {
+ let res_path = REGEX.source_dir(&runner.dirs).join("res.txt");
+ fs::write(&res_path, &output).unwrap();
+
+ if cfg!(windows) {
+ println!("Output files don't match!");
+ println!("Expected Output:\n{}", expected);
+ println!("Actual Output:\n{}", output);
+ } else {
+ let mut diff = Command::new("diff");
+ diff.arg("-u");
+ diff.arg(res_path);
+ diff.arg(expected_path);
+ spawn_and_wait(diff);
}
+
+ std::process::exit(1);
}
- });
+ }
}),
TestCase::new("test.regex", &|runner| {
- runner.in_dir(prepare::REGEX.source_dir(), |runner| {
- runner.run_cargo("clean", []);
-
- // newer aho_corasick versions throw a deprecation warning
- let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
-
- if runner.host_triple == runner.target_triple {
- let mut run_cmd = runner.cargo_command(
- "test",
- [
- "--tests",
- "--",
- "--exclude-should-panic",
- "--test-threads",
- "1",
- "-Zunstable-options",
- "-q",
- ],
- );
- run_cmd.env("RUSTFLAGS", lint_rust_flags);
- spawn_and_wait(run_cmd);
- } else {
- eprintln!("Cross-Compiling: Not running tests");
- let mut build_cmd =
- runner.cargo_command("build", ["--tests", "--target", &runner.target_triple]);
- build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
- spawn_and_wait(build_cmd);
- }
- });
+ spawn_and_wait(REGEX.clean(&runner.host_compiler.cargo, &runner.dirs));
+
+ // newer aho_corasick versions throw a deprecation warning
+ let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags);
+
+ if runner.is_native {
+ let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs);
+ run_cmd.args([
+ "--tests",
+ "--",
+ "--exclude-should-panic",
+ "--test-threads",
+ "1",
+ "-Zunstable-options",
+ "-q",
+ ]);
+ run_cmd.env("RUSTFLAGS", lint_rust_flags);
+ spawn_and_wait(run_cmd);
+ } else {
+ eprintln!("Cross-Compiling: Not running tests");
+ let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs);
+ build_cmd.arg("--tests");
+ build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
+ spawn_and_wait(build_cmd);
+ }
}),
TestCase::new("test.portable-simd", &|runner| {
- runner.in_dir(prepare::PORTABLE_SIMD.source_dir(), |runner| {
- runner.run_cargo("clean", []);
- runner.run_cargo("build", ["--all-targets", "--target", &runner.target_triple]);
+ spawn_and_wait(PORTABLE_SIMD.clean(&runner.host_compiler.cargo, &runner.dirs));
- if runner.host_triple == runner.target_triple {
- runner.run_cargo("test", ["-q"]);
- }
- });
+ let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs);
+ build_cmd.arg("--all-targets");
+ spawn_and_wait(build_cmd);
+
+ if runner.is_native {
+ let mut test_cmd = PORTABLE_SIMD.test(&runner.target_compiler, &runner.dirs);
+ test_cmd.arg("-q");
+ spawn_and_wait(test_cmd);
+ }
}),
];
pub(crate) fn run_tests(
+ dirs: &Dirs,
channel: &str,
sysroot_kind: SysrootKind,
- target_dir: &Path,
cg_clif_dylib: &Path,
host_triple: &str,
target_triple: &str,
) {
- let runner = TestRunner::new(host_triple.to_string(), target_triple.to_string());
+ let runner = TestRunner::new(dirs.clone(), host_triple.to_string(), target_triple.to_string());
if config::get_bool("testsuite.no_sysroot") {
build_sysroot::build_sysroot(
+ dirs,
channel,
SysrootKind::None,
- &target_dir,
cg_clif_dylib,
&host_triple,
&target_triple,
);
- let _ = fs::remove_dir_all(Path::new("target").join("out"));
+ BUILD_EXAMPLE_OUT_DIR.ensure_fresh(dirs);
runner.run_testsuite(NO_SYSROOT_SUITE);
} else {
eprintln!("[SKIP] no_sysroot tests");
@@ -419,9 +471,9 @@ pub(crate) fn run_tests(
if run_base_sysroot || run_extended_sysroot {
build_sysroot::build_sysroot(
+ dirs,
channel,
sysroot_kind,
- &target_dir,
cg_clif_dylib,
&host_triple,
&target_triple,
@@ -442,40 +494,50 @@ pub(crate) fn run_tests(
}
struct TestRunner {
- root_dir: PathBuf,
- out_dir: PathBuf,
+ is_native: bool,
jit_supported: bool,
- rust_flags: String,
- run_wrapper: Vec<String>,
- host_triple: String,
- target_triple: String,
+ dirs: Dirs,
+ host_compiler: Compiler,
+ target_compiler: Compiler,
}
impl TestRunner {
- pub fn new(host_triple: String, target_triple: String) -> Self {
- let root_dir = env::current_dir().unwrap();
-
- let mut out_dir = root_dir.clone();
- out_dir.push("target");
- out_dir.push("out");
-
+ pub fn new(dirs: Dirs, host_triple: String, target_triple: String) -> Self {
let is_native = host_triple == target_triple;
let jit_supported =
target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
- let mut rust_flags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
- let mut run_wrapper = Vec::new();
+ let rustc_clif =
+ RelPath::DIST.to_path(&dirs).join(get_wrapper_file_name("rustc-clif", "bin"));
+ let rustdoc_clif =
+ RelPath::DIST.to_path(&dirs).join(get_wrapper_file_name("rustdoc-clif", "bin"));
+
+ let mut rustflags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
+ let mut runner = vec![];
if !is_native {
match target_triple.as_str() {
"aarch64-unknown-linux-gnu" => {
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
- rust_flags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rust_flags);
- run_wrapper = vec!["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"];
+ rustflags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rustflags);
+ runner = vec![
+ "qemu-aarch64".to_owned(),
+ "-L".to_owned(),
+ "/usr/aarch64-linux-gnu".to_owned(),
+ ];
+ }
+ "s390x-unknown-linux-gnu" => {
+ // We are cross-compiling for s390x. Use the correct linker and run tests in qemu.
+ rustflags = format!("-Clinker=s390x-linux-gnu-gcc{}", rustflags);
+ runner = vec![
+ "qemu-s390x".to_owned(),
+ "-L".to_owned(),
+ "/usr/s390x-linux-gnu".to_owned(),
+ ];
}
"x86_64-pc-windows-gnu" => {
// We are cross-compiling for Windows. Run tests in wine.
- run_wrapper = vec!["wine"];
+ runner = vec!["wine".to_owned()];
}
_ => {
println!("Unknown non-native platform");
@@ -484,19 +546,31 @@ impl TestRunner {
}
// FIXME fix `#[linkage = "extern_weak"]` without this
- if host_triple.contains("darwin") {
- rust_flags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rust_flags);
+ if target_triple.contains("darwin") {
+ rustflags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rustflags);
}
- Self {
- root_dir,
- out_dir,
- jit_supported,
- rust_flags,
- run_wrapper: run_wrapper.iter().map(|s| s.to_string()).collect(),
- host_triple,
- target_triple,
- }
+ let host_compiler = Compiler {
+ cargo: get_cargo_path(),
+ rustc: rustc_clif.clone(),
+ rustdoc: rustdoc_clif.clone(),
+ rustflags: String::new(),
+ rustdocflags: String::new(),
+ triple: host_triple,
+ runner: vec![],
+ };
+
+ let target_compiler = Compiler {
+ cargo: get_cargo_path(),
+ rustc: rustc_clif,
+ rustdoc: rustdoc_clif,
+ rustflags: rustflags.clone(),
+ rustdocflags: rustflags,
+ triple: target_triple,
+ runner,
+ };
+
+ Self { is_native, jit_supported, dirs, host_compiler, target_compiler }
}
pub fn run_testsuite(&self, tests: &[TestCase]) {
@@ -516,29 +590,18 @@ impl TestRunner {
}
}
- fn in_dir(&self, new: impl AsRef<Path>, callback: impl FnOnce(&TestRunner)) {
- let current = env::current_dir().unwrap();
-
- env::set_current_dir(new).unwrap();
- callback(self);
- env::set_current_dir(current).unwrap();
- }
-
+ #[must_use]
fn rustc_command<I, S>(&self, args: I) -> Command
where
I: IntoIterator<Item = S>,
S: AsRef<OsStr>,
{
- let mut rustc_clif = self.root_dir.clone();
- rustc_clif.push("build");
- rustc_clif.push(get_wrapper_file_name("rustc-clif", "bin"));
-
- let mut cmd = Command::new(rustc_clif);
- cmd.args(self.rust_flags.split_whitespace());
+ let mut cmd = Command::new(&self.target_compiler.rustc);
+ cmd.args(self.target_compiler.rustflags.split_whitespace());
cmd.arg("-L");
- cmd.arg(format!("crate={}", self.out_dir.display()));
+ cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
cmd.arg("--out-dir");
- cmd.arg(format!("{}", self.out_dir.display()));
+ cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
cmd.arg("-Cdebuginfo=2");
cmd.args(args);
cmd
@@ -559,15 +622,13 @@ impl TestRunner {
let mut full_cmd = vec![];
// Prepend the RUN_WRAPPER's
- if !self.run_wrapper.is_empty() {
- full_cmd.extend(self.run_wrapper.iter().cloned());
+ if !self.target_compiler.runner.is_empty() {
+ full_cmd.extend(self.target_compiler.runner.iter().cloned());
}
- full_cmd.push({
- let mut out_path = self.out_dir.clone();
- out_path.push(name);
- out_path.to_str().unwrap().to_string()
- });
+ full_cmd.push(
+ BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).join(name).to_str().unwrap().to_string(),
+ );
for arg in args.into_iter() {
full_cmd.push(arg.to_string());
@@ -581,30 +642,4 @@ impl TestRunner {
spawn_and_wait(cmd);
}
-
- fn cargo_command<'a, I>(&self, subcommand: &str, args: I) -> Command
- where
- I: IntoIterator<Item = &'a str>,
- {
- let mut cargo_clif = self.root_dir.clone();
- cargo_clif.push("build");
- cargo_clif.push(get_wrapper_file_name("cargo-clif", "bin"));
-
- let mut cmd = cargo_command(
- cargo_clif,
- subcommand,
- if subcommand == "clean" { None } else { Some(&self.target_triple) },
- Path::new("."),
- );
- cmd.args(args);
- cmd.env("RUSTFLAGS", &self.rust_flags);
- cmd
- }
-
- fn run_cargo<'a, I>(&self, subcommand: &str, args: I)
- where
- I: IntoIterator<Item = &'a str>,
- {
- spawn_and_wait(self.cargo_command(subcommand, args));
- }
}
diff --git a/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs
index c627af4e6..2be70e8e4 100644
--- a/compiler/rustc_codegen_cranelift/build_system/utils.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/utils.rs
@@ -1,35 +1,138 @@
use std::env;
use std::fs;
use std::io::Write;
-use std::path::Path;
+use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};
-pub(crate) fn cargo_command(
- cargo: impl AsRef<Path>,
- subcommand: &str,
- triple: Option<&str>,
- source_dir: &Path,
-) -> Command {
- let mut cmd = Command::new(cargo.as_ref());
- cmd.arg(subcommand)
- .arg("--manifest-path")
- .arg(source_dir.join("Cargo.toml"))
- .arg("--target-dir")
- .arg(source_dir.join("target"));
+use super::path::{Dirs, RelPath};
+use super::rustc_info::{get_cargo_path, get_host_triple, get_rustc_path, get_rustdoc_path};
+
+pub(crate) struct Compiler {
+ pub(crate) cargo: PathBuf,
+ pub(crate) rustc: PathBuf,
+ pub(crate) rustdoc: PathBuf,
+ pub(crate) rustflags: String,
+ pub(crate) rustdocflags: String,
+ pub(crate) triple: String,
+ pub(crate) runner: Vec<String>,
+}
+
+impl Compiler {
+ pub(crate) fn host() -> Compiler {
+ Compiler {
+ cargo: get_cargo_path(),
+ rustc: get_rustc_path(),
+ rustdoc: get_rustdoc_path(),
+ rustflags: String::new(),
+ rustdocflags: String::new(),
+ triple: get_host_triple(),
+ runner: vec![],
+ }
+ }
+
+ pub(crate) fn with_triple(triple: String) -> Compiler {
+ Compiler {
+ cargo: get_cargo_path(),
+ rustc: get_rustc_path(),
+ rustdoc: get_rustdoc_path(),
+ rustflags: String::new(),
+ rustdocflags: String::new(),
+ triple,
+ runner: vec![],
+ }
+ }
+}
+
+pub(crate) struct CargoProject {
+ source: &'static RelPath,
+ target: &'static str,
+}
+
+impl CargoProject {
+ pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject {
+ CargoProject { source: path, target }
+ }
+
+ pub(crate) fn source_dir(&self, dirs: &Dirs) -> PathBuf {
+ self.source.to_path(dirs)
+ }
+
+ pub(crate) fn manifest_path(&self, dirs: &Dirs) -> PathBuf {
+ self.source_dir(dirs).join("Cargo.toml")
+ }
+
+ pub(crate) fn target_dir(&self, dirs: &Dirs) -> PathBuf {
+ RelPath::BUILD.join(self.target).to_path(dirs)
+ }
- if let Some(triple) = triple {
- cmd.arg("--target").arg(triple);
+ fn base_cmd(&self, command: &str, cargo: &Path, dirs: &Dirs) -> Command {
+ let mut cmd = Command::new(cargo);
+
+ cmd.arg(command)
+ .arg("--manifest-path")
+ .arg(self.manifest_path(dirs))
+ .arg("--target-dir")
+ .arg(self.target_dir(dirs));
+
+ cmd
+ }
+
+ fn build_cmd(&self, command: &str, compiler: &Compiler, dirs: &Dirs) -> Command {
+ let mut cmd = self.base_cmd(command, &compiler.cargo, dirs);
+
+ cmd.arg("--target").arg(&compiler.triple);
+
+ cmd.env("RUSTC", &compiler.rustc);
+ cmd.env("RUSTDOC", &compiler.rustdoc);
+ cmd.env("RUSTFLAGS", &compiler.rustflags);
+ cmd.env("RUSTDOCFLAGS", &compiler.rustdocflags);
+ if !compiler.runner.is_empty() {
+ cmd.env(
+ format!("CARGO_TARGET_{}_RUNNER", compiler.triple.to_uppercase().replace('-', "_")),
+ compiler.runner.join(" "),
+ );
+ }
+
+ cmd
}
- cmd
+ #[must_use]
+ pub(crate) fn fetch(&self, cargo: impl AsRef<Path>, dirs: &Dirs) -> Command {
+ let mut cmd = Command::new(cargo.as_ref());
+
+ cmd.arg("fetch").arg("--manifest-path").arg(self.manifest_path(dirs));
+
+ cmd
+ }
+
+ #[must_use]
+ pub(crate) fn clean(&self, cargo: &Path, dirs: &Dirs) -> Command {
+ self.base_cmd("clean", cargo, dirs)
+ }
+
+ #[must_use]
+ pub(crate) fn build(&self, compiler: &Compiler, dirs: &Dirs) -> Command {
+ self.build_cmd("build", compiler, dirs)
+ }
+
+ #[must_use]
+ pub(crate) fn test(&self, compiler: &Compiler, dirs: &Dirs) -> Command {
+ self.build_cmd("test", compiler, dirs)
+ }
+
+ #[must_use]
+ pub(crate) fn run(&self, compiler: &Compiler, dirs: &Dirs) -> Command {
+ self.build_cmd("run", compiler, dirs)
+ }
}
+#[must_use]
pub(crate) fn hyperfine_command(
warmup: u64,
runs: u64,
- prepare: Option<Command>,
- a: Command,
- b: Command,
+ prepare: Option<&str>,
+ a: &str,
+ b: &str,
) -> Command {
let mut bench = Command::new("hyperfine");
@@ -42,10 +145,10 @@ pub(crate) fn hyperfine_command(
}
if let Some(prepare) = prepare {
- bench.arg("--prepare").arg(format!("{:?}", prepare));
+ bench.arg("--prepare").arg(prepare);
}
- bench.arg(format!("{:?}", a)).arg(format!("{:?}", b));
+ bench.arg(a).arg(b);
bench
}
diff --git a/compiler/rustc_codegen_cranelift/clean_all.sh b/compiler/rustc_codegen_cranelift/clean_all.sh
index fedab2433..1760e5836 100755
--- a/compiler/rustc_codegen_cranelift/clean_all.sh
+++ b/compiler/rustc_codegen_cranelift/clean_all.sh
@@ -2,7 +2,7 @@
set -e
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
-rm -rf target/ build/ perf.data{,.old} y.bin
+rm -rf target/ build/ dist/ perf.data{,.old} y.bin
rm -rf download/
# Kept for now in case someone updates their checkout of cg_clif before running clean_all.sh
diff --git a/compiler/rustc_codegen_cranelift/config.txt b/compiler/rustc_codegen_cranelift/config.txt
index 0d539191b..258b67e93 100644
--- a/compiler/rustc_codegen_cranelift/config.txt
+++ b/compiler/rustc_codegen_cranelift/config.txt
@@ -40,6 +40,7 @@ aot.subslice-patterns-const-eval
aot.track-caller-attribute
aot.float-minmax-pass
aot.mod_bench
+aot.issue-72793
testsuite.extended_sysroot
test.rust-random/rand
diff --git a/compiler/rustc_codegen_cranelift/docs/usage.md b/compiler/rustc_codegen_cranelift/docs/usage.md
index 33f146e7b..4c2b0fa17 100644
--- a/compiler/rustc_codegen_cranelift/docs/usage.md
+++ b/compiler/rustc_codegen_cranelift/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-clif build
+$ $cg_clif_dir/dist/cargo-clif build
```
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
@@ -19,7 +19,7 @@ This will build your project with rustc_codegen_cranelift instead of the usual L
> You should prefer using the Cargo method.
```bash
-$ $cg_clif_dir/build/rustc-clif my_crate.rs
+$ $cg_clif_dir/dist/rustc-clif my_crate.rs
```
## Jit mode
@@ -32,20 +32,20 @@ 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-clif jit
+$ $cg_clif_dir/dist/cargo-clif jit
```
or
```bash
-$ $cg_clif_dir/build/rustc-clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
+$ $cg_clif_dir/dist/rustc-clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
```
There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
first called.
```bash
-$ $cg_clif_dir/build/cargo-clif lazy-jit
+$ $cg_clif_dir/dist/cargo-clif lazy-jit
```
## Shell
@@ -54,7 +54,7 @@ These are a few functions that allow you to easily run rust code from the shell
```bash
function jit_naked() {
- echo "$@" | $cg_clif_dir/build/rustc-clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic
+ echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic
}
function jit() {
diff --git a/compiler/rustc_codegen_cranelift/example/issue-72793.rs b/compiler/rustc_codegen_cranelift/example/issue-72793.rs
new file mode 100644
index 000000000..b1bb9b8e1
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/example/issue-72793.rs
@@ -0,0 +1,24 @@
+// Adapted from rustc ui test suite (ui/type-alias-impl-trait/issue-72793.rs)
+
+#![feature(type_alias_impl_trait)]
+
+trait T { type Item; }
+
+type Alias<'a> = impl T<Item = &'a ()>;
+
+struct S;
+impl<'a> T for &'a S {
+ type Item = &'a ();
+}
+
+fn filter_positive<'a>() -> Alias<'a> {
+ &S
+}
+
+fn with_positive(fun: impl Fn(Alias<'_>)) {
+ fun(filter_positive());
+}
+
+fn main() {
+ with_positive(|_| ());
+}
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 7f85b52f0..1f9db1eb2 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -19,6 +19,9 @@ pub trait Sized {}
#[lang = "destruct"]
pub trait Destruct {}
+#[lang = "tuple_trait"]
+pub trait Tuple {}
+
#[lang = "unsize"]
pub trait Unsize<T: ?Sized> {}
@@ -443,7 +446,7 @@ pub struct PhantomData<T: ?Sized>;
#[lang = "fn_once"]
#[rustc_paren_sugar]
-pub trait FnOnce<Args> {
+pub trait FnOnce<Args: Tuple> {
#[lang = "fn_once_output"]
type Output;
@@ -452,7 +455,7 @@ pub trait FnOnce<Args> {
#[lang = "fn_mut"]
#[rustc_paren_sugar]
-pub trait FnMut<Args>: FnOnce<Args> {
+pub trait FnMut<Args: Tuple>: FnOnce<Args> {
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
index 215d3556a..c00f8a2e0 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs
@@ -171,8 +171,6 @@ fn main() {
assert_eq!(slice_ptr as usize % 4, 0);
- //return;
-
unsafe {
printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs
index ad108c349..8481d9c39 100644
--- a/compiler/rustc_codegen_cranelift/example/std_example.rs
+++ b/compiler/rustc_codegen_cranelift/example/std_example.rs
@@ -164,6 +164,8 @@ unsafe fn test_simd() {
let cmp_eq = _mm_cmpeq_epi8(y, y);
let cmp_lt = _mm_cmplt_epi8(y, y);
+ let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x);
+ assert_eq!((zero0, zero1), (0, 0));
assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]);
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_eq), [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff]);
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]);
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index c0a2e7a78..d8f28dbcc 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
[toolchain]
-channel = "nightly-2022-10-23"
+channel = "nightly-2022-12-13"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
diff --git a/compiler/rustc_codegen_cranelift/rustfmt.toml b/compiler/rustc_codegen_cranelift/rustfmt.toml
index 2bd8f7d1b..ebeca8662 100644
--- a/compiler/rustc_codegen_cranelift/rustfmt.toml
+++ b/compiler/rustc_codegen_cranelift/rustfmt.toml
@@ -1,3 +1,5 @@
+ignore = ["y.rs"]
+
# Matches rustfmt.toml of rustc
version = "Two"
use_small_heuristics = "Max"
diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
index e6f60d1c0..f782671fe 100755
--- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
@@ -2,7 +2,7 @@
#![forbid(unsafe_code)]/* This line is ignored by bash
# This block is ignored by rustc
pushd $(dirname "$0")/../
-RUSTC="$(pwd)/build/rustc-clif"
+RUSTC="$(pwd)/dist/rustc-clif"
popd
PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic $0
#*/
diff --git a/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs
new file mode 100644
index 000000000..a19d72acf
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs
@@ -0,0 +1,36 @@
+use std::env;
+use std::ffi::OsString;
+#[cfg(unix)]
+use std::os::unix::process::CommandExt;
+use std::path::PathBuf;
+use std::process::Command;
+
+fn main() {
+ let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap());
+
+ let cg_clif_dylib_path = sysroot.join(if cfg!(windows) { "bin" } else { "lib" }).join(
+ env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX,
+ );
+
+ let mut args = std::env::args_os().skip(1).collect::<Vec<_>>();
+ args.push(OsString::from("-Cpanic=abort"));
+ args.push(OsString::from("-Zpanic-abort-tests"));
+ let mut codegen_backend_arg = OsString::from("-Zcodegen-backend=");
+ codegen_backend_arg.push(cg_clif_dylib_path);
+ args.push(codegen_backend_arg);
+ if !args.contains(&OsString::from("--sysroot")) {
+ args.push(OsString::from("--sysroot"));
+ args.push(OsString::from(sysroot.to_str().unwrap()));
+ }
+
+ // Ensure that the right toolchain is used
+ env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN"));
+
+ #[cfg(unix)]
+ Command::new("rustdoc").args(args).exec();
+
+ #[cfg(not(unix))]
+ std::process::exit(
+ Command::new("rustdoc").args(args).spawn().unwrap().wait().unwrap().code().unwrap_or(1),
+ );
+}
diff --git a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
index d6a377895..6c64b7de7 100644
--- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh
@@ -27,24 +27,6 @@ index d95b5b7f17f..00b6f0e3635 100644
[dev-dependencies]
rand = "0.7"
rand_xorshift = "0.2"
-diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
-index 8431aa7b818..a3ff7e68ce5 100644
---- a/src/tools/compiletest/src/runtest.rs
-+++ b/src/tools/compiletest/src/runtest.rs
-@@ -3489,12 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
- let compiler_src_dir = base_dir.join("compiler");
- normalize_path(&compiler_src_dir, "$(echo '$COMPILER_DIR')");
-
-- if let Some(virtual_rust_source_base_dir) =
-- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
-- {
-- normalize_path(&virtual_rust_source_base_dir.join("library"), "$(echo '$SRC_DIR')");
-- normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$(echo '$COMPILER_DIR')");
-- }
-+ normalize_path(&Path::new("$(cd ../build_sysroot/sysroot_src/library; pwd)"), "$(echo '$SRC_DIR')");
-
- // Paths into the build directory
- let test_build_dir = &self.config.build_base;
EOF
cat > config.toml <<EOF
@@ -54,7 +36,7 @@ changelog-seen = 2
ninja = false
[build]
-rustc = "$(pwd)/../build/rustc-clif"
+rustc = "$(pwd)/../dist/rustc-clif"
cargo = "$(rustup which cargo)"
full-bootstrap = true
local-rebuild = true
@@ -69,6 +51,8 @@ popd
# FIXME remove once inline asm is fully supported
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
+export CFG_VIRTUAL_RUST_SOURCE_BASE_DIR="$(cd build_sysroot/sysroot_src; pwd)"
+
# Allow the testsuite to use llvm tools
host_triple=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ")
export LLVM_BIN_DIR="$(rustc --print sysroot)/lib/rustlib/$host_triple/bin"
diff --git a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
index 9b5db3cf8..12ecb8cf4 100755
--- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
+++ b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh
@@ -10,110 +10,118 @@ pushd rust
command -v rg >/dev/null 2>&1 || cargo install ripgrep
-rm -r src/test/ui/{extern/,unsized-locals/,lto/,linkage*} || true
-for test in $(rg --files-with-matches "lto|// needs-asm-support|// needs-unwind" src/test/{ui,incremental}); do
+rm -r tests/ui/{extern/,unsized-locals/,lto/,linkage*} || true
+for test in $(rg --files-with-matches "lto|// needs-asm-support|// needs-unwind" tests/{ui,incremental}); do
rm $test
done
-for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" src/test/ui); do
+for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" tests/ui); do
rm $test
done
-git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
+git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
+git checkout -- tests/ui/proc-macro/pretty-print-hack/
# missing features
# ================
# requires stack unwinding
-rm src/test/incremental/change_crate_dep_kind.rs
-rm src/test/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101)
+rm tests/incremental/change_crate_dep_kind.rs
+rm tests/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101)
# requires compiling with -Cpanic=unwind
-rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/
+rm -r tests/ui/macros/rfc-2011-nicer-assert-messages/
+rm -r tests/run-make/test-benches
# vendor intrinsics
-rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
-rm src/test/ui/intrinsics/const-eval-select-x86_64.rs # requires x86_64 vendor intrinsics
-rm src/test/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
-rm src/test/ui/simd/intrinsic/generic-bitmask-pass.rs # simd_bitmask unimplemented
-rm src/test/ui/simd/intrinsic/generic-as.rs # simd_as unimplemented
-rm src/test/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs # simd_saturating_add unimplemented
-rm src/test/ui/simd/intrinsic/float-math-pass.rs # simd_fcos unimplemented
-rm src/test/ui/simd/intrinsic/generic-gather-pass.rs # simd_gather unimplemented
-rm src/test/ui/simd/intrinsic/generic-select-pass.rs # simd_select_bitmask unimplemented
-rm src/test/ui/simd/issue-85915-simd-ptrs.rs # simd_gather unimplemented
-rm src/test/ui/simd/issue-89193.rs # simd_gather unimplemented
-rm src/test/ui/simd/simd-bitmask.rs # simd_bitmask unimplemented
+rm tests/ui/sse2.rs # cpuid not supported, so sse2 not detected
+rm tests/ui/intrinsics/const-eval-select-x86_64.rs # requires x86_64 vendor intrinsics
+rm tests/ui/simd/array-type.rs # "Index argument for `simd_insert` is not a constant"
+rm tests/ui/simd/intrinsic/generic-bitmask-pass.rs # simd_bitmask unimplemented
+rm tests/ui/simd/intrinsic/generic-as.rs # simd_as unimplemented
+rm tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs # simd_saturating_add unimplemented
+rm tests/ui/simd/intrinsic/float-math-pass.rs # simd_fcos unimplemented
+rm tests/ui/simd/intrinsic/generic-gather-pass.rs # simd_gather unimplemented
+rm tests/ui/simd/intrinsic/generic-select-pass.rs # simd_select_bitmask unimplemented
+rm tests/ui/simd/issue-85915-simd-ptrs.rs # simd_gather unimplemented
+rm tests/ui/simd/issue-89193.rs # simd_gather unimplemented
+rm tests/ui/simd/simd-bitmask.rs # simd_bitmask unimplemented
# exotic linkages
-rm src/test/ui/issues/issue-33992.rs # unsupported linkages
-rm src/test/incremental/hashes/function_interfaces.rs # same
-rm src/test/incremental/hashes/statics.rs # same
+rm tests/ui/issues/issue-33992.rs # unsupported linkages
+rm tests/incremental/hashes/function_interfaces.rs # same
+rm tests/incremental/hashes/statics.rs # same
# variadic arguments
-rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
-rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support
+rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
+rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support
# unsized locals
-rm -r src/test/run-pass-valgrind/unsized-locals
+rm -r tests/run-pass-valgrind/unsized-locals
# misc unimplemented things
-rm src/test/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
-rm src/test/ui/target-feature/missing-plusminus.rs # error not implemented
-rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
-rm -r src/test/run-make/emit-named-files # requires full --emit support
-rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented
-rm src/test/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
+rm tests/ui/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics
+rm tests/ui/target-feature/missing-plusminus.rs # error not implemented
+rm tests/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
+rm -r tests/run-make/emit-named-files # requires full --emit support
+rm tests/ui/abi/stack-probes.rs # stack probes not yet implemented
+rm tests/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
+rm -r tests/run-make/repr128-dwarf # debuginfo test
+rm tests/codegen-units/item-collection/asm-sym.rs # requires support for sym in asm!()
# optimization tests
# ==================
-rm src/test/ui/codegen/issue-28950.rs # depends on stack size optimizations
-rm src/test/ui/codegen/init-large-type.rs # same
-rm src/test/ui/issues/issue-40883.rs # same
-rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
+rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations
+rm tests/ui/codegen/init-large-type.rs # same
+rm tests/ui/issues/issue-40883.rs # same
+rm -r tests/run-make/fmt-write-bloat/ # tests an optimization
# backend specific tests
# ======================
-rm src/test/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM
-rm src/test/ui/abi/stack-protector.rs # requires stack protector support
+rm tests/incremental/thinlto/cgu_invalidated_when_import_{added,removed}.rs # requires LLVM
+rm tests/ui/abi/stack-protector.rs # requires stack protector support
# giving different but possibly correct results
# =============================================
-rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
-rm src/test/ui/mir/mir_raw_fat_ptr.rs # same
-rm src/test/ui/consts/issue-33537.rs # same
+rm tests/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
+rm tests/ui/mir/mir_raw_fat_ptr.rs # same
+rm tests/ui/consts/issue-33537.rs # same
+rm tests/ui/layout/valid_range_oob.rs # different ICE message
# doesn't work due to the way the rustc test suite is invoked.
# should work when using ./x.py test the way it is intended
# ============================================================
-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/rustdoc-* # same
-rm -r src/test/run-make/issue-88756-default-output # same
-rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
+rm -r tests/run-make/emit-shared-files # requires the rustdoc executable in dist/bin/
+rm -r tests/run-make/unstable-flag-required # same
+rm -r tests/run-make/rustdoc-* # same
+rm -r tests/run-make/issue-88756-default-output # same
+rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
+rm -r tests/ui/consts/missing_span_in_backtrace.rs # expects sysroot source to be elsewhere
# genuine bugs
# ============
-rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
+rm tests/incremental/spike-neg1.rs # errors out for some reason
+rm tests/incremental/spike-neg2.rs # same
+rm tests/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
+rm tests/ui/mir/ssa-analysis-regression-50041.rs # produces ICE
+rm tests/ui/type-alias-impl-trait/assoc-projection-ice.rs # produces ICE
-rm src/test/incremental/spike-neg1.rs # errors out for some reason
-rm src/test/incremental/spike-neg2.rs # same
-rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
-rm src/test/ui/mir/ssa-analysis-regression-50041.rs # produces ICE
-rm src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs # produces ICE
+rm tests/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
-rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
+rm tests/ui/runtime/out-of-stack.rs # SIGSEGV instead of SIGABRT for some reason (#1301)
# bugs in the test suite
# ======================
-rm src/test/ui/backtrace.rs # TODO warning
-rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support
-rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
+rm tests/ui/backtrace.rs # TODO warning
+rm tests/ui/simple_global_asm.rs # TODO add needs-asm-support
+rm tests/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
-rm -r src/test/run-make/native-link-modifier-bundle
+rm -r tests/run-make/native-link-modifier-bundle
+rm tests/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
+rm tests/ui/dyn-star/dispatch-on-pin-mut.rs # TODO failed assertion in vtable::get_ptr_and_method_ref
-rm src/test/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
+rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
echo "[TEST] rustc test suite"
-RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
+RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 tests/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
popd
diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
index 1e22537c2..65cc6b437 100644
--- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs
@@ -56,13 +56,13 @@ pub(crate) fn conv_to_call_conv(c: Conv, default_call_conv: CallConv) -> CallCon
pub(crate) fn get_function_sig<'tcx>(
tcx: TyCtxt<'tcx>,
- triple: &target_lexicon::Triple,
+ default_call_conv: CallConv,
inst: Instance<'tcx>,
) -> Signature {
assert!(!inst.substs.needs_infer());
clif_sig_from_fn_abi(
tcx,
- CallConv::triple_default(triple),
+ default_call_conv,
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
)
}
@@ -74,7 +74,7 @@ pub(crate) fn import_function<'tcx>(
inst: Instance<'tcx>,
) -> FuncId {
let name = tcx.symbol_name(inst).name;
- let sig = get_function_sig(tcx, module.isa().triple(), inst);
+ let sig = get_function_sig(tcx, module.target_config().default_call_conv, inst);
match module.declare_function(name, Linkage::Import, &sig) {
Ok(func_id) => func_id,
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
@@ -341,18 +341,16 @@ pub(crate) fn codegen_terminator_call<'tcx>(
destination: Place<'tcx>,
target: Option<BasicBlock>,
) {
- let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
- let fn_sig =
- fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
+ let func = codegen_operand(fx, func);
+ let fn_sig = func.layout().ty.fn_sig(fx.tcx);
let ret_place = codegen_place(fx, destination);
// Handle special calls like intrinsics and empty drop glue.
- let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
- let instance = ty::Instance::resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
- .unwrap()
- .unwrap()
- .polymorphize(fx.tcx);
+ let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
+ let instance =
+ ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
+ .polymorphize(fx.tcx);
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
crate::intrinsics::codegen_llvm_intrinsic_call(
@@ -391,17 +389,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
None
};
- let extra_args = &args[fn_sig.inputs().len()..];
+ let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
let extra_args = fx
.tcx
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
let fn_abi = if let Some(instance) = instance {
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
} else {
- RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
+ RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
};
- let is_cold = if fn_sig.abi == Abi::RustCold {
+ let is_cold = if fn_sig.abi() == Abi::RustCold {
true
} else {
instance
@@ -418,7 +416,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
// Unpack arguments tuple for closures
- let mut args = if fn_sig.abi == Abi::RustCall {
+ let mut args = if fn_sig.abi() == Abi::RustCall {
assert_eq!(args.len(), 2, "rust-call abi requires two arguments");
let self_arg = codegen_call_argument_operand(fx, &args[0]);
let pack_arg = codegen_call_argument_operand(fx, &args[1]);
@@ -486,7 +484,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
fx.add_comment(nop_inst, "indirect call");
}
- let func = codegen_operand(fx, func).load_scalar(fx);
+ let func = func.load_scalar(fx);
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig);
@@ -517,11 +515,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
};
// FIXME find a cleaner way to support varargs
- if fn_sig.c_variadic {
- if !matches!(fn_sig.abi, Abi::C { .. }) {
+ if fn_sig.c_variadic() {
+ if !matches!(fn_sig.abi(), Abi::C { .. }) {
fx.tcx.sess.span_fatal(
source_info.span,
- &format!("Variadic call for non-C abi {:?}", fn_sig.abi),
+ &format!("Variadic call for non-C abi {:?}", fn_sig.abi()),
);
}
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs
index 12bb00d34..850822717 100644
--- a/compiler/rustc_codegen_cranelift/src/allocator.rs
+++ b/compiler/rustc_codegen_cranelift/src/allocator.rs
@@ -66,7 +66,7 @@ fn codegen_inner(
};
let sig = Signature {
- call_conv: CallConv::triple_default(module.isa().triple()),
+ call_conv: module.target_config().default_call_conv,
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
returns: output.into_iter().map(AbiParam::new).collect(),
};
@@ -104,7 +104,7 @@ fn codegen_inner(
}
let sig = Signature {
- call_conv: CallConv::triple_default(module.isa().triple()),
+ call_conv: module.target_config().default_call_conv,
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
returns: vec![],
};
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 1db445027..89d955e8b 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -59,7 +59,7 @@ pub(crate) fn codegen_fn<'tcx>(
// Declare function
let symbol_name = tcx.symbol_name(instance).name.to_string();
- let sig = get_function_sig(tcx, module.isa().triple(), instance);
+ let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance);
let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap();
// Make the FunctionBuilder
@@ -372,8 +372,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
}
}
- TerminatorKind::SwitchInt { discr, switch_ty, targets } => {
- let discr = codegen_operand(fx, discr).load_scalar(fx);
+ TerminatorKind::SwitchInt { discr, targets } => {
+ let discr = codegen_operand(fx, discr);
+ let switch_ty = discr.layout().ty;
+ let discr = discr.load_scalar(fx);
let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind()
|| (targets.iter().count() == 1 && targets.iter().next().unwrap().0 == 0);
@@ -388,11 +390,9 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
_ => unreachable!("{:?}", targets),
};
- let discr = crate::optimize::peephole::maybe_unwrap_bint(&mut fx.bcx, discr);
let (discr, is_inverted) =
crate::optimize::peephole::maybe_unwrap_bool_not(&mut fx.bcx, discr);
let test_zero = if is_inverted { !test_zero } else { test_zero };
- let discr = crate::optimize::peephole::maybe_unwrap_bint(&mut fx.bcx, discr);
if let Some(taken) = crate::optimize::peephole::maybe_known_branch_taken(
&fx.bcx, discr, test_zero,
) {
@@ -569,7 +569,7 @@ fn codegen_stmt<'tcx>(
UnOp::Not => match layout.ty.kind() {
ty::Bool => {
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
- CValue::by_val(fx.bcx.ins().bint(types::I8, res), layout)
+ CValue::by_val(res, layout)
}
ty::Uint(_) | ty::Int(_) => {
CValue::by_val(fx.bcx.ins().bnot(val), layout)
@@ -577,12 +577,6 @@ fn codegen_stmt<'tcx>(
_ => unreachable!("un op Not for {:?}", layout.ty),
},
UnOp::Neg => match layout.ty.kind() {
- ty::Int(IntTy::I128) => {
- // FIXME remove this case once ineg.i128 works
- let zero =
- CValue::const_val(fx, layout, ty::ScalarInt::null(layout.size));
- crate::num::codegen_int_binop(fx, BinOp::Sub, zero, operand)
- }
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
_ => unreachable!("un op Neg for {:?}", layout.ty),
diff --git a/compiler/rustc_codegen_cranelift/src/cast.rs b/compiler/rustc_codegen_cranelift/src/cast.rs
index bad5d1f08..5091c5a9f 100644
--- a/compiler/rustc_codegen_cranelift/src/cast.rs
+++ b/compiler/rustc_codegen_cranelift/src/cast.rs
@@ -149,7 +149,7 @@ pub(crate) fn clif_int_or_float_cast(
}
let is_not_nan = fx.bcx.ins().fcmp(FloatCC::Equal, from, from);
- let zero = fx.bcx.ins().iconst(to_ty, 0);
+ let zero = type_zero_value(&mut fx.bcx, to_ty);
fx.bcx.ins().select(is_not_nan, val, zero)
} else if from_ty.is_float() && to_ty.is_float() {
// float -> float
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index 589594465..2dcd42fbd 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -162,11 +162,20 @@ pub(crate) fn codegen_icmp_imm(
}
}
} else {
- let rhs = i64::try_from(rhs).expect("codegen_icmp_imm rhs out of range for <128bit int");
+ let rhs = rhs as i64; // Truncates on purpose in case rhs is actually an unsigned value
fx.bcx.ins().icmp_imm(intcc, lhs, rhs)
}
}
+pub(crate) fn type_zero_value(bcx: &mut FunctionBuilder<'_>, ty: Type) -> Value {
+ if ty == types::I128 {
+ let zero = bcx.ins().iconst(types::I64, 0);
+ bcx.ins().iconcat(zero, zero)
+ } else {
+ bcx.ins().iconst(ty, 0)
+ }
+}
+
pub(crate) fn type_min_max_value(
bcx: &mut FunctionBuilder<'_>,
ty: Type,
diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs
index a6bde8840..51450897b 100644
--- a/compiler/rustc_codegen_cranelift/src/constant.rs
+++ b/compiler/rustc_codegen_cranelift/src/constant.rs
@@ -28,9 +28,7 @@ impl ConstantCx {
}
pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) {
- //println!("todo {:?}", self.todo);
define_all_allocs(tcx, module, &mut self);
- //println!("done {:?}", self.done);
self.done.clear();
}
}
@@ -268,16 +266,7 @@ fn data_id_for_static(
def_id: DefId,
definition: bool,
) -> DataId {
- let rlinkage = tcx.codegen_fn_attrs(def_id).linkage;
- let linkage = if definition {
- crate::linkage::get_static_linkage(tcx, def_id)
- } else if rlinkage == Some(rustc_middle::mir::mono::Linkage::ExternalWeak)
- || rlinkage == Some(rustc_middle::mir::mono::Linkage::WeakAny)
- {
- Linkage::Preemptible
- } else {
- Linkage::Import
- };
+ let attrs = tcx.codegen_fn_attrs(def_id);
let instance = Instance::mono(tcx, def_id).polymorphize(tcx);
let symbol_name = tcx.symbol_name(instance).name;
@@ -289,25 +278,33 @@ fn data_id_for_static(
};
let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes();
- let attrs = tcx.codegen_fn_attrs(def_id);
+ if let Some(import_linkage) = attrs.import_linkage {
+ assert!(!definition);
- let data_id = match module.declare_data(
- &*symbol_name,
- linkage,
- is_mutable,
- attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
- ) {
- Ok(data_id) => data_id,
- Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
- "attempt to declare `{symbol_name}` as static, but it was already declared as function"
- )),
- Err(err) => Err::<_, _>(err).unwrap(),
- };
+ let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak
+ || import_linkage == rustc_middle::mir::mono::Linkage::WeakAny
+ {
+ Linkage::Preemptible
+ } else {
+ Linkage::Import
+ };
+
+ let data_id = match module.declare_data(
+ &*symbol_name,
+ linkage,
+ is_mutable,
+ attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
+ ) {
+ Ok(data_id) => data_id,
+ Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
+ "attempt to declare `{symbol_name}` as static, but it was already declared as function"
+ )),
+ Err(err) => Err::<_, _>(err).unwrap(),
+ };
- if rlinkage.is_some() {
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
// Declare an internal global `extern_with_linkage_foo` which
- // is initialized with the address of `foo`. If `foo` is
+ // is initialized with the address of `foo`. If `foo` is
// discarded during linking (for example, if `foo` has weak
// linkage and there are no definitions), then
// `extern_with_linkage_foo` will instead be initialized to
@@ -326,10 +323,34 @@ fn data_id_for_static(
Err(ModuleError::DuplicateDefinition(_)) => {}
res => res.unwrap(),
}
- ref_data_id
- } else {
- data_id
+
+ return ref_data_id;
}
+
+ let linkage = if definition {
+ crate::linkage::get_static_linkage(tcx, def_id)
+ } else if attrs.linkage == Some(rustc_middle::mir::mono::Linkage::ExternalWeak)
+ || attrs.linkage == Some(rustc_middle::mir::mono::Linkage::WeakAny)
+ {
+ Linkage::Preemptible
+ } else {
+ Linkage::Import
+ };
+
+ let data_id = match module.declare_data(
+ &*symbol_name,
+ linkage,
+ is_mutable,
+ attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
+ ) {
+ Ok(data_id) => data_id,
+ Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
+ "attempt to declare `{symbol_name}` as static, but it was already declared as function"
+ )),
+ Err(err) => Err::<_, _>(err).unwrap(),
+ };
+
+ data_id
}
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) {
@@ -348,8 +369,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
(data_id, alloc, None)
}
TodoItem::Static(def_id) => {
- //println!("static {:?}", def_id);
-
let section_name = tcx.codegen_fn_attrs(def_id).link_section;
let alloc = tcx.eval_static_initializer(def_id).unwrap();
@@ -359,7 +378,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
}
};
- //("data_id {}", data_id);
if cx.done.contains(&data_id) {
continue;
}
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
index 2ba012a77..28fbcb15b 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs
@@ -68,7 +68,7 @@ impl DebugContext {
.working_dir
.to_string_lossy(FileNameDisplayPreference::Remapped)
.into_owned();
- let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
+ let (name, file_info) = match tcx.sess.local_crate_source_file() {
Some(path) => {
let name = path.to_string_lossy().into_owned();
(name, None)
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
index d26392c49..493359c74 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs
@@ -39,7 +39,9 @@ impl UnwindContext {
}
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
- let unwind_info = if let Some(unwind_info) = context.create_unwind_info(isa).unwrap() {
+ let unwind_info = if let Some(unwind_info) =
+ context.compiled_code().unwrap().create_unwind_info(isa).unwrap()
+ {
unwind_info
} else {
return;
diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs
index 97b395bcd..3cbf313ad 100644
--- a/compiler/rustc_codegen_cranelift/src/discriminant.rs
+++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs
@@ -1,6 +1,7 @@
//! Handling of enum discriminants
//!
-//! Adapted from <https://github.com/rust-lang/rust/blob/d760df5aea483aae041c9a241e7acacf48f75035/src/librustc_codegen_ssa/mir/place.rs>
+//! Adapted from <https://github.com/rust-lang/rust/blob/31c0645b9d2539f47eecb096142474b29dc542f7/compiler/rustc_codegen_ssa/src/mir/place.rs>
+//! (<https://github.com/rust-lang/rust/pull/104535>)
use rustc_target::abi::{Int, TagEncoding, Variants};
@@ -47,13 +48,19 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
} => {
if variant_index != untagged_variant {
let niche = place.place_field(fx, mir::Field::new(tag_field));
+ let niche_type = fx.clif_type(niche.layout().ty).unwrap();
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
- let niche_value = ty::ScalarInt::try_from_uint(
- u128::from(niche_value).wrapping_add(niche_start),
- niche.layout().size,
- )
- .unwrap();
- let niche_llval = CValue::const_val(fx, niche.layout(), niche_value);
+ let niche_value = (niche_value as u128).wrapping_add(niche_start);
+ let niche_value = match niche_type {
+ types::I128 => {
+ let lsb = fx.bcx.ins().iconst(types::I64, niche_value as u64 as i64);
+ let msb =
+ fx.bcx.ins().iconst(types::I64, (niche_value >> 64) as u64 as i64);
+ fx.bcx.ins().iconcat(lsb, msb)
+ }
+ ty => fx.bcx.ins().iconst(ty, niche_value as i64),
+ };
+ let niche_llval = CValue::by_val(niche_value, niche.layout());
niche.write_cvalue(fx, niche_llval);
}
}
@@ -96,6 +103,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
}
};
+ let cast_to_size = dest_layout.layout.size();
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
// Read the tag/niche-encoded discriminant from memory.
@@ -114,21 +122,128 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
dest.write_cvalue(fx, res);
}
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
- // Rebase from niche values to discriminants, and check
- // whether the result is in range for the niche variants.
-
- // We first compute the "relative discriminant" (wrt `niche_variants`),
- // that is, if `n = niche_variants.end() - niche_variants.start()`,
- // we remap `niche_start..=niche_start + n` (which may wrap around)
- // to (non-wrap-around) `0..=n`, to be able to check whether the
- // discriminant corresponds to a niche variant with one comparison.
- // We also can't go directly to the (variant index) discriminant
- // and check that it is in the range `niche_variants`, because
- // that might not fit in the same type, on top of needing an extra
- // comparison (see also the comment on `let niche_discr`).
- let relative_discr = if niche_start == 0 {
- tag
+ let tag_size = tag_scalar.size(fx);
+ let max_unsigned = tag_size.unsigned_int_max();
+ let max_signed = tag_size.signed_int_max() as u128;
+ let min_signed = max_signed + 1;
+ let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
+ let niche_end = niche_start.wrapping_add(relative_max as u128) & max_unsigned;
+ let range = tag_scalar.valid_range(fx);
+
+ let sle = |lhs: u128, rhs: u128| -> bool {
+ // Signed and unsigned comparisons give the same results,
+ // except that in signed comparisons an integer with the
+ // sign bit set is less than one with the sign bit clear.
+ // Toggle the sign bit to do a signed comparison.
+ (lhs ^ min_signed) <= (rhs ^ min_signed)
+ };
+
+ // We have a subrange `niche_start..=niche_end` inside `range`.
+ // If the value of the tag is inside this subrange, it's a
+ // "niche value", an increment of the discriminant. Otherwise it
+ // indicates the untagged variant.
+ // A general algorithm to extract the discriminant from the tag
+ // is:
+ // relative_tag = tag - niche_start
+ // is_niche = relative_tag <= (ule) relative_max
+ // discr = if is_niche {
+ // cast(relative_tag) + niche_variants.start()
+ // } else {
+ // untagged_variant
+ // }
+ // However, we will likely be able to emit simpler code.
+
+ // Find the least and greatest values in `range`, considered
+ // both as signed and unsigned.
+ let (low_unsigned, high_unsigned) =
+ if range.start <= range.end { (range.start, range.end) } else { (0, max_unsigned) };
+ let (low_signed, high_signed) = if sle(range.start, range.end) {
+ (range.start, range.end)
} else {
+ (min_signed, max_signed)
+ };
+
+ let niches_ule = niche_start <= niche_end;
+ let niches_sle = sle(niche_start, niche_end);
+ let cast_smaller = cast_to_size <= tag_size;
+
+ // In the algorithm above, we can change
+ // cast(relative_tag) + niche_variants.start()
+ // into
+ // cast(tag + (niche_variants.start() - niche_start))
+ // if either the casted type is no larger than the original
+ // type, or if the niche values are contiguous (in either the
+ // signed or unsigned sense).
+ let can_incr = cast_smaller || niches_ule || niches_sle;
+
+ let data_for_boundary_niche = || -> Option<(IntCC, u128)> {
+ if !can_incr {
+ None
+ } else if niche_start == low_unsigned {
+ Some((IntCC::UnsignedLessThanOrEqual, niche_end))
+ } else if niche_end == high_unsigned {
+ Some((IntCC::UnsignedGreaterThanOrEqual, niche_start))
+ } else if niche_start == low_signed {
+ Some((IntCC::SignedLessThanOrEqual, niche_end))
+ } else if niche_end == high_signed {
+ Some((IntCC::SignedGreaterThanOrEqual, niche_start))
+ } else {
+ None
+ }
+ };
+
+ let (is_niche, tagged_discr, delta) = if relative_max == 0 {
+ // Best case scenario: only one tagged variant. This will
+ // likely become just a comparison and a jump.
+ // The algorithm is:
+ // is_niche = tag == niche_start
+ // discr = if is_niche {
+ // niche_start
+ // } else {
+ // untagged_variant
+ // }
+ let is_niche = codegen_icmp_imm(fx, IntCC::Equal, tag, niche_start as i128);
+ let tagged_discr =
+ fx.bcx.ins().iconst(cast_to, niche_variants.start().as_u32() as i64);
+ (is_niche, tagged_discr, 0)
+ } else if let Some((predicate, constant)) = data_for_boundary_niche() {
+ // The niche values are either the lowest or the highest in
+ // `range`. We can avoid the first subtraction in the
+ // algorithm.
+ // The algorithm is now this:
+ // is_niche = tag <= niche_end
+ // discr = if is_niche {
+ // cast(tag + (niche_variants.start() - niche_start))
+ // } else {
+ // untagged_variant
+ // }
+ // (the first line may instead be tag >= niche_start,
+ // and may be a signed or unsigned comparison)
+ // The arithmetic must be done before the cast, so we can
+ // have the correct wrapping behavior. See issue #104519 for
+ // the consequences of getting this wrong.
+ let is_niche = codegen_icmp_imm(fx, predicate, tag, constant as i128);
+ let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start);
+ let incr_tag = if delta == 0 {
+ tag
+ } else {
+ let delta = match fx.bcx.func.dfg.value_type(tag) {
+ types::I128 => {
+ let lsb = fx.bcx.ins().iconst(types::I64, delta as u64 as i64);
+ let msb = fx.bcx.ins().iconst(types::I64, (delta >> 64) as u64 as i64);
+ fx.bcx.ins().iconcat(lsb, msb)
+ }
+ ty => fx.bcx.ins().iconst(ty, delta as i64),
+ };
+ fx.bcx.ins().iadd(tag, delta)
+ };
+
+ let cast_tag = clif_intcast(fx, incr_tag, cast_to, !niches_ule);
+
+ (is_niche, cast_tag, 0)
+ } else {
+ // The special cases don't apply, so we'll have to go with
+ // the general algorithm.
let niche_start = match fx.bcx.func.dfg.value_type(tag) {
types::I128 => {
let lsb = fx.bcx.ins().iconst(types::I64, niche_start as u64 as i64);
@@ -138,40 +253,40 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
}
ty => fx.bcx.ins().iconst(ty, niche_start as i64),
};
- fx.bcx.ins().isub(tag, niche_start)
- };
- let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
- let is_niche = {
- codegen_icmp_imm(
+ let relative_discr = fx.bcx.ins().isub(tag, niche_start);
+ let cast_tag = clif_intcast(fx, relative_discr, cast_to, false);
+ let is_niche = crate::common::codegen_icmp_imm(
fx,
IntCC::UnsignedLessThanOrEqual,
relative_discr,
i128::from(relative_max),
- )
+ );
+ (is_niche, cast_tag, niche_variants.start().as_u32() as u128)
};
- // NOTE(eddyb) this addition needs to be performed on the final
- // type, in case the niche itself can't represent all variant
- // indices (e.g. `u8` niche with more than `256` variants,
- // but enough uninhabited variants so that the remaining variants
- // fit in the niche).
- // In other words, `niche_variants.end - niche_variants.start`
- // is representable in the niche, but `niche_variants.end`
- // might not be, in extreme cases.
- let niche_discr = {
- let relative_discr = if relative_max == 0 {
- // HACK(eddyb) since we have only one niche, we know which
- // one it is, and we can avoid having a dynamic value here.
- fx.bcx.ins().iconst(cast_to, 0)
- } else {
- clif_intcast(fx, relative_discr, cast_to, false)
+ let tagged_discr = if delta == 0 {
+ tagged_discr
+ } else {
+ let delta = match cast_to {
+ types::I128 => {
+ let lsb = fx.bcx.ins().iconst(types::I64, delta as u64 as i64);
+ let msb = fx.bcx.ins().iconst(types::I64, (delta >> 64) as u64 as i64);
+ fx.bcx.ins().iconcat(lsb, msb)
+ }
+ ty => fx.bcx.ins().iconst(ty, delta as i64),
};
- fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32()))
+ fx.bcx.ins().iadd(tagged_discr, delta)
};
- let untagged_variant =
- fx.bcx.ins().iconst(cast_to, i64::from(untagged_variant.as_u32()));
- let discr = fx.bcx.ins().select(is_niche, niche_discr, untagged_variant);
+ let untagged_variant = if cast_to == types::I128 {
+ let zero = fx.bcx.ins().iconst(types::I64, 0);
+ let untagged_variant =
+ fx.bcx.ins().iconst(types::I64, i64::from(untagged_variant.as_u32()));
+ fx.bcx.ins().iconcat(untagged_variant, zero)
+ } else {
+ fx.bcx.ins().iconst(cast_to, i64::from(untagged_variant.as_u32()))
+ };
+ let discr = fx.bcx.ins().select(is_niche, tagged_discr, untagged_variant);
let res = CValue::by_val(discr, dest_layout);
dest.write_cvalue(fx, res);
}
diff --git a/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
index 6a430b521..be1b8c9ea 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/jit.rs
@@ -159,7 +159,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
tcx.sess.abort_if_errors();
- jit_module.finalize_definitions();
+ jit_module.finalize_definitions().unwrap();
unsafe { cx.unwind_context.register_jit(&jit_module) };
println!(
@@ -245,7 +245,11 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
let backend_config = lazy_jit_state.backend_config.clone();
let name = tcx.symbol_name(instance).name;
- let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
+ let sig = crate::abi::get_function_sig(
+ tcx,
+ jit_module.target_config().default_call_conv,
+ instance,
+ );
let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap();
let current_ptr = jit_module.read_got_entry(func_id);
@@ -278,7 +282,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
});
assert!(cx.global_asm.is_empty());
- jit_module.finalize_definitions();
+ jit_module.finalize_definitions().unwrap();
unsafe { cx.unwind_context.register_jit(&jit_module) };
jit_module.get_finalized_function(func_id)
})
@@ -344,7 +348,7 @@ fn codegen_shim<'tcx>(
let pointer_type = module.target_config().pointer_type();
let name = tcx.symbol_name(inst).name;
- let sig = crate::abi::get_function_sig(tcx, module.isa().triple(), inst);
+ let sig = crate::abi::get_function_sig(tcx, module.target_config().default_call_conv, inst);
let func_id = module.declare_function(name, Linkage::Export, &sig).unwrap();
let instance_ptr = Box::into_raw(Box::new(inst));
diff --git a/compiler/rustc_codegen_cranelift/src/driver/mod.rs b/compiler/rustc_codegen_cranelift/src/driver/mod.rs
index 8f5714ecb..6e925cea2 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/mod.rs
@@ -24,7 +24,8 @@ fn predefine_mono_items<'tcx>(
MonoItem::Fn(instance) => {
let name = tcx.symbol_name(instance).name;
let _inst_guard = crate::PrintOnPanic(|| format!("{:?} {}", instance, name));
- let sig = get_function_sig(tcx, module.isa().triple(), instance);
+ let sig =
+ get_function_sig(tcx, module.target_config().default_call_conv, instance);
let linkage = crate::linkage::get_clif_linkage(
mono_item,
linkage,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
index 783d426c3..f722e5228 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm.rs
@@ -8,135 +8,37 @@ use rustc_middle::ty::subst::SubstsRef;
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
intrinsic: &str,
- _substs: SubstsRef<'tcx>,
+ substs: SubstsRef<'tcx>,
args: &[mir::Operand<'tcx>],
ret: CPlace<'tcx>,
target: Option<BasicBlock>,
) {
- match intrinsic {
- "llvm.x86.sse2.pause" | "llvm.aarch64.isb" => {
- // Spin loop hint
- }
+ if intrinsic.starts_with("llvm.aarch64") {
+ return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
+ fx, intrinsic, substs, args, ret, target,
+ );
+ }
+ if intrinsic.starts_with("llvm.x86") {
+ return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
+ }
- // Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8`
- "llvm.x86.sse2.pmovmskb.128" | "llvm.x86.avx2.pmovmskb" | "llvm.x86.sse2.movmsk.pd" => {
+ match intrinsic {
+ _ if intrinsic.starts_with("llvm.ctlz.v") => {
intrinsic_args!(fx, args => (a); intrinsic);
- let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
- let lane_ty = fx.clif_type(lane_ty).unwrap();
- assert!(lane_count <= 32);
-
- let mut res = fx.bcx.ins().iconst(types::I32, 0);
-
- for lane in (0..lane_count).rev() {
- let a_lane = a.value_lane(fx, lane).load_scalar(fx);
-
- // cast float to int
- let a_lane = match lane_ty {
- types::F32 => fx.bcx.ins().bitcast(types::I32, a_lane),
- types::F64 => fx.bcx.ins().bitcast(types::I64, a_lane),
- _ => a_lane,
- };
-
- // extract sign bit of an int
- let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_ty.bits() - 1));
-
- // shift sign bit into result
- let a_lane_sign = clif_intcast(fx, a_lane_sign, types::I32, false);
- res = fx.bcx.ins().ishl_imm(res, 1);
- res = fx.bcx.ins().bor(res, a_lane_sign);
- }
-
- let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.i32));
- ret.write_cvalue(fx, res);
- }
- "llvm.x86.sse2.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
- let (x, y, kind) = match args {
- [x, y, kind] => (x, y, kind),
- _ => bug!("wrong number of args for intrinsic {intrinsic}"),
- };
- let x = codegen_operand(fx, x);
- let y = codegen_operand(fx, y);
- let kind = crate::constant::mir_operand_get_const_val(fx, kind)
- .expect("llvm.x86.sse2.cmp.* kind not const");
-
- let flt_cc = match kind
- .try_to_bits(Size::from_bytes(1))
- .unwrap_or_else(|| panic!("kind not scalar: {:?}", kind))
- {
- 0 => FloatCC::Equal,
- 1 => FloatCC::LessThan,
- 2 => FloatCC::LessThanOrEqual,
- 7 => FloatCC::Ordered,
- 3 => FloatCC::Unordered,
- 4 => FloatCC::NotEqual,
- 5 => FloatCC::UnorderedOrGreaterThanOrEqual,
- 6 => FloatCC::UnorderedOrGreaterThan,
- kind => unreachable!("kind {:?}", kind),
- };
-
- simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, res_lane_ty, x_lane, y_lane| {
- let res_lane = match lane_ty.kind() {
- ty::Float(_) => fx.bcx.ins().fcmp(flt_cc, x_lane, y_lane),
- _ => unreachable!("{:?}", lane_ty),
- };
- bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+ fx.bcx.ins().clz(lane)
});
}
- "llvm.x86.sse2.psrli.d" => {
- let (a, imm8) = match args {
- [a, imm8] => (a, imm8),
- _ => bug!("wrong number of args for intrinsic {intrinsic}"),
- };
- let a = codegen_operand(fx, a);
- let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8)
- .expect("llvm.x86.sse2.psrli.d imm8 not const");
- simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm8
- .try_to_bits(Size::from_bytes(4))
- .unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8))
- {
- imm8 if imm8 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm8 as u8)),
- _ => fx.bcx.ins().iconst(types::I32, 0),
- });
- }
- "llvm.x86.sse2.pslli.d" => {
- let (a, imm8) = match args {
- [a, imm8] => (a, imm8),
- _ => bug!("wrong number of args for intrinsic {intrinsic}"),
- };
- let a = codegen_operand(fx, a);
- let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8)
- .expect("llvm.x86.sse2.psrli.d imm8 not const");
+ _ if intrinsic.starts_with("llvm.ctpop.v") => {
+ intrinsic_args!(fx, args => (a); intrinsic);
- simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm8
- .try_to_bits(Size::from_bytes(4))
- .unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8))
- {
- imm8 if imm8 < 32 => fx.bcx.ins().ishl_imm(lane, i64::from(imm8 as u8)),
- _ => fx.bcx.ins().iconst(types::I32, 0),
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+ fx.bcx.ins().popcnt(lane)
});
}
- "llvm.x86.sse2.storeu.dq" => {
- intrinsic_args!(fx, args => (mem_addr, a); intrinsic);
- let mem_addr = mem_addr.load_scalar(fx);
-
- // FIXME correctly handle the unalignment
- let dest = CPlace::for_ptr(Pointer::new(mem_addr), a.layout());
- dest.write_cvalue(fx, a);
- }
- "llvm.x86.addcarry.64" => {
- intrinsic_args!(fx, args => (c_in, a, b); intrinsic);
- let c_in = c_in.load_scalar(fx);
-
- llvm_add_sub(fx, BinOp::Add, ret, c_in, a, b);
- }
- "llvm.x86.subborrow.64" => {
- intrinsic_args!(fx, args => (b_in, a, b); intrinsic);
- let b_in = b_in.load_scalar(fx);
- llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b);
- }
_ => {
fx.tcx
.sess
@@ -150,47 +52,3 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
let ret_block = fx.get_block(dest);
fx.bcx.ins().jump(ret_block, &[]);
}
-
-// llvm.x86.avx2.vperm2i128
-// llvm.x86.ssse3.pshuf.b.128
-// 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);
-}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
new file mode 100644
index 000000000..b431158d2
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_aarch64.rs
@@ -0,0 +1,222 @@
+//! Emulate AArch64 LLVM intrinsics
+
+use crate::intrinsics::*;
+use crate::prelude::*;
+
+use rustc_middle::ty::subst::SubstsRef;
+
+pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ intrinsic: &str,
+ _substs: SubstsRef<'tcx>,
+ args: &[mir::Operand<'tcx>],
+ ret: CPlace<'tcx>,
+ target: Option<BasicBlock>,
+) {
+ // llvm.aarch64.neon.sqshl.v*i*
+
+ match intrinsic {
+ "llvm.aarch64.isb" => {
+ fx.bcx.ins().fence();
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.abs.v") => {
+ intrinsic_args!(fx, args => (a); intrinsic);
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+ fx.bcx.ins().iabs(lane)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.cls.v") => {
+ intrinsic_args!(fx, args => (a); intrinsic);
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+ fx.bcx.ins().cls(lane)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.rbit.v") => {
+ intrinsic_args!(fx, args => (a); intrinsic);
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
+ fx.bcx.ins().bitrev(lane)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sqadd.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
+ crate::num::codegen_saturating_int_binop(fx, BinOp::Add, x_lane, y_lane)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sqsub.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
+ crate::num::codegen_saturating_int_binop(fx, BinOp::Sub, x_lane, y_lane)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.smax.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
+ let gt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, x_lane, y_lane);
+ fx.bcx.ins().select(gt, x_lane, y_lane)
+ },
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.umax.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
+ let gt = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, x_lane, y_lane);
+ fx.bcx.ins().select(gt, x_lane, y_lane)
+ },
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.smaxv.i") => {
+ intrinsic_args!(fx, args => (v); intrinsic);
+
+ simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
+ let gt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, a, b);
+ fx.bcx.ins().select(gt, a, b)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.umaxv.i") => {
+ intrinsic_args!(fx, args => (v); intrinsic);
+
+ simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
+ let gt = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, a, b);
+ fx.bcx.ins().select(gt, a, b)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.smin.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
+ let gt = fx.bcx.ins().icmp(IntCC::SignedLessThan, x_lane, y_lane);
+ fx.bcx.ins().select(gt, x_lane, y_lane)
+ },
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.umin.v") => {
+ intrinsic_args!(fx, args => (x, y); intrinsic);
+
+ simd_pair_for_each_lane(
+ fx,
+ x,
+ y,
+ ret,
+ &|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
+ let gt = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, x_lane, y_lane);
+ fx.bcx.ins().select(gt, x_lane, y_lane)
+ },
+ );
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sminv.i") => {
+ intrinsic_args!(fx, args => (v); intrinsic);
+
+ simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
+ let gt = fx.bcx.ins().icmp(IntCC::SignedLessThan, a, b);
+ fx.bcx.ins().select(gt, a, b)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.uminv.i") => {
+ intrinsic_args!(fx, args => (v); intrinsic);
+
+ simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
+ let gt = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, a, b);
+ fx.bcx.ins().select(gt, a, b)
+ });
+ }
+
+ /*
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sshl.v")
+ || intrinsic.starts_with("llvm.aarch64.neon.sqshl.v")
+ // FIXME split this one out once saturating is implemented
+ || intrinsic.starts_with("llvm.aarch64.neon.sqshlu.v") =>
+ {
+ intrinsic_args!(fx, args => (a, b); intrinsic);
+
+ simd_pair_for_each_lane(fx, a, b, ret, &|fx, _lane_ty, _res_lane_ty, a, b| {
+ // FIXME saturate?
+ fx.bcx.ins().ishl(a, b)
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sqshrn.v") => {
+ let (a, imm32) = match args {
+ [a, imm32] => (a, imm32),
+ _ => bug!("wrong number of args for intrinsic {intrinsic}"),
+ };
+ let a = codegen_operand(fx, a);
+ let imm32 = crate::constant::mir_operand_get_const_val(fx, imm32)
+ .expect("llvm.aarch64.neon.sqshrn.v* imm32 not const");
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm32
+ .try_to_bits(Size::from_bytes(4))
+ .unwrap_or_else(|| panic!("imm32 not scalar: {:?}", imm32))
+ {
+ imm32 if imm32 < 32 => fx.bcx.ins().sshr_imm(lane, i64::from(imm32 as u8)),
+ _ => fx.bcx.ins().iconst(types::I32, 0),
+ });
+ }
+
+ _ if intrinsic.starts_with("llvm.aarch64.neon.sqshrun.v") => {
+ let (a, imm32) = match args {
+ [a, imm32] => (a, imm32),
+ _ => bug!("wrong number of args for intrinsic {intrinsic}"),
+ };
+ let a = codegen_operand(fx, a);
+ let imm32 = crate::constant::mir_operand_get_const_val(fx, imm32)
+ .expect("llvm.aarch64.neon.sqshrn.v* imm32 not const");
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm32
+ .try_to_bits(Size::from_bytes(4))
+ .unwrap_or_else(|| panic!("imm32 not scalar: {:?}", imm32))
+ {
+ imm32 if imm32 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm32 as u8)),
+ _ => fx.bcx.ins().iconst(types::I32, 0),
+ });
+ }
+ */
+ _ => {
+ fx.tcx.sess.warn(&format!(
+ "unsupported AArch64 llvm intrinsic {}; replacing with trap",
+ intrinsic
+ ));
+ crate::trap::trap_unimplemented(fx, intrinsic);
+ return;
+ }
+ }
+
+ let dest = target.expect("all llvm intrinsics used by stdlib should return");
+ let ret_block = fx.get_block(dest);
+ fx.bcx.ins().jump(ret_block, &[]);
+}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
new file mode 100644
index 000000000..7bc161fbe
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -0,0 +1,197 @@
+//! Emulate x86 LLVM intrinsics
+
+use crate::intrinsics::*;
+use crate::prelude::*;
+
+use rustc_middle::ty::subst::SubstsRef;
+
+pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
+ fx: &mut FunctionCx<'_, '_, 'tcx>,
+ intrinsic: &str,
+ _substs: SubstsRef<'tcx>,
+ args: &[mir::Operand<'tcx>],
+ ret: CPlace<'tcx>,
+ target: Option<BasicBlock>,
+) {
+ match intrinsic {
+ "llvm.x86.sse2.pause" | "llvm.aarch64.isb" => {
+ // Spin loop hint
+ }
+
+ // Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8`
+ "llvm.x86.sse2.pmovmskb.128" | "llvm.x86.avx2.pmovmskb" | "llvm.x86.sse2.movmsk.pd" => {
+ intrinsic_args!(fx, args => (a); intrinsic);
+
+ let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
+ let lane_ty = fx.clif_type(lane_ty).unwrap();
+ assert!(lane_count <= 32);
+
+ let mut res = fx.bcx.ins().iconst(types::I32, 0);
+
+ for lane in (0..lane_count).rev() {
+ let a_lane = a.value_lane(fx, lane).load_scalar(fx);
+
+ // cast float to int
+ let a_lane = match lane_ty {
+ types::F32 => fx.bcx.ins().bitcast(types::I32, a_lane),
+ types::F64 => fx.bcx.ins().bitcast(types::I64, a_lane),
+ _ => a_lane,
+ };
+
+ // extract sign bit of an int
+ let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_ty.bits() - 1));
+
+ // shift sign bit into result
+ let a_lane_sign = clif_intcast(fx, a_lane_sign, types::I32, false);
+ res = fx.bcx.ins().ishl_imm(res, 1);
+ res = fx.bcx.ins().bor(res, a_lane_sign);
+ }
+
+ let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.i32));
+ ret.write_cvalue(fx, res);
+ }
+ "llvm.x86.sse2.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
+ let (x, y, kind) = match args {
+ [x, y, kind] => (x, y, kind),
+ _ => bug!("wrong number of args for intrinsic {intrinsic}"),
+ };
+ let x = codegen_operand(fx, x);
+ let y = codegen_operand(fx, y);
+ let kind = crate::constant::mir_operand_get_const_val(fx, kind)
+ .expect("llvm.x86.sse2.cmp.* kind not const");
+
+ let flt_cc = match kind
+ .try_to_bits(Size::from_bytes(1))
+ .unwrap_or_else(|| panic!("kind not scalar: {:?}", kind))
+ {
+ 0 => FloatCC::Equal,
+ 1 => FloatCC::LessThan,
+ 2 => FloatCC::LessThanOrEqual,
+ 7 => FloatCC::Ordered,
+ 3 => FloatCC::Unordered,
+ 4 => FloatCC::NotEqual,
+ 5 => FloatCC::UnorderedOrGreaterThanOrEqual,
+ 6 => FloatCC::UnorderedOrGreaterThan,
+ kind => unreachable!("kind {:?}", kind),
+ };
+
+ simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, res_lane_ty, x_lane, y_lane| {
+ let res_lane = match lane_ty.kind() {
+ ty::Float(_) => fx.bcx.ins().fcmp(flt_cc, x_lane, y_lane),
+ _ => unreachable!("{:?}", lane_ty),
+ };
+ bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)
+ });
+ }
+ "llvm.x86.sse2.psrli.d" => {
+ let (a, imm8) = match args {
+ [a, imm8] => (a, imm8),
+ _ => bug!("wrong number of args for intrinsic {intrinsic}"),
+ };
+ let a = codegen_operand(fx, a);
+ let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8)
+ .expect("llvm.x86.sse2.psrli.d imm8 not const");
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm8
+ .try_to_bits(Size::from_bytes(4))
+ .unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8))
+ {
+ imm8 if imm8 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm8 as u8)),
+ _ => fx.bcx.ins().iconst(types::I32, 0),
+ });
+ }
+ "llvm.x86.sse2.pslli.d" => {
+ let (a, imm8) = match args {
+ [a, imm8] => (a, imm8),
+ _ => bug!("wrong number of args for intrinsic {intrinsic}"),
+ };
+ let a = codegen_operand(fx, a);
+ let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8)
+ .expect("llvm.x86.sse2.psrli.d imm8 not const");
+
+ simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm8
+ .try_to_bits(Size::from_bytes(4))
+ .unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8))
+ {
+ imm8 if imm8 < 32 => fx.bcx.ins().ishl_imm(lane, i64::from(imm8 as u8)),
+ _ => fx.bcx.ins().iconst(types::I32, 0),
+ });
+ }
+ "llvm.x86.sse2.storeu.dq" => {
+ intrinsic_args!(fx, args => (mem_addr, a); intrinsic);
+ let mem_addr = mem_addr.load_scalar(fx);
+
+ // FIXME correctly handle the unalignment
+ let dest = CPlace::for_ptr(Pointer::new(mem_addr), a.layout());
+ dest.write_cvalue(fx, a);
+ }
+ "llvm.x86.addcarry.64" => {
+ intrinsic_args!(fx, args => (c_in, a, b); intrinsic);
+ let c_in = c_in.load_scalar(fx);
+
+ llvm_add_sub(fx, BinOp::Add, ret, c_in, a, b);
+ }
+ "llvm.x86.subborrow.64" => {
+ intrinsic_args!(fx, args => (b_in, a, b); intrinsic);
+ let b_in = b_in.load_scalar(fx);
+
+ llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b);
+ }
+ _ => {
+ fx.tcx.sess.warn(&format!(
+ "unsupported x86 llvm intrinsic {}; replacing with trap",
+ intrinsic
+ ));
+ crate::trap::trap_unimplemented(fx, intrinsic);
+ return;
+ }
+ }
+
+ let dest = target.expect("all llvm intrinsics used by stdlib should return");
+ let ret_block = fx.get_block(dest);
+ fx.bcx.ins().jump(ret_block, &[]);
+}
+
+// llvm.x86.avx2.vperm2i128
+// llvm.x86.ssse3.pshuf.b.128
+// 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);
+}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 0302b843a..e4ac89a7b 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -14,6 +14,8 @@ macro_rules! intrinsic_args {
mod cpuid;
mod llvm;
+mod llvm_aarch64;
+mod llvm_x86;
mod simd;
pub(crate) use cpuid::codegen_cpuid_call;
@@ -195,8 +197,7 @@ fn bool_to_zero_or_max_uint<'tcx>(
ty => ty,
};
- let val = fx.bcx.ins().bint(int_ty, val);
- let mut res = fx.bcx.ins().ineg(val);
+ let mut res = fx.bcx.ins().bmask(int_ty, val);
if ty.is_float() {
res = fx.bcx.ins().bitcast(ty, res);
@@ -632,88 +633,18 @@ fn codegen_regular_intrinsic_call<'tcx>(
ret.write_cvalue(fx, res);
}
sym::bswap => {
- // FIXME(CraneStation/cranelift#794) add bswap instruction to cranelift
- fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
- match bcx.func.dfg.value_type(v) {
- types::I8 => v,
-
- // https://code.woboq.org/gcc/include/bits/byteswap.h.html
- types::I16 => {
- let tmp1 = bcx.ins().ishl_imm(v, 8);
- let n1 = bcx.ins().band_imm(tmp1, 0xFF00);
-
- let tmp2 = bcx.ins().ushr_imm(v, 8);
- let n2 = bcx.ins().band_imm(tmp2, 0x00FF);
-
- bcx.ins().bor(n1, n2)
- }
- types::I32 => {
- let tmp1 = bcx.ins().ishl_imm(v, 24);
- let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000);
-
- let tmp2 = bcx.ins().ishl_imm(v, 8);
- let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000);
-
- let tmp3 = bcx.ins().ushr_imm(v, 8);
- let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00);
-
- let tmp4 = bcx.ins().ushr_imm(v, 24);
- let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF);
-
- let or_tmp1 = bcx.ins().bor(n1, n2);
- let or_tmp2 = bcx.ins().bor(n3, n4);
- bcx.ins().bor(or_tmp1, or_tmp2)
- }
- types::I64 => {
- let tmp1 = bcx.ins().ishl_imm(v, 56);
- let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000_0000_0000u64 as i64);
-
- let tmp2 = bcx.ins().ishl_imm(v, 40);
- let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000_0000_0000u64 as i64);
-
- let tmp3 = bcx.ins().ishl_imm(v, 24);
- let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00_0000_0000u64 as i64);
-
- let tmp4 = bcx.ins().ishl_imm(v, 8);
- let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF_0000_0000u64 as i64);
-
- let tmp5 = bcx.ins().ushr_imm(v, 8);
- let n5 = bcx.ins().band_imm(tmp5, 0x0000_0000_FF00_0000u64 as i64);
-
- let tmp6 = bcx.ins().ushr_imm(v, 24);
- let n6 = bcx.ins().band_imm(tmp6, 0x0000_0000_00FF_0000u64 as i64);
-
- let tmp7 = bcx.ins().ushr_imm(v, 40);
- let n7 = bcx.ins().band_imm(tmp7, 0x0000_0000_0000_FF00u64 as i64);
-
- let tmp8 = bcx.ins().ushr_imm(v, 56);
- let n8 = bcx.ins().band_imm(tmp8, 0x0000_0000_0000_00FFu64 as i64);
-
- let or_tmp1 = bcx.ins().bor(n1, n2);
- let or_tmp2 = bcx.ins().bor(n3, n4);
- let or_tmp3 = bcx.ins().bor(n5, n6);
- let or_tmp4 = bcx.ins().bor(n7, n8);
-
- let or_tmp5 = bcx.ins().bor(or_tmp1, or_tmp2);
- let or_tmp6 = bcx.ins().bor(or_tmp3, or_tmp4);
- bcx.ins().bor(or_tmp5, or_tmp6)
- }
- types::I128 => {
- let (lo, hi) = bcx.ins().isplit(v);
- let lo = swap(bcx, lo);
- let hi = swap(bcx, hi);
- bcx.ins().iconcat(hi, lo)
- }
- ty => unreachable!("bswap {}", ty),
- }
- }
intrinsic_args!(fx, args => (arg); intrinsic);
let val = arg.load_scalar(fx);
- let res = CValue::by_val(swap(&mut fx.bcx, val), arg.layout());
+ let res = if fx.bcx.func.dfg.value_type(val) == types::I8 {
+ val
+ } else {
+ fx.bcx.ins().bswap(val)
+ };
+ let res = CValue::by_val(res, arg.layout());
ret.write_cvalue(fx, res);
}
- sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
+ sym::assert_inhabited | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => {
intrinsic_args!(fx, args => (); intrinsic);
let layout = fx.layout_of(substs.type_at(0));
@@ -742,7 +673,9 @@ fn codegen_regular_intrinsic_call<'tcx>(
return;
}
- if intrinsic == sym::assert_uninit_valid && !fx.tcx.permits_uninit_init(layout) {
+ if intrinsic == sym::assert_mem_uninitialized_valid
+ && !fx.tcx.permits_uninit_init(layout)
+ {
with_no_trimmed_paths!({
crate::base::codegen_panic(
fx,
@@ -936,8 +869,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let old = fx.bcx.ins().atomic_cas(MemFlags::trusted(), ptr, test_old, new);
let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old);
- let ret_val =
- CValue::by_val_pair(old, fx.bcx.ins().bint(types::I8, is_eq), ret.layout());
+ let ret_val = CValue::by_val_pair(old, is_eq, ret.layout());
ret.write_cvalue(fx, ret_val)
}
@@ -1259,8 +1191,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
flags.set_notrap();
let lhs_val = fx.bcx.ins().load(clty, flags, lhs_ref, 0);
let rhs_val = fx.bcx.ins().load(clty, flags, rhs_ref, 0);
- let eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val);
- fx.bcx.ins().bint(types::I8, eq)
+ fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val)
} else {
// Just call `memcmp` (like slices do in core) when the
// size is too large or it's not a power-of-two.
@@ -1270,8 +1201,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
let returns = vec![AbiParam::new(types::I32)];
let args = &[lhs_ref, rhs_ref, bytes_val];
let cmp = fx.lib_call("memcmp", params, returns, args)[0];
- let eq = fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0);
- fx.bcx.ins().bint(types::I8, eq)
+ fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0)
};
ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout()));
}
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 51fce8c85..14f5e9187 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -112,10 +112,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
_ => unreachable!(),
};
- let ty = fx.clif_type(res_lane_ty).unwrap();
-
- let res_lane = fx.bcx.ins().bint(ty, res_lane);
- fx.bcx.ins().ineg(res_lane)
+ bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)
});
}
@@ -716,7 +713,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
let res_type =
Type::int_with_byte_size(u16::try_from(expected_bytes).unwrap()).unwrap();
- let mut res = fx.bcx.ins().iconst(res_type, 0);
+ let mut res = type_zero_value(&mut fx.bcx, res_type);
let lanes = match fx.tcx.sess.target.endian {
Endian::Big => Box::new(0..lane_count) as Box<dyn Iterator<Item = u64>>,
diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs
index f7434633e..c10054e7f 100644
--- a/compiler/rustc_codegen_cranelift/src/main_shim.rs
+++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs
@@ -65,7 +65,7 @@ pub(crate) fn maybe_create_entry_wrapper(
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
call_conv: crate::conv_to_call_conv(
tcx.sess.target.options.entry_abi,
- CallConv::triple_default(m.isa().triple()),
+ m.target_config().default_call_conv,
),
};
@@ -75,7 +75,7 @@ pub(crate) fn maybe_create_entry_wrapper(
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
let main_name = tcx.symbol_name(instance).name;
- let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
+ let main_sig = get_function_sig(tcx, m.target_config().default_call_conv, instance);
let main_func_id = m.declare_function(main_name, Linkage::Import, &main_sig).unwrap();
let mut ctx = Context::new();
@@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
.polymorphize(tcx);
let report_name = tcx.symbol_name(report).name;
- let report_sig = get_function_sig(tcx, m.isa().triple(), report);
+ let report_sig = get_function_sig(tcx, m.target_config().default_call_conv, report);
let report_func_id =
m.declare_function(report_name, Linkage::Import, &report_sig).unwrap();
let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func);
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index ecbab408d..afacbec64 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -49,7 +49,6 @@ fn codegen_compare_bin_op<'tcx>(
) -> CValue<'tcx> {
let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap();
let val = fx.bcx.ins().icmp(intcc, lhs, rhs);
- let val = fx.bcx.ins().bint(types::I8, val);
CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
}
@@ -290,8 +289,6 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
_ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs),
};
- let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow);
-
let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()));
CValue::by_val_pair(res, has_overflow, out_layout)
}
@@ -368,7 +365,6 @@ pub(crate) fn codegen_float_binop<'tcx>(
_ => unreachable!(),
};
let val = fx.bcx.ins().fcmp(fltcc, lhs, rhs);
- let val = fx.bcx.ins().bint(types::I8, val);
return CValue::by_val(val, fx.layout_of(fx.tcx.types.bool));
}
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs),
@@ -440,7 +436,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
_ => panic!("bin_op {:?} on ptr", bin_op),
};
- CValue::by_val(fx.bcx.ins().bint(types::I8, res), fx.layout_of(fx.tcx.types.bool))
+ CValue::by_val(res, fx.layout_of(fx.tcx.types.bool))
}
}
diff --git a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs
index d637b4d89..7f45bbd8f 100644
--- a/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs
+++ b/compiler/rustc_codegen_cranelift/src/optimize/peephole.rs
@@ -3,19 +3,6 @@
use cranelift_codegen::ir::{condcodes::IntCC, InstructionData, Opcode, Value, ValueDef};
use cranelift_frontend::FunctionBuilder;
-/// If the given value was produced by a `bint` instruction, return it's input, otherwise return the
-/// given value.
-pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value {
- if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) {
- match bcx.func.dfg[arg_inst] {
- InstructionData::Unary { opcode: Opcode::Bint, arg } => arg,
- _ => arg,
- }
- } else {
- arg
- }
-}
-
/// If the given value was produced by the lowering of `Rvalue::Not` return the input and true,
/// otherwise return the given value and false.
pub(crate) fn maybe_unwrap_bool_not(bcx: &mut FunctionBuilder<'_>, arg: Value) -> (Value, bool) {
@@ -48,13 +35,6 @@ pub(crate) fn maybe_known_branch_taken(
};
match bcx.func.dfg[arg_inst] {
- InstructionData::UnaryBool { opcode: Opcode::Bconst, imm } => {
- if test_zero {
- Some(!imm)
- } else {
- Some(imm)
- }
- }
InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => {
if test_zero {
Some(imm.bits() == 0)
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index 34746ff6b..fe8af21ac 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -392,7 +392,7 @@ impl<'tcx> CPlace<'tcx> {
local: Local,
layout: TyAndLayout<'tcx>,
) -> CPlace<'tcx> {
- let var = Variable::with_u32(fx.next_ssa_var);
+ let var = Variable::from_u32(fx.next_ssa_var);
fx.next_ssa_var += 1;
fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap());
CPlace { inner: CPlaceInner::Var(local, var), layout }
@@ -403,9 +403,9 @@ impl<'tcx> CPlace<'tcx> {
local: Local,
layout: TyAndLayout<'tcx>,
) -> CPlace<'tcx> {
- let var1 = Variable::with_u32(fx.next_ssa_var);
+ let var1 = Variable::from_u32(fx.next_ssa_var);
fx.next_ssa_var += 1;
- let var2 = Variable::with_u32(fx.next_ssa_var);
+ let var2 = Variable::from_u32(fx.next_ssa_var);
fx.next_ssa_var += 1;
let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap();
@@ -515,9 +515,7 @@ impl<'tcx> CPlace<'tcx> {
| (types::F32, types::I32)
| (types::I64, types::F64)
| (types::F64, types::I64) => fx.bcx.ins().bitcast(dst_ty, data),
- _ if src_ty.is_vector() && dst_ty.is_vector() => {
- fx.bcx.ins().raw_bitcast(dst_ty, data)
- }
+ _ if src_ty.is_vector() && dst_ty.is_vector() => fx.bcx.ins().bitcast(dst_ty, data),
_ if src_ty.is_vector() || dst_ty.is_vector() => {
// FIXME do something more efficient for transmutes between vectors and integers.
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
@@ -590,7 +588,10 @@ impl<'tcx> CPlace<'tcx> {
return;
}
CPlaceInner::VarPair(_local, var1, var2) => {
- let (data1, data2) = CValue(from.0, dst_layout).load_scalar_pair(fx);
+ let (ptr, meta) = from.force_stack(fx);
+ assert!(meta.is_none());
+ let (data1, data2) =
+ CValue(CValueInner::ByRef(ptr, None), dst_layout).load_scalar_pair(fx);
let (dst_ty1, dst_ty2) = fx.clif_pair_type(self.layout().ty).unwrap();
transmute_value(fx, var1, data1, dst_ty1);
transmute_value(fx, var2, data2, dst_ty2);
diff --git a/compiler/rustc_codegen_cranelift/test.sh b/compiler/rustc_codegen_cranelift/test.sh
index 3d929a1d5..13e778453 100755
--- a/compiler/rustc_codegen_cranelift/test.sh
+++ b/compiler/rustc_codegen_cranelift/test.sh
@@ -1,2 +1,2 @@
#!/usr/bin/env bash
-exec ./y.rs test
+exec ./y.rs test "$@"
diff --git a/compiler/rustc_codegen_cranelift/y.rs b/compiler/rustc_codegen_cranelift/y.rs
index f177b91c2..02e1e21ad 100755
--- a/compiler/rustc_codegen_cranelift/y.rs
+++ b/compiler/rustc_codegen_cranelift/y.rs
@@ -3,7 +3,7 @@
# This block is ignored by rustc
set -e
echo "[BUILD] y.rs" 1>&2
-rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1
+rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1 --edition 2021
exec ${0/.rs/.bin} $@
*/