From 482feee3118977db3731f1de171da7dfd043a864 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Sat, 3 May 2025 22:58:27 -0600
Subject: [PATCH 01/29] refactor ub_checks and contract_checks to share logic
---
src/base.rs | 13 ++-----------
1 file changed, 2 insertions(+), 11 deletions(-)
diff --git a/src/base.rs b/src/base.rs
index 7d50548b40262..6a1217a6a49b5 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -841,17 +841,8 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
fields.iter(),
)
.bytes(),
- NullOp::UbChecks => {
- let val = fx.tcx.sess.ub_checks();
- let val = CValue::by_val(
- fx.bcx.ins().iconst(types::I8, i64::from(val)),
- fx.layout_of(fx.tcx.types.bool),
- );
- lval.write_cvalue(fx, val);
- return;
- }
- NullOp::ContractChecks => {
- let val = fx.tcx.sess.contract_checks();
+ NullOp::RuntimeChecks(kind) => {
+ let val = kind.value(fx.tcx.sess);
let val = CValue::by_val(
fx.bcx.ins().iconst(types::I8, i64::from(val)),
fx.layout_of(fx.tcx.types.bool),
From c90a9d836ba72cd3ae6bb0d6ba09883025835d8b Mon Sep 17 00:00:00 2001
From: bjorn3 <17426603+bjorn3@users.noreply.github.com>
Date: Sat, 8 Nov 2025 14:18:53 +0000
Subject: [PATCH 02/29] Merge commit 'a0b865dc8782500efe9623859017dd5e16f85407'
into sync_cg_clif-2025-11-08
---
.cirrus.yml | 44 +--
.github/workflows/abi-cafe.yml | 2 +-
.github/workflows/main.yml | 6 +-
.vscode/settings.json | 6 +-
Cargo.lock | 288 +++++++++++-------
Cargo.toml | 31 +-
Readme.md | 19 +-
build_system/abi_cafe.rs | 2 +
build_system/bench.rs | 2 +-
build_system/build_backend.rs | 7 +-
build_system/build_sysroot.rs | 73 ++---
build_system/main.rs | 7 +
build_system/rustc_info.rs | 30 +-
build_system/tests.rs | 42 ++-
build_system/usage.txt | 4 +
build_system/utils.rs | 4 +-
config.txt | 1 -
example/example.rs | 16 +-
example/mini_core.rs | 22 +-
example/mini_core_hello_world.rs | 85 +++---
example/neon.rs | 52 ++--
example/raw-dylib.rs | 2 +-
example/std_example.rs | 158 +++++-----
...oot_tests-Disable-long-running-tests.patch | 47 +--
rust-toolchain | 2 +-
scripts/cargo-clif.rs | 6 +-
scripts/rustc-clif.rs | 6 +-
scripts/rustdoc-clif.rs | 6 +-
scripts/rustup.sh | 2 +-
scripts/setup_rust_fork.sh | 27 +-
scripts/test_rustc_tests.sh | 29 +-
src/abi/mod.rs | 208 ++++++++++---
src/abi/pass_mode.rs | 7 +-
src/base.rs | 99 ++++--
src/codegen_f16_f128.rs | 11 +-
src/common.rs | 36 +--
src/compiler_builtins.rs | 51 +++-
src/config.rs | 2 +-
src/constant.rs | 76 ++---
src/debuginfo/emit.rs | 6 +-
src/debuginfo/gcc_except_table.rs | 271 ++++++++++++++++
src/debuginfo/line_info.rs | 50 +--
src/debuginfo/mod.rs | 51 +++-
src/debuginfo/types.rs | 4 +-
src/debuginfo/unwind.rs | 191 +++++++++++-
src/driver/aot.rs | 61 ++--
src/driver/jit.rs | 43 ++-
src/driver/mod.rs | 16 +-
src/global_asm.rs | 5 +-
src/inline_asm.rs | 56 ++--
src/intrinsics/mod.rs | 76 ++++-
src/intrinsics/simd.rs | 18 +-
src/lib.rs | 96 ++----
src/main_shim.rs | 6 +-
src/pretty_clif.rs | 9 +-
src/unsize.rs | 2 +-
src/value_and_place.rs | 21 +-
src/vtable.rs | 2 +-
58 files changed, 1667 insertions(+), 835 deletions(-)
create mode 100644 src/debuginfo/gcc_except_table.rs
diff --git a/.cirrus.yml b/.cirrus.yml
index ee5de8b42f465..3ed89beceb7fe 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -1,21 +1,23 @@
-# FIXME re-enable once https://github.com/rust-lang/rust/issues/134863 is fixed.
-# task:
-# name: freebsd
-# freebsd_instance:
-# image: freebsd-13-2-release-amd64
-# setup_rust_script:
-# - pkg install -y git-tiny binutils
-# - curl https://sh.rustup.rs -sSf --output rustup.sh
-# - sh rustup.sh --default-toolchain none -y --profile=minimal
-# target_cache:
-# folder: build/cg_clif
-# prepare_script:
-# - . $HOME/.cargo/env
-# - ./y.sh prepare
-# test_script:
-# - . $HOME/.cargo/env
-# # Disabling incr comp reduces cache size and incr comp doesn't save as much
-# # on CI anyway.
-# - export CARGO_BUILD_INCREMENTAL=false
-# # Skip rand as it fails on FreeBSD due to rust-random/rand#1355
-# - ./y.sh test --skip-test test.rust-random/rand
+task:
+ name: freebsd
+ freebsd_instance:
+ image_family: freebsd-14-2
+ setup_rust_script:
+ - pkg install -y git-tiny binutils
+ - curl https://sh.rustup.rs -sSf --output rustup.sh
+ - sh rustup.sh --default-toolchain none -y --profile=minimal
+ target_cache:
+ folder: build/cg_clif
+ prepare_script:
+ - . $HOME/.cargo/env
+ - ./y.sh prepare
+ test_script:
+ - . $HOME/.cargo/env
+ # Disabling incr comp reduces cache size and incr comp doesn't save as much
+ # on CI anyway.
+ - export CARGO_BUILD_INCREMENTAL=false
+ # FIXME(rust-lang/rust#134863) necessary to avoid error when dlopening proc
+ # macros during compilation of cg_clif.
+ - export LD_STATIC_TLS_EXTRA=4096
+ # Skip rand as it fails on FreeBSD due to rust-random/rand#1355
+ - ./y.sh test --skip-test test.rust-random/rand
diff --git a/.github/workflows/abi-cafe.yml b/.github/workflows/abi-cafe.yml
index 6ad041a796c92..170c7126c296b 100644
--- a/.github/workflows/abi-cafe.yml
+++ b/.github/workflows/abi-cafe.yml
@@ -28,7 +28,7 @@ jobs:
- os: ubuntu-24.04-arm
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
- - os: macos-13
+ - os: macos-15-intel
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: macos-latest
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index d92e0fdce99a8..0930b924d1773 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -56,7 +56,7 @@ jobs:
- os: ubuntu-24.04-arm
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
- - os: macos-13
+ - os: macos-15-intel
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: macos-latest
@@ -187,7 +187,7 @@ jobs:
- os: ubuntu-24.04-arm
env:
TARGET_TRIPLE: aarch64-unknown-linux-gnu
- - os: macos-13
+ - os: macos-15-intel
env:
TARGET_TRIPLE: x86_64-apple-darwin
- os: macos-latest
@@ -231,7 +231,7 @@ jobs:
release:
runs-on: ubuntu-latest
timeout-minutes: 10
- if: ${{ github.ref == 'refs/heads/master' }}
+ if: ${{ github.ref == 'refs/heads/main' }}
needs: [rustfmt, test, bench, dist]
permissions:
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 68bd93aea8901..2a3ec5e1c905a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -20,13 +20,13 @@
"crates": [
{
"root_module": "./example/mini_core.rs",
- "edition": "2015",
+ "edition": "2024",
"deps": [],
"cfg": [],
},
{
"root_module": "./example/mini_core_hello_world.rs",
- "edition": "2015",
+ "edition": "2024",
"deps": [
{
"crate": 0,
@@ -37,7 +37,7 @@
},
{
"root_module": "./example/std_example.rs",
- "edition": "2015",
+ "edition": "2024",
"deps": [],
"cfg": [],
},
diff --git a/Cargo.lock b/Cargo.lock
index b893a2be9a2cb..09b6c6b87c300 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,9 +10,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
[[package]]
name = "anyhow"
-version = "1.0.95"
+version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
[[package]]
name = "arbitrary"
@@ -28,57 +28,57 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
-version = "3.16.0"
+version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
+checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
dependencies = [
"allocator-api2",
]
[[package]]
name = "cfg-if"
-version = "1.0.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "cranelift-assembler-x64"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f53499803b1607b6ee0ba0de4ba036e6da700c2e489fe8f9d0f683d0b84d31"
+checksum = "f502c60b6af2025c312b37788c089943ef03156a2910da1aa046bb39eb8f61c7"
dependencies = [
"cranelift-assembler-x64-meta",
]
[[package]]
name = "cranelift-assembler-x64-meta"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1aadaa5bc8430d0e7bb999459369bedd0e5816ad4a82a0e20748341c4e333eda"
+checksum = "2b7e21a74bcf08443a4ef800a4a257063e5c51ee4d7a3bd58da5262d10340830"
dependencies = [
"cranelift-srcgen",
]
[[package]]
name = "cranelift-bforest"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2005fda2fc52a2dbce58229b4fb4483b70cbc806ba8ecc11b3f050c1a2d26cac"
+checksum = "f337d268865c292ad5df0669a9bbf6223ca41460292a20ad5b0a57b8e9f27f93"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56935e02452ca1249d39ad5c45a96304d0b4300a158a391fd113451e0cd4483d"
+checksum = "c0e60319a8242c8d1c7b5a2444d140c416f903f75e0d84da3256fceb822bab85"
[[package]]
name = "cranelift-codegen"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62612786bf00e10999f50217d6f455d02b31591155881a45a903d1a95d1a4043"
+checksum = "78dee669e447a1c68760bf7acee33835e99d564f0137b067f74d4718dfc9970d"
dependencies = [
"bumpalo",
"cranelift-assembler-x64",
@@ -97,49 +97,50 @@ dependencies = [
"serde",
"smallvec",
"target-lexicon",
- "wasmtime-math",
+ "wasmtime-internal-math",
]
[[package]]
name = "cranelift-codegen-meta"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07bae789df91ef236079733af9df11d852256c64af196f0bc6471ea0f5f301be"
+checksum = "601f629d172b7230f41dd0e78ee797efaf7ec1a5e113c8f395f4027dff6a92ca"
dependencies = [
"cranelift-assembler-x64-meta",
"cranelift-codegen-shared",
"cranelift-srcgen",
+ "heck",
]
[[package]]
name = "cranelift-codegen-shared"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1be319616d36527782558a8312508757815f64deb19b094c7b8f4337229a9bc6"
+checksum = "15755c2660902c7d59d96f6551a66ef629650dc3fd405f9dad841e8c58c1a4a2"
[[package]]
name = "cranelift-control"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8810ee1ab5e9bd5cff4c0c8d240e2009cb5c2b79888fde1d5256d605712314b7"
+checksum = "727bfca18705101a294ab9077ad214a8b762ea2bc9844389d0db233d7c61ec3b"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "086452c97cfbe116bf17dbe622dc5fdf2ea97299c7d4ce42460f284387c9928a"
+checksum = "15564c6f0c72750ca4374f40b044857cbc8087571e46d4c7ccdbdcc29b1dec8b"
dependencies = [
"cranelift-bitset",
]
[[package]]
name = "cranelift-frontend"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c27947010ab759330f252610c17a8cd64d123358be4f33164233d04fcd77b80"
+checksum = "16c681f2731f1cf68eed9f3b6811571823a5ac498f59c52b73736b68599defb3"
dependencies = [
"cranelift-codegen",
"log",
@@ -149,15 +150,15 @@ dependencies = [
[[package]]
name = "cranelift-isle"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec67bfb8bd55b1e9760eb9f5186dca8d81bd4d86110f8d5af01154a044c91802"
+checksum = "40cedc02f08307da019a3e06d3f20f772f829ff813aec975accb012f8930b688"
[[package]]
name = "cranelift-jit"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d67cdfc447f2abdb46bb30a6582cce189539c3c051c1d5330692376e1400edff"
+checksum = "c2864461448c72d15ae3311ea63df9c7e35f22f04683785f6715a0cf17e6577d"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -169,15 +170,15 @@ dependencies = [
"log",
"region",
"target-lexicon",
- "wasmtime-jit-icache-coherence",
- "windows-sys 0.59.0",
+ "wasmtime-internal-jit-icache-coherence",
+ "windows-sys 0.60.2",
]
[[package]]
name = "cranelift-module"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e4597eaa52bca1ed111986c7a7f70cdbe192f83d271d627201365078e37b7e84"
+checksum = "2b31d249bbbccc4c1ae54701087d4d49d05951897691eef44f4a60e70252743b"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -186,9 +187,9 @@ dependencies = [
[[package]]
name = "cranelift-native"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75a9b63edea46e013fce459c46e500462cb03a0490fdd9c18fe42b1dd7b93aa1"
+checksum = "db03ab51c60710eb83d0217725b77db4062aca83b35359f5e6aa99ed1c275977"
dependencies = [
"cranelift-codegen",
"libc",
@@ -197,9 +198,9 @@ dependencies = [
[[package]]
name = "cranelift-object"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ce706f0166d5b7f31693dff521e87cb9858e12adf22ffcde93c4a2826f8f04a9"
+checksum = "7131e0eb45ee10b0bd6082d0c0114c2e9a670b034d46774b39d0fc5c0ed7cedf"
dependencies = [
"anyhow",
"cranelift-codegen",
@@ -212,24 +213,24 @@ dependencies = [
[[package]]
name = "cranelift-srcgen"
-version = "0.121.0"
+version = "0.125.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d5870e266df8237b56cc98b04f5739c228565c92dd629ec6c66efa87271a158"
+checksum = "3d7a06c330b7994a891ad5b622ebc9aefcd17beae832dd25f577cf60c13426bf"
[[package]]
name = "crc32fast"
-version = "1.4.2"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
[[package]]
name = "equivalent"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
+checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "fallible-iterator"
@@ -239,15 +240,15 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
[[package]]
name = "foldhash"
-version = "0.1.4"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "gimli"
-version = "0.31.1"
+version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe"
dependencies = [
"fallible-iterator",
"indexmap",
@@ -256,18 +257,24 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.15.2"
+version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
dependencies = [
"foldhash",
]
+[[package]]
+name = "heck"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
+
[[package]]
name = "indexmap"
-version = "2.7.0"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
+checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661"
dependencies = [
"equivalent",
"hashbrown",
@@ -275,18 +282,18 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.169"
+version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libloading"
-version = "0.8.6"
+version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
+checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
- "windows-targets",
+ "windows-targets 0.53.3",
]
[[package]]
@@ -297,30 +304,30 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "log"
-version = "0.4.22"
+version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "mach2"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
+checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
-version = "2.7.4"
+version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "object"
-version = "0.36.7"
+version = "0.37.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
dependencies = [
"crc32fast",
"hashbrown",
@@ -330,27 +337,27 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.92"
+version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.38"
+version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regalloc2"
-version = "0.12.2"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5216b1837de2149f8bc8e6d5f88a9326b63b8c836ed58ce4a0a29ec736a59734"
+checksum = "efd8138ce7c3d7c13be4f61893154b5d711bd798d2d7be3ecb8dcc7e7a06ca98"
dependencies = [
"allocator-api2",
"bumpalo",
@@ -374,9 +381,9 @@ dependencies = [
[[package]]
name = "rustc-hash"
-version = "2.1.0"
+version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
+checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustc_codegen_cranelift"
@@ -398,18 +405,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.217"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.217"
+version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
@@ -418,9 +425,9 @@ dependencies = [
[[package]]
name = "smallvec"
-version = "1.13.2"
+version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "stable_deref_trait"
@@ -430,9 +437,9 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "syn"
-version = "2.0.95"
+version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
"proc-macro2",
"quote",
@@ -441,53 +448,59 @@ dependencies = [
[[package]]
name = "target-lexicon"
-version = "0.13.1"
+version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc12939a1c9b9d391e0b7135f72fd30508b73450753e28341fed159317582a77"
+checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a"
[[package]]
name = "unicode-ident"
-version = "1.0.14"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
-name = "wasmtime-jit-icache-coherence"
-version = "34.0.0"
+name = "wasmtime-internal-jit-icache-coherence"
+version = "38.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2eedc0324e37cf39b049f4dca0c30997eaab49f09006d5f4c1994e64e7b7dba8"
+checksum = "8d0a76f1a6e887cc1b551b02dfd6e2ce5f6738e8cacd9ad7284f6ac1aac4698f"
dependencies = [
"anyhow",
"cfg-if",
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
]
[[package]]
-name = "wasmtime-math"
-version = "34.0.0"
+name = "wasmtime-internal-math"
+version = "38.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd35fae4cf51d2b4a9bd2ef04b0eb309fa1849cab6a6ab5ac27cbd054ea284d"
+checksum = "b900df4252ad86547e7f2b2c00201b006db4e864893bedfb3aca32b23d81868a"
dependencies = [
"libm",
]
+[[package]]
+name = "windows-link"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
+
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
]
[[package]]
name = "windows-sys"
-version = "0.59.0"
+version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
- "windows-targets",
+ "windows-targets 0.53.3",
]
[[package]]
@@ -496,14 +509,31 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_gnullvm",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
+dependencies = [
+ "windows-link",
+ "windows_aarch64_gnullvm 0.53.0",
+ "windows_aarch64_msvc 0.53.0",
+ "windows_i686_gnu 0.53.0",
+ "windows_i686_gnullvm 0.53.0",
+ "windows_i686_msvc 0.53.0",
+ "windows_x86_64_gnu 0.53.0",
+ "windows_x86_64_gnullvm 0.53.0",
+ "windows_x86_64_msvc 0.53.0",
]
[[package]]
@@ -512,44 +542,92 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
+
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
+
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
diff --git a/Cargo.toml b/Cargo.toml
index 9066e4dbbb528..f2001123e579d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,22 +1,22 @@
[package]
name = "rustc_codegen_cranelift"
version = "0.1.0"
-edition = "2021"
+edition = "2024"
[lib]
crate-type = ["dylib"]
[dependencies]
# These have to be in sync with each other
-cranelift-codegen = { version = "0.121.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
-cranelift-frontend = { version = "0.121.0" }
-cranelift-module = { version = "0.121.0" }
-cranelift-native = { version = "0.121.0" }
-cranelift-jit = { version = "0.121.0", optional = true }
-cranelift-object = { version = "0.121.0" }
+cranelift-codegen = { version = "0.125.0", default-features = false, features = ["std", "timing", "unwind", "all-native-arch"] }
+cranelift-frontend = { version = "0.125.0" }
+cranelift-module = { version = "0.125.0" }
+cranelift-native = { version = "0.125.0" }
+cranelift-jit = { version = "0.125.0", optional = true }
+cranelift-object = { version = "0.125.0" }
target-lexicon = "0.13"
-gimli = { version = "0.31", default-features = false, features = ["write"] }
-object = { version = "0.36", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
+gimli = { version = "0.32", default-features = false, features = ["write"] }
+object = { version = "0.37.3", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
indexmap = "2.0.0"
libloading = { version = "0.8.0", optional = true }
@@ -24,12 +24,12 @@ smallvec = "1.8.1"
[patch.crates-io]
# Uncomment to use an unreleased version of cranelift
-#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" }
-#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" }
-#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" }
-#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" }
-#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" }
-#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-34.0.0", version = "0.121.0" }
+#cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
+#cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
+#cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
+#cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
+#cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
+#cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git", branch = "release-38.0.0" }
# Uncomment to use local checkout of cranelift
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
@@ -46,6 +46,7 @@ smallvec = "1.8.1"
unstable-features = ["jit", "inline_asm_sym"]
jit = ["cranelift-jit", "libloading"]
inline_asm_sym = []
+unwinding = [] # Not yet included in unstable-features for performance reasons
[package.metadata.rust-analyzer]
rustc_private = true
diff --git a/Readme.md b/Readme.md
index 4d1e4d843ffeb..c5436cf67c80a 100644
--- a/Readme.md
+++ b/Readme.md
@@ -11,7 +11,7 @@ The Cranelift codegen backend is distributed in nightly builds on Linux, macOS a
install it using Rustup, you can do that by running:
```bash
-$ rustup component add rustc-codegen-cranelift-preview --toolchain nightly
+rustup component add rustc-codegen-cranelift-preview --toolchain nightly
```
Once it is installed, you can enable it with one of the following approaches:
@@ -47,16 +47,16 @@ If you want to use `cargo clif build` instead of having to specify the full path
If you want to build the backend manually, you can download it from GitHub and build it yourself:
```bash
-$ git clone https://github.com/rust-lang/rustc_codegen_cranelift
-$ cd rustc_codegen_cranelift
-$ ./y.sh build
+git clone https://github.com/rust-lang/rustc_codegen_cranelift
+cd rustc_codegen_cranelift
+./y.sh build
```
To run the test suite replace the last command with:
```bash
-$ ./y.sh prepare # only needs to be run the first time
-$ ./test.sh
+./y.sh prepare # only needs to be run the first time
+./test.sh
```
For more docs on how to build and test see [build_system/usage.txt](build_system/usage.txt) or the help message of `./y.sh`.
@@ -66,7 +66,7 @@ For more docs on how to build and test see [build_system/usage.txt](build_system
|OS \ architecture|x86\_64|AArch64|Riscv64|s390x (System-Z)|
|---|---|---|---|---|
|Linux|✅|✅|✅[^no-rustup]|✅[^no-rustup]|
-|FreeBSD|✅[^no-rustup]|❓|❓|❓|
+|FreeBSD|✅[^no-rustup][^tls]|❓|❓|❓|
|AIX|❌[^xcoff]|N/A|N/A|❌[^xcoff]|
|Other unixes|❓|❓|❓|❓|
|macOS|✅|✅|N/A|N/A|
@@ -80,6 +80,7 @@ Not all targets are available as rustup component for nightly. See notes in the
[^xcoff]: XCOFF object file format is not supported.
[^no-rustup]: Not available as [rustup component for nightly](https://rust-lang.github.io/rustup-components-history/). You can build it yourself.
+[^tls]: FreeBSD requires setting `LD_STATIC_TLS_EXTRA=4096` to build cg_clif. In addition you need at least FreeBSD 14.
## Usage
@@ -90,7 +91,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/dist/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.
@@ -104,7 +105,7 @@ See [rustc_testing.md](docs/rustc_testing.md).
## Not yet supported
* SIMD ([tracked here](https://github.com/rust-lang/rustc_codegen_cranelift/issues/171), `std::simd` fully works, `std::arch` is partially supported)
-* Unwinding on panics ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1677), `-Cpanic=abort` is enabled by default)
+* Unwinding on panics ([experimental and not supported on Windows and macOS](https://github.com/rust-lang/rustc_codegen_cranelift/issues/1567), `-Cpanic=abort` is enabled by default)
## License
diff --git a/build_system/abi_cafe.rs b/build_system/abi_cafe.rs
index 43025137bc6bb..5a393a217c278 100644
--- a/build_system/abi_cafe.rs
+++ b/build_system/abi_cafe.rs
@@ -19,6 +19,7 @@ pub(crate) fn run(
cg_clif_dylib: &CodegenBackend,
rustup_toolchain_name: Option<&str>,
bootstrap_host_compiler: &Compiler,
+ panic_unwind_support: bool,
) {
std::fs::create_dir_all(&dirs.download_dir).unwrap();
ABI_CAFE_REPO.fetch(dirs);
@@ -32,6 +33,7 @@ pub(crate) fn run(
bootstrap_host_compiler,
rustup_toolchain_name,
bootstrap_host_compiler.triple.clone(),
+ panic_unwind_support,
);
eprintln!("Running abi-cafe");
diff --git a/build_system/bench.rs b/build_system/bench.rs
index 8359b7b527903..192cb499536f1 100644
--- a/build_system/bench.rs
+++ b/build_system/bench.rs
@@ -144,7 +144,7 @@ fn hyperfine_command(
}
for &(name, cmd) in cmds {
- if name != "" {
+ if !name.is_empty() {
bench.arg("-n").arg(name);
}
bench.arg(cmd);
diff --git a/build_system/build_backend.rs b/build_system/build_backend.rs
index bf7cf1c0a346f..b9fa0ff2d94c3 100644
--- a/build_system/build_backend.rs
+++ b/build_system/build_backend.rs
@@ -12,10 +12,11 @@ pub(crate) fn build_backend(
dirs: &Dirs,
bootstrap_host_compiler: &Compiler,
use_unstable_features: bool,
+ panic_unwind_support: bool,
) -> PathBuf {
let _group = LogGroup::guard("Build backend");
- let mut cmd = CG_CLIF.build(&bootstrap_host_compiler, dirs);
+ let mut cmd = CG_CLIF.build(bootstrap_host_compiler, dirs);
let mut rustflags = rustflags_from_env("RUSTFLAGS");
rustflags.push("-Zallow-features=rustc_private,f16,f128".to_owned());
@@ -31,6 +32,10 @@ pub(crate) fn build_backend(
cmd.arg("--features").arg("unstable-features");
}
+ if panic_unwind_support {
+ cmd.arg("--features").arg("unwinding");
+ }
+
cmd.arg("--release");
eprintln!("[BUILD] rustc_codegen_cranelift");
diff --git a/build_system/build_sysroot.rs b/build_system/build_sysroot.rs
index 00955998e703d..72140c651a9a4 100644
--- a/build_system/build_sysroot.rs
+++ b/build_system/build_sysroot.rs
@@ -17,6 +17,7 @@ pub(crate) fn build_sysroot(
bootstrap_host_compiler: &Compiler,
rustup_toolchain_name: Option<&str>,
target_triple: String,
+ panic_unwind_support: bool,
) -> Compiler {
let _guard = LogGroup::guard("Build sysroot");
@@ -48,10 +49,13 @@ pub(crate) fn build_sysroot(
let mut build_cargo_wrapper_cmd = Command::new(&bootstrap_host_compiler.rustc);
let wrapper_path = dist_dir.join(&wrapper_name);
build_cargo_wrapper_cmd
- .arg(dirs.source_dir.join("scripts").join(&format!("{wrapper}.rs")))
+ .arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs")))
.arg("-o")
.arg(&wrapper_path)
.arg("-Cstrip=debuginfo");
+ if panic_unwind_support {
+ build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind");
+ }
if let Some(rustup_toolchain_name) = &rustup_toolchain_name {
build_cargo_wrapper_cmd
.env("TOOLCHAIN_NAME", rustup_toolchain_name)
@@ -77,6 +81,7 @@ pub(crate) fn build_sysroot(
bootstrap_host_compiler.clone(),
&cg_clif_dylib_path,
sysroot_kind,
+ panic_unwind_support,
);
host.install_into_sysroot(dist_dir);
@@ -91,6 +96,7 @@ pub(crate) fn build_sysroot(
},
&cg_clif_dylib_path,
sysroot_kind,
+ panic_unwind_support,
)
.install_into_sysroot(dist_dir);
}
@@ -134,19 +140,20 @@ impl SysrootTarget {
static STDLIB_SRC: RelPath = RelPath::build("stdlib");
static STANDARD_LIBRARY: CargoProject =
CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target");
-static RTSTARTUP_SYSROOT: RelPath = RelPath::build("rtstartup");
fn build_sysroot_for_triple(
dirs: &Dirs,
compiler: Compiler,
cg_clif_dylib_path: &CodegenBackend,
sysroot_kind: SysrootKind,
+ panic_unwind_support: bool,
) -> SysrootTarget {
match sysroot_kind {
- SysrootKind::None => build_rtstartup(dirs, &compiler)
- .unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }),
+ SysrootKind::None => SysrootTarget { triple: compiler.triple, libs: vec![] },
SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler),
- SysrootKind::Clif => build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path),
+ SysrootKind::Clif => {
+ build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path, panic_unwind_support)
+ }
}
}
@@ -188,25 +195,28 @@ fn build_clif_sysroot_for_triple(
dirs: &Dirs,
mut compiler: Compiler,
cg_clif_dylib_path: &CodegenBackend,
+ panic_unwind_support: bool,
) -> SysrootTarget {
let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] };
- if let Some(rtstartup_target_libs) = build_rtstartup(dirs, &compiler) {
- rtstartup_target_libs.install_into_sysroot(&RTSTARTUP_SYSROOT.to_path(dirs));
-
- target_libs.libs.extend(rtstartup_target_libs.libs);
- }
-
let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join("release");
if !config::get_bool("keep_sysroot") {
+ let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust");
+ assert!(sysroot_src_orig.exists());
+
+ apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs));
+
// Cleanup the deps dir, but keep build scripts and the incremental cache for faster
// recompilation as they are not affected by changes in cg_clif.
ensure_empty_dir(&build_dir.join("deps"));
}
// Build sysroot
- let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned(), "-Cpanic=abort".to_owned()];
+ let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned()];
+ if !panic_unwind_support {
+ rustflags.push("-Cpanic=abort".to_owned());
+ }
match cg_clif_dylib_path {
CodegenBackend::Local(path) => {
rustflags.push(format!("-Zcodegen-backend={}", path.to_str().unwrap()));
@@ -215,9 +225,7 @@ fn build_clif_sysroot_for_triple(
rustflags.push(format!("-Zcodegen-backend={name}"));
}
};
- // Necessary for MinGW to find rsbegin.o and rsend.o
- rustflags.push("--sysroot".to_owned());
- rustflags.push(RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap().to_owned());
+ rustflags.push("--sysroot=/dev/null".to_owned());
// Incremental compilation by default disables mir inlining. This leads to both a decent
// compile perf and a significant runtime perf regression. As such forcefully enable mir
@@ -258,38 +266,3 @@ fn build_clif_sysroot_for_triple(
target_libs
}
-
-fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option {
- if !config::get_bool("keep_sysroot") {
- let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust");
- assert!(sysroot_src_orig.exists());
-
- apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs));
- }
-
- if !compiler.triple.ends_with("windows-gnu") {
- return None;
- }
-
- let rtstartup_sysroot = RTSTARTUP_SYSROOT.to_path(dirs);
- ensure_empty_dir(&rtstartup_sysroot);
-
- let rtstartup_src = STDLIB_SRC.to_path(dirs).join("library").join("rtstartup");
- let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] };
-
- for file in ["rsbegin", "rsend"] {
- let obj = rtstartup_sysroot.join(format!("{file}.o"));
- let mut build_rtstartup_cmd = Command::new(&compiler.rustc);
- build_rtstartup_cmd
- .arg("--target")
- .arg(&compiler.triple)
- .arg("--emit=obj")
- .arg("-o")
- .arg(&obj)
- .arg(rtstartup_src.join(format!("{file}.rs")));
- spawn_and_wait(build_rtstartup_cmd);
- target_libs.libs.push(obj.clone());
- }
-
- Some(target_libs)
-}
diff --git a/build_system/main.rs b/build_system/main.rs
index 3ff9751a3ef2d..fc00931283002 100644
--- a/build_system/main.rs
+++ b/build_system/main.rs
@@ -83,6 +83,7 @@ fn main() {
let mut download_dir = None;
let mut sysroot_kind = SysrootKind::Clif;
let mut use_unstable_features = true;
+ let mut panic_unwind_support = false;
let mut frozen = false;
let mut skip_tests = vec![];
let mut use_backend = None;
@@ -108,6 +109,7 @@ fn main() {
}
}
"--no-unstable-features" => use_unstable_features = false,
+ "--panic-unwind-support" => panic_unwind_support = true,
"--frozen" => frozen = true,
"--skip-test" => {
// FIXME check that all passed in tests actually exist
@@ -201,6 +203,7 @@ fn main() {
&dirs,
&bootstrap_host_compiler,
use_unstable_features,
+ panic_unwind_support,
))
};
match command {
@@ -212,6 +215,7 @@ fn main() {
&dirs,
sysroot_kind,
use_unstable_features,
+ panic_unwind_support,
&skip_tests.iter().map(|test| &**test).collect::>(),
&cg_clif_dylib,
&bootstrap_host_compiler,
@@ -230,6 +234,7 @@ fn main() {
&cg_clif_dylib,
rustup_toolchain_name.as_deref(),
&bootstrap_host_compiler,
+ panic_unwind_support,
);
}
Command::Build => {
@@ -240,6 +245,7 @@ fn main() {
&bootstrap_host_compiler,
rustup_toolchain_name.as_deref(),
target_triple,
+ panic_unwind_support,
);
}
Command::Bench => {
@@ -250,6 +256,7 @@ fn main() {
&bootstrap_host_compiler,
rustup_toolchain_name.as_deref(),
target_triple,
+ panic_unwind_support,
);
bench::benchmark(&dirs, &compiler);
}
diff --git a/build_system/rustc_info.rs b/build_system/rustc_info.rs
index 5b71504e90a4f..2fa827498de93 100644
--- a/build_system/rustc_info.rs
+++ b/build_system/rustc_info.rs
@@ -2,25 +2,19 @@ use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
pub(crate) fn get_host_triple(rustc: &Path) -> String {
- let version_info =
- Command::new(rustc).stderr(Stdio::inherit()).args(&["-vV"]).output().unwrap().stdout;
- String::from_utf8(version_info)
- .unwrap()
- .lines()
- .to_owned()
- .find(|line| line.starts_with("host"))
- .unwrap()
- .split(":")
- .nth(1)
+ let version_info = Command::new(rustc)
+ .stderr(Stdio::inherit())
+ .args(["--print", "host-tuple"])
+ .output()
.unwrap()
- .trim()
- .to_owned()
+ .stdout;
+ String::from_utf8(version_info).unwrap().trim().to_owned()
}
pub(crate) fn get_toolchain_name() -> String {
let active_toolchain = Command::new("rustup")
.stderr(Stdio::inherit())
- .args(&["show", "active-toolchain"])
+ .args(["show", "active-toolchain"])
.output()
.unwrap()
.stdout;
@@ -33,7 +27,7 @@ pub(crate) fn get_cargo_path() -> PathBuf {
}
let cargo_path = Command::new("rustup")
.stderr(Stdio::inherit())
- .args(&["which", "cargo"])
+ .args(["which", "cargo"])
.output()
.unwrap()
.stdout;
@@ -46,7 +40,7 @@ pub(crate) fn get_rustc_path() -> PathBuf {
}
let rustc_path = Command::new("rustup")
.stderr(Stdio::inherit())
- .args(&["which", "rustc"])
+ .args(["which", "rustc"])
.output()
.unwrap()
.stdout;
@@ -59,7 +53,7 @@ pub(crate) fn get_rustdoc_path() -> PathBuf {
}
let rustc_path = Command::new("rustup")
.stderr(Stdio::inherit())
- .args(&["which", "rustdoc"])
+ .args(["which", "rustdoc"])
.output()
.unwrap()
.stdout;
@@ -69,7 +63,7 @@ pub(crate) fn get_rustdoc_path() -> PathBuf {
pub(crate) fn get_default_sysroot(rustc: &Path) -> PathBuf {
let default_sysroot = Command::new(rustc)
.stderr(Stdio::inherit())
- .args(&["--print", "sysroot"])
+ .args(["--print", "sysroot"])
.output()
.unwrap()
.stdout;
@@ -80,7 +74,7 @@ pub(crate) fn get_default_sysroot(rustc: &Path) -> PathBuf {
pub(crate) fn get_file_name(rustc: &Path, crate_name: &str, crate_type: &str) -> String {
let file_name = Command::new(rustc)
.stderr(Stdio::inherit())
- .args(&[
+ .args([
"--crate-name",
crate_name,
"--crate-type",
diff --git a/build_system/tests.rs b/build_system/tests.rs
index eec89c026b26a..dd8cf929bc2f0 100644
--- a/build_system/tests.rs
+++ b/build_system/tests.rs
@@ -89,15 +89,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
TestCase::build_bin_and_run("aot.issue-72793", "example/issue-72793.rs", &[]),
TestCase::build_bin("aot.issue-59326", "example/issue-59326.rs"),
TestCase::build_bin_and_run("aot.neon", "example/neon.rs", &[]),
- TestCase::custom("aot.gen_block_iterate", &|runner| {
- runner.run_rustc([
- "example/gen_block_iterate.rs",
- "--edition",
- "2024",
- "-Zunstable-options",
- ]);
- runner.run_out_command("gen_block_iterate", &[]);
- }),
+ TestCase::build_bin_and_run("aot.gen_block_iterate", "example/gen_block_iterate.rs", &[]),
TestCase::build_bin_and_run("aot.raw-dylib", "example/raw-dylib.rs", &[]),
TestCase::custom("test.sysroot", &|runner| {
apply_patches(
@@ -217,13 +209,15 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
PORTABLE_SIMD.clean(&runner.dirs);
- let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs);
- build_cmd.arg("--all-targets");
+ let build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs);
+ // FIXME uncomment once examples work: https://github.com/rust-lang/portable-simd/issues/470
+ //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");
+ // FIXME remove --tests once examples work: https://github.com/rust-lang/portable-simd/issues/470
+ test_cmd.arg("-q").arg("--tests");
spawn_and_wait(test_cmd);
}
}),
@@ -233,6 +227,7 @@ pub(crate) fn run_tests(
dirs: &Dirs,
sysroot_kind: SysrootKind,
use_unstable_features: bool,
+ panic_unwind_support: bool,
skip_tests: &[&str],
cg_clif_dylib: &CodegenBackend,
bootstrap_host_compiler: &Compiler,
@@ -251,12 +246,14 @@ pub(crate) fn run_tests(
bootstrap_host_compiler,
rustup_toolchain_name,
target_triple.clone(),
+ panic_unwind_support,
);
let runner = TestRunner::new(
dirs.clone(),
target_compiler,
use_unstable_features,
+ panic_unwind_support,
skip_tests,
bootstrap_host_compiler.triple == target_triple,
stdlib_source.clone(),
@@ -283,12 +280,14 @@ pub(crate) fn run_tests(
bootstrap_host_compiler,
rustup_toolchain_name,
target_triple.clone(),
+ panic_unwind_support,
);
let mut runner = TestRunner::new(
dirs.clone(),
target_compiler,
use_unstable_features,
+ panic_unwind_support,
skip_tests,
bootstrap_host_compiler.triple == target_triple,
stdlib_source,
@@ -314,6 +313,7 @@ pub(crate) fn run_tests(
struct TestRunner<'a> {
is_native: bool,
jit_supported: bool,
+ panic_unwind_support: bool,
skip_tests: &'a [&'a str],
dirs: Dirs,
target_compiler: Compiler,
@@ -325,6 +325,7 @@ impl<'a> TestRunner<'a> {
dirs: Dirs,
mut target_compiler: Compiler,
use_unstable_features: bool,
+ panic_unwind_support: bool,
skip_tests: &'a [&'a str],
is_native: bool,
stdlib_source: PathBuf,
@@ -335,7 +336,15 @@ impl<'a> TestRunner<'a> {
let jit_supported =
use_unstable_features && is_native && !target_compiler.triple.contains("windows");
- Self { is_native, jit_supported, skip_tests, dirs, target_compiler, stdlib_source }
+ Self {
+ is_native,
+ jit_supported,
+ panic_unwind_support,
+ skip_tests,
+ dirs,
+ target_compiler,
+ stdlib_source,
+ }
}
fn run_testsuite(&self, tests: &[TestCase]) {
@@ -346,7 +355,7 @@ impl<'a> TestRunner<'a> {
let _guard = if !config::get_bool(config)
|| (is_jit_test && !self.jit_supported)
- || self.skip_tests.contains(&config)
+ || self.skip_tests.contains(config)
{
eprintln!("[{tag}] {testname} (skipped)");
continue;
@@ -404,8 +413,11 @@ impl<'a> TestRunner<'a> {
cmd.arg("-Cdebuginfo=2");
cmd.arg("--target");
cmd.arg(&self.target_compiler.triple);
- cmd.arg("-Cpanic=abort");
+ if !self.panic_unwind_support {
+ cmd.arg("-Cpanic=abort");
+ }
cmd.arg("--check-cfg=cfg(jit)");
+ cmd.arg("--edition=2024");
cmd.args(args);
cmd
}
diff --git a/build_system/usage.txt b/build_system/usage.txt
index 5c333fe2db596..6c98087e52399 100644
--- a/build_system/usage.txt
+++ b/build_system/usage.txt
@@ -25,6 +25,10 @@ OPTIONS:
Some features are not yet ready for production usage. This option will disable these
features. This includes the JIT mode and inline assembly support.
+ --panic-unwind-support
+ Enable support for unwinding when -Cpanic=unwind is used. This currently regresses build
+ performance.
+
--frozen
Require Cargo.lock and cache are up to date
diff --git a/build_system/utils.rs b/build_system/utils.rs
index d9807155a3d5d..3266aa0ce8b64 100644
--- a/build_system/utils.rs
+++ b/build_system/utils.rs
@@ -162,7 +162,7 @@ impl CargoProject {
pub(crate) fn try_hard_link(src: impl AsRef, dst: impl AsRef) {
let src = src.as_ref();
let dst = dst.as_ref();
- if let Err(_) = fs::hard_link(src, dst) {
+ if fs::hard_link(src, dst).is_err() {
fs::copy(src, dst).unwrap(); // Fallback to copying if hardlinking failed
}
}
@@ -179,7 +179,7 @@ pub(crate) fn spawn_and_wait(mut cmd: Command) {
/// Create the specified directory if it doesn't exist yet and delete all contents.
pub(crate) fn ensure_empty_dir(path: &Path) {
fs::create_dir_all(path).unwrap();
- let read_dir = match fs::read_dir(&path) {
+ let read_dir = match fs::read_dir(path) {
Ok(read_dir) => read_dir,
Err(err) if err.kind() == io::ErrorKind::NotFound => {
return;
diff --git a/config.txt b/config.txt
index 6ae4767adfdf5..85748a4f8a789 100644
--- a/config.txt
+++ b/config.txt
@@ -20,7 +20,6 @@ aot.mini_core_hello_world
testsuite.base_sysroot
aot.arbitrary_self_types_pointers_and_wrappers
-aot.issue_91827_extern_types
jit.std_example
aot.std_example
aot.dst_field_align
diff --git a/example/example.rs b/example/example.rs
index 769d262b9ebb5..2e15f06f8fc7e 100644
--- a/example/example.rs
+++ b/example/example.rs
@@ -77,12 +77,16 @@ pub fn use_size_of() -> usize {
}
pub unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) {
- intrinsics::copy::(src, dst, 1);
+ unsafe {
+ intrinsics::copy::(src, dst, 1);
+ }
}
pub unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) {
- let copy2 = &intrinsics::copy::;
- copy2(src, dst, 1);
+ unsafe {
+ let copy2 = &intrinsics::copy::;
+ copy2(src, dst, 1);
+ }
}
pub const ABC: u8 = 6 * 7;
@@ -126,11 +130,11 @@ pub fn eq_char(a: char, b: char) -> bool {
}
pub unsafe fn transmute(c: char) -> u32 {
- intrinsics::transmute(c)
+ unsafe { intrinsics::transmute(c) }
}
pub unsafe fn deref_str_ptr(s: *const str) -> &'static str {
- &*s
+ unsafe { &*s }
}
pub fn use_array(arr: [u8; 3]) -> u8 {
@@ -146,7 +150,7 @@ pub fn array_as_slice(arr: &[u8; 3]) -> &[u8] {
}
pub unsafe fn use_ctlz_nonzero(a: u16) -> u32 {
- intrinsics::ctlz_nonzero(a)
+ unsafe { intrinsics::ctlz_nonzero(a) }
}
pub fn ptr_as_usize(ptr: *const u8) -> usize {
diff --git a/example/mini_core.rs b/example/mini_core.rs
index 304d0d648561e..b522ea1937166 100644
--- a/example/mini_core.rs
+++ b/example/mini_core.rs
@@ -546,7 +546,7 @@ fn panic_in_cleanup() -> ! {
#[cfg(all(unix, not(target_vendor = "apple")))]
#[link(name = "gcc_s")]
-extern "C" {
+unsafe extern "C" {
fn _Unwind_Resume(exc: *mut ()) -> !;
}
@@ -555,7 +555,9 @@ extern "C" {
pub unsafe fn drop_in_place(to_drop: *mut T) {
// Code here does not matter - this is replaced by the
// real drop glue by the compiler.
- drop_in_place(to_drop);
+ unsafe {
+ drop_in_place(to_drop);
+ }
}
#[lang = "unpin"]
@@ -622,7 +624,7 @@ impl Deref for Box {
#[lang = "exchange_malloc"]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
- libc::malloc(size)
+ unsafe { libc::malloc(size) }
}
#[lang = "drop"]
@@ -649,11 +651,11 @@ pub mod intrinsics {
#[rustc_intrinsic]
pub const fn size_of() -> usize;
#[rustc_intrinsic]
- pub unsafe fn size_of_val(val: *const T) -> usize;
+ pub unsafe fn size_of_val(val: *const T) -> usize;
#[rustc_intrinsic]
pub const fn align_of() -> usize;
#[rustc_intrinsic]
- pub unsafe fn align_of_val(val: *const T) -> usize;
+ pub unsafe fn align_of_val(val: *const T) -> usize;
#[rustc_intrinsic]
pub unsafe fn copy(src: *const T, dst: *mut T, count: usize);
#[rustc_intrinsic]
@@ -661,7 +663,7 @@ pub mod intrinsics {
#[rustc_intrinsic]
pub unsafe fn ctlz_nonzero(x: T) -> u32;
#[rustc_intrinsic]
- pub const fn needs_drop() -> bool;
+ pub const fn needs_drop() -> bool;
#[rustc_intrinsic]
pub fn bitreverse(x: T) -> T;
#[rustc_intrinsic]
@@ -678,13 +680,13 @@ pub mod libc {
// symbols to link against.
#[cfg_attr(unix, link(name = "c"))]
#[cfg_attr(target_env = "msvc", link(name = "legacy_stdio_definitions"))]
- extern "C" {
+ unsafe extern "C" {
pub fn printf(format: *const i8, ...) -> i32;
}
#[cfg_attr(unix, link(name = "c"))]
#[cfg_attr(target_env = "msvc", link(name = "msvcrt"))]
- extern "C" {
+ unsafe extern "C" {
pub fn puts(s: *const i8) -> i32;
pub fn malloc(size: usize) -> *mut u8;
pub fn free(ptr: *mut u8);
@@ -733,7 +735,7 @@ trait SizedTypeProperties: Sized {
}
impl SizedTypeProperties for T {}
-extern "C" {
+unsafe extern "C" {
type VaListImpl;
}
@@ -792,7 +794,7 @@ struct PanicLocation {
column: u32,
}
-#[no_mangle]
+#[unsafe(no_mangle)]
#[cfg(not(all(windows, target_env = "gnu")))]
pub fn get_tls() -> u8 {
#[thread_local]
diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs
index a9388814a7f59..10549cd2a41e2 100644
--- a/example/mini_core_hello_world.rs
+++ b/example/mini_core_hello_world.rs
@@ -124,9 +124,11 @@ static mut NUM: u8 = 6 * 7;
static NUM_REF: &'static u8 = unsafe { &*&raw const NUM };
unsafe fn zeroed() -> T {
- let mut uninit = MaybeUninit { uninit: () };
- intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1);
- uninit.value.value
+ unsafe {
+ let mut uninit = MaybeUninit { uninit: () };
+ intrinsics::write_bytes(&mut uninit.value.value as *mut T, 0, 1);
+ uninit.value.value
+ }
}
fn take_f32(_f: f32) {}
@@ -237,7 +239,7 @@ fn main() {
}
unsafe fn uninitialized() -> T {
- MaybeUninit { uninit: () }.value.value
+ unsafe { MaybeUninit { uninit: () }.value.value }
}
zeroed::<(u8, u8)>();
@@ -270,20 +272,20 @@ fn main() {
let x = &[0u32, 42u32] as &[u32];
match x {
[] => assert_eq!(0u32, 1),
- [_, ref y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize),
+ [_, y @ ..] => assert_eq!(&x[1] as *const u32 as usize, &y[0] as *const u32 as usize),
}
assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42);
#[cfg(not(any(jit, target_vendor = "apple", windows)))]
{
- extern "C" {
+ unsafe extern "C" {
#[linkage = "extern_weak"]
static ABC: *const u8;
}
{
- extern "C" {
+ unsafe extern "C" {
#[linkage = "extern_weak"]
static ABC: *const u8;
}
@@ -310,7 +312,7 @@ fn main() {
check_niche_behavior();
- extern "C" {
+ unsafe extern "C" {
type ExternType;
}
@@ -364,7 +366,7 @@ fn stack_val_align() {
}
#[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "macos")))]
-extern "C" {
+unsafe extern "C" {
fn global_asm_test();
}
@@ -412,7 +414,7 @@ struct pthread_attr_t {
#[link(name = "pthread")]
#[cfg(unix)]
-extern "C" {
+unsafe extern "C" {
fn pthread_attr_init(attr: *mut pthread_attr_t) -> c_int;
fn pthread_create(
@@ -433,7 +435,7 @@ type HANDLE = *mut c_void;
#[link(name = "msvcrt")]
#[cfg(windows)]
-extern "C" {
+unsafe extern "C" {
fn WaitForSingleObject(hHandle: LPVOID, dwMilliseconds: DWORD) -> DWORD;
fn CreateThread(
@@ -455,46 +457,51 @@ struct Thread {
impl Thread {
unsafe fn create(f: extern "C" fn(_: *mut c_void) -> *mut c_void) -> Self {
- #[cfg(unix)]
- {
- let mut attr: pthread_attr_t = zeroed();
- let mut thread: pthread_t = 0;
+ unsafe {
+ #[cfg(unix)]
+ {
+ let mut attr: pthread_attr_t = zeroed();
+ let mut thread: pthread_t = 0;
- if pthread_attr_init(&mut attr) != 0 {
- assert!(false);
- }
+ if pthread_attr_init(&mut attr) != 0 {
+ assert!(false);
+ }
+
+ if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 {
+ assert!(false);
+ }
- if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 {
- assert!(false);
+ Thread { handle: thread }
}
- Thread { handle: thread }
- }
+ #[cfg(windows)]
+ {
+ let handle =
+ CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32);
- #[cfg(windows)]
- {
- let handle = CreateThread(0 as *mut c_void, 0, f, 0 as *mut c_void, 0, 0 as *mut u32);
+ if (handle as u64) == 0 {
+ assert!(false);
+ }
- if (handle as u64) == 0 {
- assert!(false);
+ Thread { handle }
}
-
- Thread { handle }
}
}
unsafe fn join(self) {
- #[cfg(unix)]
- {
- let mut res = 0 as *mut c_void;
- pthread_join(self.handle, &mut res);
- }
+ unsafe {
+ #[cfg(unix)]
+ {
+ let mut res = 0 as *mut c_void;
+ pthread_join(self.handle, &mut res);
+ }
- #[cfg(windows)]
- {
- // The INFINITE macro is used to signal operations that do not timeout.
- let infinite = 0xffffffff;
- assert!(WaitForSingleObject(self.handle, infinite) == 0);
+ #[cfg(windows)]
+ {
+ // The INFINITE macro is used to signal operations that do not timeout.
+ let infinite = 0xffffffff;
+ assert!(WaitForSingleObject(self.handle, infinite) == 0);
+ }
}
}
}
diff --git a/example/neon.rs b/example/neon.rs
index 704f866e2c4f5..fb3e10a41c025 100644
--- a/example/neon.rs
+++ b/example/neon.rs
@@ -14,7 +14,7 @@ unsafe fn test_vpmin_s8() {
let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]);
let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
let e = i8x8::from([-2, -4, 5, 7, 0, 2, 4, 6]);
- let r: i8x8 = transmute(vpmin_s8(transmute(a), transmute(b)));
+ let r: i8x8 = unsafe { transmute(vpmin_s8(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -23,7 +23,7 @@ unsafe fn test_vpmin_s16() {
let a = i16x4::from([1, 2, 3, -4]);
let b = i16x4::from([0, 3, 2, 5]);
let e = i16x4::from([1, -4, 0, 2]);
- let r: i16x4 = transmute(vpmin_s16(transmute(a), transmute(b)));
+ let r: i16x4 = unsafe { transmute(vpmin_s16(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -32,7 +32,7 @@ unsafe fn test_vpmin_s32() {
let a = i32x2::from([1, -2]);
let b = i32x2::from([0, 3]);
let e = i32x2::from([-2, 0]);
- let r: i32x2 = transmute(vpmin_s32(transmute(a), transmute(b)));
+ let r: i32x2 = unsafe { transmute(vpmin_s32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -41,7 +41,7 @@ unsafe fn test_vpmin_u8() {
let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
let e = u8x8::from([1, 3, 5, 7, 0, 2, 4, 6]);
- let r: u8x8 = transmute(vpmin_u8(transmute(a), transmute(b)));
+ let r: u8x8 = unsafe { transmute(vpmin_u8(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -50,7 +50,7 @@ unsafe fn test_vpmin_u16() {
let a = u16x4::from([1, 2, 3, 4]);
let b = u16x4::from([0, 3, 2, 5]);
let e = u16x4::from([1, 3, 0, 2]);
- let r: u16x4 = transmute(vpmin_u16(transmute(a), transmute(b)));
+ let r: u16x4 = unsafe { transmute(vpmin_u16(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -59,7 +59,7 @@ unsafe fn test_vpmin_u32() {
let a = u32x2::from([1, 2]);
let b = u32x2::from([0, 3]);
let e = u32x2::from([1, 0]);
- let r: u32x2 = transmute(vpmin_u32(transmute(a), transmute(b)));
+ let r: u32x2 = unsafe { transmute(vpmin_u32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -68,7 +68,7 @@ unsafe fn test_vpmin_f32() {
let a = f32x2::from([1., -2.]);
let b = f32x2::from([0., 3.]);
let e = f32x2::from([-2., 0.]);
- let r: f32x2 = transmute(vpmin_f32(transmute(a), transmute(b)));
+ let r: f32x2 = unsafe { transmute(vpmin_f32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -77,7 +77,7 @@ unsafe fn test_vpmax_s8() {
let a = i8x8::from([1, -2, 3, -4, 5, 6, 7, 8]);
let b = i8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
let e = i8x8::from([1, 3, 6, 8, 3, 5, 7, 9]);
- let r: i8x8 = transmute(vpmax_s8(transmute(a), transmute(b)));
+ let r: i8x8 = unsafe { transmute(vpmax_s8(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -86,7 +86,7 @@ unsafe fn test_vpmax_s16() {
let a = i16x4::from([1, 2, 3, -4]);
let b = i16x4::from([0, 3, 2, 5]);
let e = i16x4::from([2, 3, 3, 5]);
- let r: i16x4 = transmute(vpmax_s16(transmute(a), transmute(b)));
+ let r: i16x4 = unsafe { transmute(vpmax_s16(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -95,7 +95,7 @@ unsafe fn test_vpmax_s32() {
let a = i32x2::from([1, -2]);
let b = i32x2::from([0, 3]);
let e = i32x2::from([1, 3]);
- let r: i32x2 = transmute(vpmax_s32(transmute(a), transmute(b)));
+ let r: i32x2 = unsafe { transmute(vpmax_s32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -104,7 +104,7 @@ unsafe fn test_vpmax_u8() {
let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
let b = u8x8::from([0, 3, 2, 5, 4, 7, 6, 9]);
let e = u8x8::from([2, 4, 6, 8, 3, 5, 7, 9]);
- let r: u8x8 = transmute(vpmax_u8(transmute(a), transmute(b)));
+ let r: u8x8 = unsafe { transmute(vpmax_u8(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -113,7 +113,7 @@ unsafe fn test_vpmax_u16() {
let a = u16x4::from([1, 2, 3, 4]);
let b = u16x4::from([0, 3, 2, 5]);
let e = u16x4::from([2, 4, 3, 5]);
- let r: u16x4 = transmute(vpmax_u16(transmute(a), transmute(b)));
+ let r: u16x4 = unsafe { transmute(vpmax_u16(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -122,7 +122,7 @@ unsafe fn test_vpmax_u32() {
let a = u32x2::from([1, 2]);
let b = u32x2::from([0, 3]);
let e = u32x2::from([2, 3]);
- let r: u32x2 = transmute(vpmax_u32(transmute(a), transmute(b)));
+ let r: u32x2 = unsafe { transmute(vpmax_u32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -131,7 +131,7 @@ unsafe fn test_vpmax_f32() {
let a = f32x2::from([1., -2.]);
let b = f32x2::from([0., 3.]);
let e = f32x2::from([1., 3.]);
- let r: f32x2 = transmute(vpmax_f32(transmute(a), transmute(b)));
+ let r: f32x2 = unsafe { transmute(vpmax_f32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -139,7 +139,7 @@ unsafe fn test_vpmax_f32() {
unsafe fn test_vpadd_s16() {
let a = i16x4::from([1, 2, 3, 4]);
let b = i16x4::from([0, -1, -2, -3]);
- let r: i16x4 = transmute(vpadd_s16(transmute(a), transmute(b)));
+ let r: i16x4 = unsafe { transmute(vpadd_s16(transmute(a), transmute(b))) };
let e = i16x4::from([3, 7, -1, -5]);
assert_eq!(r, e);
}
@@ -147,7 +147,7 @@ unsafe fn test_vpadd_s16() {
unsafe fn test_vpadd_s32() {
let a = i32x2::from([1, 2]);
let b = i32x2::from([0, -1]);
- let r: i32x2 = transmute(vpadd_s32(transmute(a), transmute(b)));
+ let r: i32x2 = unsafe { transmute(vpadd_s32(transmute(a), transmute(b))) };
let e = i32x2::from([3, -1]);
assert_eq!(r, e);
}
@@ -155,7 +155,7 @@ unsafe fn test_vpadd_s32() {
unsafe fn test_vpadd_s8() {
let a = i8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
let b = i8x8::from([0, -1, -2, -3, -4, -5, -6, -7]);
- let r: i8x8 = transmute(vpadd_s8(transmute(a), transmute(b)));
+ let r: i8x8 = unsafe { transmute(vpadd_s8(transmute(a), transmute(b))) };
let e = i8x8::from([3, 7, 11, 15, -1, -5, -9, -13]);
assert_eq!(r, e);
}
@@ -163,7 +163,7 @@ unsafe fn test_vpadd_s8() {
unsafe fn test_vpadd_u16() {
let a = u16x4::from([1, 2, 3, 4]);
let b = u16x4::from([30, 31, 32, 33]);
- let r: u16x4 = transmute(vpadd_u16(transmute(a), transmute(b)));
+ let r: u16x4 = unsafe { transmute(vpadd_u16(transmute(a), transmute(b))) };
let e = u16x4::from([3, 7, 61, 65]);
assert_eq!(r, e);
}
@@ -171,7 +171,7 @@ unsafe fn test_vpadd_u16() {
unsafe fn test_vpadd_u32() {
let a = u32x2::from([1, 2]);
let b = u32x2::from([30, 31]);
- let r: u32x2 = transmute(vpadd_u32(transmute(a), transmute(b)));
+ let r: u32x2 = unsafe { transmute(vpadd_u32(transmute(a), transmute(b))) };
let e = u32x2::from([3, 61]);
assert_eq!(r, e);
}
@@ -179,7 +179,7 @@ unsafe fn test_vpadd_u32() {
unsafe fn test_vpadd_u8() {
let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 8]);
let b = u8x8::from([30, 31, 32, 33, 34, 35, 36, 37]);
- let r: u8x8 = transmute(vpadd_u8(transmute(a), transmute(b)));
+ let r: u8x8 = unsafe { transmute(vpadd_u8(transmute(a), transmute(b))) };
let e = u8x8::from([3, 7, 11, 15, 61, 65, 69, 73]);
assert_eq!(r, e);
}
@@ -188,7 +188,7 @@ unsafe fn test_vpadd_u8() {
unsafe fn test_vqsub_u8() {
let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]);
let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]);
- let r: u8x8 = transmute(vqsub_u8(transmute(a), transmute(b)));
+ let r: u8x8 = unsafe { transmute(vqsub_u8(transmute(a), transmute(b))) };
let e = u8x8::from([0, 1, 2, 3, 0, 0, 0, 218]);
assert_eq!(r, e);
}
@@ -197,7 +197,7 @@ unsafe fn test_vqsub_u8() {
unsafe fn test_vqadd_u8() {
let a = u8x8::from([1, 2, 3, 4, 5, 6, 7, 0xff]);
let b = u8x8::from([30, 1, 1, 1, 34, 0xff, 36, 37]);
- let r: u8x8 = transmute(vqadd_u8(transmute(a), transmute(b)));
+ let r: u8x8 = unsafe { transmute(vqadd_u8(transmute(a), transmute(b))) };
let e = u8x8::from([31, 3, 4, 5, 39, 0xff, 43, 0xff]);
assert_eq!(r, e);
}
@@ -208,7 +208,7 @@ unsafe fn test_vmaxq_f32() {
let a = f32x4::from([0., -1., 2., -3.]);
let b = f32x4::from([-4., 5., -6., 7.]);
let e = f32x4::from([0., 5., 2., 7.]);
- let r: f32x4 = transmute(vmaxq_f32(transmute(a), transmute(b)));
+ let r: f32x4 = unsafe { transmute(vmaxq_f32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -218,7 +218,7 @@ unsafe fn test_vminq_f32() {
let a = f32x4::from([0., -1., 2., -3.]);
let b = f32x4::from([-4., 5., -6., 7.]);
let e = f32x4::from([-4., -1., -6., -3.]);
- let r: f32x4 = transmute(vminq_f32(transmute(a), transmute(b)));
+ let r: f32x4 = unsafe { transmute(vminq_f32(transmute(a), transmute(b))) };
assert_eq!(r, e);
}
@@ -227,7 +227,7 @@ unsafe fn test_vaddvq_f32() {
// AArch64 llvm intrinsic: llvm.aarch64.neon.faddv.f32.v4f32
let a = f32x4::from([0., 1., 2., 3.]);
let e = 6f32;
- let r = vaddvq_f32(transmute(a));
+ let r = unsafe { vaddvq_f32(transmute(a)) };
assert_eq!(r, e);
}
@@ -236,7 +236,7 @@ unsafe fn test_vrndnq_f32() {
// llvm intrinsic: llvm.roundeven.v4f32
let a = f32x4::from([0.1, -1.9, 4.5, 5.5]);
let e = f32x4::from([0., -2., 4., 6.]);
- let r: f32x4 = transmute(vrndnq_f32(transmute(a)));
+ let r: f32x4 = unsafe { transmute(vrndnq_f32(transmute(a))) };
assert_eq!(r, e);
}
diff --git a/example/raw-dylib.rs b/example/raw-dylib.rs
index 4711884f76af6..5f5bde7d4dc5e 100644
--- a/example/raw-dylib.rs
+++ b/example/raw-dylib.rs
@@ -5,7 +5,7 @@ fn main() {
#[cfg(windows)]
{
#[link(name = "kernel32", kind = "raw-dylib")]
- extern "C" {
+ unsafe extern "C" {
fn GetModuleFileNameA(
module: *mut std::ffi::c_void,
filename: *mut u8,
diff --git a/example/std_example.rs b/example/std_example.rs
index 5d83066cffb88..c569ef0ef8297 100644
--- a/example/std_example.rs
+++ b/example/std_example.rs
@@ -230,51 +230,53 @@ unsafe fn test_crc32() {
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse2")]
unsafe fn test_simd() {
- assert!(is_x86_feature_detected!("sse2"));
-
- let x = _mm_setzero_si128();
- let y = _mm_set1_epi16(7);
- let or = _mm_or_si128(x, y);
- 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]);
-
- test_mm_slli_si128();
- test_mm_movemask_epi8();
- test_mm256_movemask_epi8();
- test_mm_add_epi8();
- test_mm_add_pd();
- test_mm_cvtepi8_epi16();
- #[cfg(not(jit))]
- test_mm_cvtps_epi32();
- test_mm_cvttps_epi32();
- test_mm_cvtsi128_si64();
-
- test_mm_extract_epi8();
- test_mm_insert_epi16();
- test_mm_shuffle_epi8();
-
- #[cfg(not(jit))]
- test_mm_cmpestri();
-
- test_mm256_shuffle_epi8();
- test_mm256_permute2x128_si256();
- test_mm256_permutevar8x32_epi32();
-
- #[rustfmt::skip]
+ unsafe {
+ assert!(is_x86_feature_detected!("sse2"));
+
+ let x = _mm_setzero_si128();
+ let y = _mm_set1_epi16(7);
+ let or = _mm_or_si128(x, y);
+ 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]);
+
+ test_mm_slli_si128();
+ test_mm_movemask_epi8();
+ test_mm256_movemask_epi8();
+ test_mm_add_epi8();
+ test_mm_add_pd();
+ test_mm_cvtepi8_epi16();
+ #[cfg(not(jit))]
+ test_mm_cvtps_epi32();
+ test_mm_cvttps_epi32();
+ test_mm_cvtsi128_si64();
+
+ test_mm_extract_epi8();
+ test_mm_insert_epi16();
+ test_mm_shuffle_epi8();
+
+ #[cfg(not(jit))]
+ test_mm_cmpestri();
+
+ test_mm256_shuffle_epi8();
+ test_mm256_permute2x128_si256();
+ test_mm256_permutevar8x32_epi32();
+
+ #[rustfmt::skip]
let mask1 = _mm_movemask_epi8(dbg!(_mm_setr_epi8(255u8 as i8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)));
- assert_eq!(mask1, 1);
+ assert_eq!(mask1, 1);
- #[cfg(not(jit))]
- test_crc32();
+ #[cfg(not(jit))]
+ test_crc32();
+ }
}
#[cfg(target_arch = "x86_64")]
@@ -361,7 +363,7 @@ fn assert_eq_m128i(x: std::arch::x86_64::__m128i, y: std::arch::x86_64::__m128i)
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse2")]
-pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) {
+pub fn assert_eq_m128d(a: __m128d, b: __m128d) {
if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 {
panic!("{:?} != {:?}", a, b);
}
@@ -369,15 +371,19 @@ pub unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) {
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx")]
-pub unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) {
- assert_eq!(std::mem::transmute::<_, [u64; 4]>(a), std::mem::transmute::<_, [u64; 4]>(b))
+pub fn assert_eq_m256i(a: __m256i, b: __m256i) {
+ unsafe {
+ assert_eq!(std::mem::transmute::<_, [u64; 4]>(a), std::mem::transmute::<_, [u64; 4]>(b))
+ }
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse2")]
unsafe fn test_mm_cvtsi128_si64() {
- let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0]));
- assert_eq!(r, 5);
+ unsafe {
+ let r = _mm_cvtsi128_si64(std::mem::transmute::<[i64; 2], _>([5, 0]));
+ assert_eq!(r, 5);
+ }
}
#[cfg(target_arch = "x86_64")]
@@ -445,20 +451,24 @@ unsafe fn test_mm_shuffle_epi8() {
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse4.2")]
unsafe fn str_to_m128i(s: &[u8]) -> __m128i {
- assert!(s.len() <= 16);
- let slice = &mut [0u8; 16];
- std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len());
- _mm_loadu_si128(slice.as_ptr() as *const _)
+ unsafe {
+ assert!(s.len() <= 16);
+ let slice = &mut [0u8; 16];
+ std::ptr::copy_nonoverlapping(s.as_ptr(), slice.as_mut_ptr(), s.len());
+ _mm_loadu_si128(slice.as_ptr() as *const _)
+ }
}
#[cfg(not(jit))]
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "sse4.2")]
unsafe fn test_mm_cmpestri() {
- let a = str_to_m128i(b"bar - garbage");
- let b = str_to_m128i(b"foobar");
- let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6);
- assert_eq!(3, i);
+ unsafe {
+ let a = str_to_m128i(b"bar - garbage");
+ let b = str_to_m128i(b"foobar");
+ let i = _mm_cmpestri::<_SIDD_CMP_EQUAL_ORDERED>(a, 3, b, 6);
+ assert_eq!(3, i);
+ }
}
#[cfg(target_arch = "x86_64")]
@@ -513,35 +523,39 @@ unsafe fn test_mm256_permutevar8x32_epi32() {
#[target_feature(enable = "avx2")]
#[cfg(not(jit))]
unsafe fn test_mm_cvtps_epi32() {
- let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN];
+ unsafe {
+ let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN];
- let float_vec = _mm_loadu_ps(floats.as_ptr());
- let int_vec = _mm_cvtps_epi32(float_vec);
+ let float_vec = _mm_loadu_ps(floats.as_ptr());
+ let int_vec = _mm_cvtps_epi32(float_vec);
- let mut ints: [i32; 4] = [0; 4];
- _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec);
+ let mut ints: [i32; 4] = [0; 4];
+ _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec);
- // this is very different from `floats.map(|f| f as i32)`!
- let expected_ints: [i32; 4] = [2, -2, i32::MIN, i32::MIN];
+ // this is very different from `floats.map(|f| f as i32)`!
+ let expected_ints: [i32; 4] = [2, -2, i32::MIN, i32::MIN];
- assert_eq!(ints, expected_ints);
+ assert_eq!(ints, expected_ints);
+ }
}
#[cfg(target_arch = "x86_64")]
#[target_feature(enable = "avx2")]
unsafe fn test_mm_cvttps_epi32() {
- let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN];
+ unsafe {
+ let floats: [f32; 4] = [1.5, -2.5, i32::MAX as f32 + 1.0, f32::NAN];
- let float_vec = _mm_loadu_ps(floats.as_ptr());
- let int_vec = _mm_cvttps_epi32(float_vec);
+ let float_vec = _mm_loadu_ps(floats.as_ptr());
+ let int_vec = _mm_cvttps_epi32(float_vec);
- let mut ints: [i32; 4] = [0; 4];
- _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec);
+ let mut ints: [i32; 4] = [0; 4];
+ _mm_storeu_si128(ints.as_mut_ptr() as *mut __m128i, int_vec);
- // this is very different from `floats.map(|f| f as i32)`!
- let expected_ints: [i32; 4] = [1, -2, i32::MIN, i32::MIN];
+ // this is very different from `floats.map(|f| f as i32)`!
+ let expected_ints: [i32; 4] = [1, -2, i32::MIN, i32::MIN];
- assert_eq!(ints, expected_ints);
+ assert_eq!(ints, expected_ints);
+ }
}
fn test_checked_mul() {
diff --git a/patches/0028-sysroot_tests-Disable-long-running-tests.patch b/patches/0028-sysroot_tests-Disable-long-running-tests.patch
index 357b8d306cf6a..853acab2773b5 100644
--- a/patches/0028-sysroot_tests-Disable-long-running-tests.patch
+++ b/patches/0028-sysroot_tests-Disable-long-running-tests.patch
@@ -11,38 +11,41 @@ diff --git a/coretests/tests/slice.rs b/coretests/tests/slice.rs
index 8402833..84592e0 100644
--- a/coretests/tests/slice.rs
+++ b/coretests/tests/slice.rs
-@@ -1809,6 +1809,7 @@ fn sort_unstable() {
- }
- }
+@@ -1619,7 +1619,7 @@ fn brute_force_rotate_test_1() {
-+/*
#[test]
#[cfg(not(target_arch = "wasm32"))]
- #[cfg_attr(miri, ignore)] // Miri is too slow
-@@ -1914,6 +1915,7 @@ fn select_nth_unstable() {
- v.select_nth_unstable(0);
- assert!(v == [0xDEADBEEF]);
- }
-+*/
+-#[cfg_attr(miri, ignore)] // Miri is too slow
++#[ignore] // Miri is too slow
+ fn select_nth_unstable() {
+ use core::cmp::Ordering::{Equal, Greater, Less};
- #[test]
- #[should_panic(expected = "index 0 greater than length of slice")]
-@@ -2462,6 +2462,7 @@ take_tests! {
- #[cfg(not(miri))] // unused in Miri
+@@ -2303,14 +2303,14 @@ split_off_tests! {
const EMPTY_MAX: &'static [()] = &[(); usize::MAX];
-+/*
// can't be a constant due to const mutability rules
- #[cfg(not(miri))] // unused in Miri
+-#[cfg(not(miri))] // unused in Miri
++#[cfg(any())] // unused in Miri
macro_rules! empty_max_mut {
-@@ -2485,6 +2486,7 @@ take_tests! {
- (split_off_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
- (split_off_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
+ () => {
+ &mut [(); usize::MAX] as _
+ };
}
-+*/
- #[test]
- fn test_slice_from_ptr_range() {
+-#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
++#[cfg(any())] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
+ split_off_tests! {
+ slice: &[(); usize::MAX], method: split_off,
+ (split_off_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]),
+@@ -2318,7 +2318,7 @@ split_off_tests! {
+ (split_off_in_bounds_max_range_from, (usize::MAX..), Some(&[] as _), EMPTY_MAX),
+ }
+
+-#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
++#[cfg(any())] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
+ split_off_tests! {
+ slice: &mut [(); usize::MAX], method: split_off_mut,
+ (split_off_mut_in_bounds_max_range_to, (..usize::MAX), Some(empty_max_mut!()), &mut [(); 0]),
diff --git a/alloctests/tests/sort/tests.rs b/alloctests/tests/sort/tests.rs
index d321f8d..8b2040a 100644
--- a/alloctests/tests/sort/tests.rs
diff --git a/rust-toolchain b/rust-toolchain
index 150bb562f74a7..17c2cc5ac6609 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,4 +1,4 @@
[toolchain]
-channel = "nightly-2025-06-24"
+channel = "nightly-2025-11-08"
components = ["rust-src", "rustc-dev", "llvm-tools"]
profile = "minimal"
diff --git a/scripts/cargo-clif.rs b/scripts/cargo-clif.rs
index e6c63bf5e6508..e391cc7f75a92 100644
--- a/scripts/cargo-clif.rs
+++ b/scripts/cargo-clif.rs
@@ -12,7 +12,11 @@ fn main() {
sysroot = sysroot.parent().unwrap();
}
- let mut rustflags = vec!["-Cpanic=abort".to_owned(), "-Zpanic-abort-tests".to_owned()];
+ let mut rustflags = vec![];
+ if !cfg!(support_panic_unwind) {
+ rustflags.push("-Cpanic=abort".to_owned());
+ rustflags.push("-Zpanic-abort-tests".to_owned());
+ }
if let Some(name) = option_env!("BUILTIN_BACKEND") {
rustflags.push(format!("-Zcodegen-backend={name}"));
} else {
diff --git a/scripts/rustc-clif.rs b/scripts/rustc-clif.rs
index 528031af82a84..15d929d0f5a51 100644
--- a/scripts/rustc-clif.rs
+++ b/scripts/rustc-clif.rs
@@ -17,8 +17,10 @@ fn main() {
let passed_args = std::env::args_os().skip(1).collect::>();
let mut args = vec![];
- args.push(OsString::from("-Cpanic=abort"));
- args.push(OsString::from("-Zpanic-abort-tests"));
+ if !cfg!(support_panic_unwind) {
+ args.push(OsString::from("-Cpanic=abort"));
+ args.push(OsString::from("-Zpanic-abort-tests"));
+ }
if let Some(name) = option_env!("BUILTIN_BACKEND") {
args.push(OsString::from(format!("-Zcodegen-backend={name}")))
} else {
diff --git a/scripts/rustdoc-clif.rs b/scripts/rustdoc-clif.rs
index 6ebe060d8bbd1..dc5bef18cda8c 100644
--- a/scripts/rustdoc-clif.rs
+++ b/scripts/rustdoc-clif.rs
@@ -17,8 +17,10 @@ fn main() {
let passed_args = std::env::args_os().skip(1).collect::>();
let mut args = vec![];
- args.push(OsString::from("-Cpanic=abort"));
- args.push(OsString::from("-Zpanic-abort-tests"));
+ if !cfg!(support_panic_unwind) {
+ args.push(OsString::from("-Cpanic=abort"));
+ args.push(OsString::from("-Zpanic-abort-tests"));
+ }
if let Some(name) = option_env!("BUILTIN_BACKEND") {
args.push(OsString::from(format!("-Zcodegen-backend={name}")))
} else {
diff --git a/scripts/rustup.sh b/scripts/rustup.sh
index 152c243aa6adc..fdfd03029b160 100755
--- a/scripts/rustup.sh
+++ b/scripts/rustup.sh
@@ -46,7 +46,7 @@ case $1 in
git pull origin master
branch=sync_cg_clif-$(date +%Y-%m-%d)
git checkout -b "$branch"
- "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git master
+ "$cg_clif/git-fixed-subtree.sh" pull --prefix=compiler/rustc_codegen_cranelift/ https://github.com/rust-lang/rustc_codegen_cranelift.git main
git push -u my "$branch"
# immediately merge the merge commit into cg_clif to prevent merge conflicts when syncing
diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh
index 492f4dc445277..c16cb4e538fe4 100644
--- a/scripts/setup_rust_fork.sh
+++ b/scripts/setup_rust_fork.sh
@@ -50,23 +50,24 @@ EOF
cat <(
+ );
+ }
-- if b && self.is_running_on_ci {
-- // On CI, we must always rebuild LLVM if there were any modifications to it
-- panic!(
-- "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead."
-- );
-- }
+- #[cfg(not(test))]
+- if b && dwn_ctx.is_running_on_ci && CiEnv::is_rust_lang_managed_ci_job() {
+- // On rust-lang CI, we must always rebuild LLVM if there were any modifications to it
+- panic!(
+- "\`llvm.download-ci-llvm\` cannot be set to \`true\` on CI. Use \`if-unchanged\` instead."
+- );
+- }
-
- // If download-ci-llvm=true we also want to check that CI llvm is available
- b && llvm::is_ci_llvm_available_for_target(self, asserts)
- }
+ // If download-ci-llvm=true we also want to check that CI llvm is available
+ b && llvm::is_ci_llvm_available_for_target(&dwn_ctx.host_target, asserts)
+ }
EOF
popd
diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh
index 62f1cc6a8933b..b5af585a732e3 100755
--- a/scripts/test_rustc_tests.sh
+++ b/scripts/test_rustc_tests.sh
@@ -10,7 +10,7 @@ pushd rust
command -v rg >/dev/null 2>&1 || cargo install ripgrep
-rm -r tests/ui/{unsized-locals/,lto/,linkage*} || true
+rm -r tests/ui/{lto/,linkage*} || true
for test in $(rg --files-with-matches "lto" tests/{codegen-units,ui,incremental}); do
rm $test
done
@@ -34,6 +34,7 @@ git checkout -- tests/ui/entry-point/auxiliary/bad_main_functions.rs
# vendor intrinsics
rm tests/ui/asm/x86_64/evex512-implicit-feature.rs # unimplemented AVX512 x86 vendor intrinsic
rm tests/ui/simd/dont-invalid-bitcast-x86_64.rs # unimplemented llvm.x86.sse41.round.ps
+rm tests/ui/simd/intrinsic/generic-arithmetic-pass.rs # unimplemented simd_funnel_{shl,shr}
# exotic linkages
rm tests/incremental/hashes/function_interfaces.rs
@@ -42,8 +43,14 @@ rm -r tests/run-make/naked-symbol-visibility
# variadic arguments
rm tests/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
+rm tests/ui/c-variadic/naked.rs # same
rm tests/ui/abi/variadic-ffi.rs # requires callee side vararg support
rm -r tests/run-make/c-link-to-rust-va-list-fn # requires callee side vararg support
+rm tests/ui/c-variadic/valid.rs # same
+rm tests/ui/c-variadic/trait-method.rs # same
+rm tests/ui/c-variadic/inherent-method.rs # same
+rm tests/ui/sanitizer/kcfi-c-variadic.rs # same
+rm tests/ui/c-variadic/same-program-multiple-abis-x86_64.rs # variadics for calling conventions other than C unsupported
rm tests/ui/delegation/fn-header.rs
# misc unimplemented things
@@ -56,8 +63,13 @@ rm tests/ui/asm/x86_64/issue-96797.rs # const and sym inline asm operands don't
rm tests/ui/asm/global-asm-mono-sym-fn.rs # same
rm tests/ui/asm/naked-asm-mono-sym-fn.rs # same
rm tests/ui/asm/x86_64/goto.rs # inline asm labels not supported
+rm tests/ui/asm/label-operand.rs # same
rm tests/ui/simd/simd-bitmask-notpow2.rs # non-pow-of-2 simd vector sizes
-rm -r tests/run-make/embed-source-dwarf # embedding sources in debuginfo
+rm -r tests/run-make/used-proc-macro # used(linker) isn't supported yet
+rm tests/ui/linking/no-gc-encapsulation-symbols.rs # same
+rm tests/ui/attributes/fn-align-dyn.rs # per-function alignment not supported
+rm -r tests/ui/explicit-tail-calls # tail calls
+rm -r tests/run-make/pointer-auth-link-with-c # pointer auth
# requires LTO
rm -r tests/run-make/cdylib
@@ -69,15 +81,13 @@ rm -r tests/run-make/reachable-extern-fn-available-lto
# coverage instrumentation
rm tests/ui/consts/precise-drop-with-coverage.rs
-rm tests/ui/issues/issue-85461.rs
rm -r tests/ui/instrument-coverage/
# optimization tests
# ==================
rm tests/ui/codegen/issue-28950.rs # depends on stack size optimizations
rm tests/ui/codegen/init-large-type.rs # same
-rm -r tests/run-make/fmt-write-bloat/ # tests an optimization
-rm tests/ui/statics/const_generics.rs # same
+rm tests/ui/statics/const_generics.rs # tests an optimization
rm tests/ui/linking/executable-no-mangle-strip.rs # requires --gc-sections to work for statics
# backend specific tests
@@ -92,7 +102,7 @@ rm -r tests/run-make/llvm-location-discriminator-limit-dummy-span # same
rm tests/ui/abi/stack-protector.rs # requires stack protector support
rm -r tests/run-make/emit-stack-sizes # requires support for -Z emit-stack-sizes
rm -r tests/run-make/optimization-remarks-dir # remarks are LLVM specific
-rm -r tests/ui/optimization-remark.rs # same
+rm -r tests/ui/codegen/remark-flag-functionality.rs # same
rm -r tests/run-make/print-to-output # requires --print relocation-models
# requires asm, llvm-ir and/or llvm-bc emit support
@@ -123,6 +133,8 @@ rm -r tests/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
rm -r tests/run-make/strip # same
rm -r tests/run-make-cargo/compiler-builtins # Expects lib/rustlib/src/rust to contains the standard library source
rm -r tests/run-make/translation # same
+rm -r tests/run-make-cargo/panic-immediate-abort-works # same
+rm -r tests/run-make-cargo/panic-immediate-abort-codegen # same
rm -r tests/run-make/missing-unstable-trait-bound # This disables support for unstable features, but running cg_clif needs some unstable features
rm -r tests/run-make/const-trait-stable-toolchain # same
rm -r tests/run-make/print-request-help-stable-unstable # same
@@ -130,6 +142,7 @@ rm -r tests/run-make/incr-add-rust-src-component
rm tests/ui/errors/remap-path-prefix-sysroot.rs # different sysroot source path
rm -r tests/run-make/export/extern-opt # something about rustc version mismatches
rm -r tests/run-make/export # same
+rm -r tests/ui/compiletest-self-test/compile-flags-incremental.rs # needs compiletest compiled with panic=unwind
# genuine bugs
# ============
@@ -143,9 +156,9 @@ rm tests/ui/backtrace/synchronized-panic-handler.rs # missing needs-unwind annot
rm tests/ui/lint/non-snake-case/lint-non-snake-case-crate.rs # same
rm tests/ui/async-await/async-drop/async-drop-initial.rs # same (rust-lang/rust#140493)
rm -r tests/ui/codegen/equal-pointers-unequal # make incorrect assumptions about the location of stack variables
+rm -r tests/run-make-cargo/rustdoc-scrape-examples-paths # FIXME(rust-lang/rust#145580) incr comp bug
-rm tests/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
-rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # same
+rm tests/ui/intrinsics/panic-uninitialized-zeroed.rs # really slow with unoptimized libstd
rm tests/ui/process/process-panic-after-fork.rs # same
cp ../dist/bin/rustdoc-clif ../dist/bin/rustdoc # some tests expect bin/rustdoc to exist
diff --git a/src/abi/mod.rs b/src/abi/mod.rs
index d7f17795815de..9ac282df5b5ea 100644
--- a/src/abi/mod.rs
+++ b/src/abi/mod.rs
@@ -7,7 +7,9 @@ mod returning;
use std::borrow::Cow;
use std::mem;
-use cranelift_codegen::ir::{ArgumentPurpose, SigRef};
+use cranelift_codegen::ir::{
+ ArgumentPurpose, BlockArg, ExceptionTableData, ExceptionTableItem, ExceptionTag, SigRef,
+};
use cranelift_codegen::isa::CallConv;
use cranelift_module::ModuleError;
use rustc_abi::{CanonAbi, ExternAbi, X86Call};
@@ -21,10 +23,12 @@ use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_target::callconv::{FnAbi, PassMode};
use rustc_target::spec::Arch;
-use smallvec::SmallVec;
+use smallvec::{SmallVec, smallvec};
use self::pass_mode::*;
pub(crate) use self::returning::codegen_return;
+use crate::base::codegen_unwind_terminate;
+use crate::debuginfo::EXCEPTION_HANDLER_CLEANUP;
use crate::prelude::*;
fn clif_sig_from_fn_abi<'tcx>(
@@ -82,7 +86,7 @@ pub(crate) fn get_function_sig<'tcx>(
clif_sig_from_fn_abi(
tcx,
default_call_conv,
- &FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
+ FullyMonomorphizedLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
)
}
@@ -111,7 +115,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
/// Instance must be monomorphized
pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef {
let func_id = import_function(self.tcx, self.module, inst);
- let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
+ let func_ref = self.module.declare_func_in_func(func_id, self.bcx.func);
if self.clif_comments.enabled() {
self.add_comment(func_ref, format!("{:?}", inst));
@@ -182,7 +186,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
) -> &[Value] {
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
- let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
+ let func_ref = self.module.declare_func_in_func(func_id, self.bcx.func);
let call_inst = self.bcx.ins().call(func_ref, args);
if self.clif_comments.enabled() {
self.add_comment(func_ref, format!("{:?}", name));
@@ -267,7 +271,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
// individual function arguments.
let tupled_arg_tys = match arg_ty.kind() {
- ty::Tuple(ref tys) => tys,
+ ty::Tuple(tys) => tys,
_ => bug!("spread argument isn't a tuple?! but {:?}", arg_ty),
};
@@ -297,7 +301,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_
Some(cvalue_for_param(fx, None, None, arg_abi, &mut block_params_iter).unwrap());
}
- assert!(arg_abis_iter.next().is_none(), "ArgAbi left behind");
+ assert_eq!(arg_abis_iter.next(), None, "ArgAbi left behind for {:?}", fx.fn_abi);
assert!(block_params_iter.next().is_none(), "arg_value left behind");
self::comments::add_locals_header_comment(fx);
@@ -381,7 +385,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
args: &[Spanned>],
destination: Place<'tcx>,
target: Option,
- _unwind: UnwindAction,
+ unwind: UnwindAction,
) {
let func = codegen_operand(fx, func);
let fn_sig = func.layout().ty.fn_sig(fx.tcx);
@@ -416,7 +420,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
if fx.tcx.symbol_name(instance).name.starts_with("llvm.") {
crate::intrinsics::codegen_llvm_intrinsic_call(
fx,
- &fx.tcx.symbol_name(instance).name,
+ fx.tcx.symbol_name(instance).name,
args,
ret_place,
target,
@@ -490,7 +494,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
};
let tupled_arguments = match pack_arg.value.layout().ty.kind() {
- ty::Tuple(ref tupled_arguments) => tupled_arguments,
+ ty::Tuple(tupled_arguments) => tupled_arguments,
_ => bug!("argument to function with \"rust-call\" ABI is not a tuple"),
};
@@ -516,12 +520,6 @@ pub(crate) fn codegen_terminator_call<'tcx>(
let args = args;
assert_eq!(fn_abi.args.len(), args.len());
- #[derive(Copy, Clone)]
- enum CallTarget {
- Direct(FuncRef),
- Indirect(SigRef, Value),
- }
-
let (func_ref, first_arg_override) = match instance {
// Trait object call
Some(Instance { def: InstanceKind::Virtual(_, idx), .. }) => {
@@ -537,7 +535,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0].value, idx);
- let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
+ let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi);
let sig = fx.bcx.import_signature(sig);
(CallTarget::Indirect(sig, method), Some(ptr.get_addr(fx)))
@@ -557,7 +555,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
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 = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi);
let sig = fx.bcx.import_signature(sig);
(CallTarget::Indirect(sig, func), None)
@@ -567,7 +565,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
self::returning::codegen_with_call_return_arg(fx, &fn_abi.ret, ret_place, |fx, return_ptr| {
let mut call_args = return_ptr
.into_iter()
- .chain(first_arg_override.into_iter())
+ .chain(first_arg_override)
.chain(
args.into_iter()
.enumerate()
@@ -580,21 +578,15 @@ pub(crate) fn codegen_terminator_call<'tcx>(
// FIXME: Find a cleaner way to support varargs.
if fn_abi.c_variadic {
- adjust_call_for_c_variadic(fx, &fn_abi, source_info, func_ref, &mut call_args);
+ adjust_call_for_c_variadic(fx, fn_abi, source_info, func_ref, &mut call_args);
}
- let call_inst = match func_ref {
- CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, &call_args),
- CallTarget::Indirect(sig, func_ptr) => {
- fx.bcx.ins().call_indirect(sig, func_ptr, &call_args)
- }
- };
-
if fx.clif_comments.enabled() {
- with_no_trimmed_paths!(fx.add_comment(call_inst, format!("abi: {:?}", fn_abi)));
+ let nop_inst = fx.bcx.ins().nop();
+ with_no_trimmed_paths!(fx.add_post_comment(nop_inst, format!("abi: {:?}", fn_abi)));
}
- fx.bcx.func.dfg.inst_results(call_inst).iter().copied().collect::>()
+ codegen_call_with_unwind_action(fx, source_info.span, func_ref, unwind, &call_args, None)
});
if let Some(dest) = target {
@@ -704,7 +696,7 @@ pub(crate) fn codegen_drop<'tcx>(
source_info: mir::SourceInfo,
drop_place: CPlace<'tcx>,
target: BasicBlock,
- _unwind: UnwindAction,
+ unwind: UnwindAction,
) {
let ty = drop_place.layout().ty;
let drop_instance = Instance::resolve_drop_in_place(fx.tcx, ty);
@@ -748,11 +740,16 @@ pub(crate) fn codegen_drop<'tcx>(
let fn_abi = FullyMonomorphizedLayoutCx(fx.tcx)
.fn_abi_of_instance(virtual_drop, ty::List::empty());
- let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
+ let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, fn_abi);
let sig = fx.bcx.import_signature(sig);
- // FIXME implement cleanup on exceptions
- fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
- fx.bcx.ins().jump(ret_block, &[]);
+ codegen_call_with_unwind_action(
+ fx,
+ source_info.span,
+ CallTarget::Indirect(sig, drop_fn),
+ unwind,
+ &[ptr],
+ Some(ret_block),
+ );
}
_ => {
assert!(!matches!(drop_instance.def, InstanceKind::Virtual(_, _)));
@@ -771,15 +768,146 @@ pub(crate) fn codegen_drop<'tcx>(
if drop_instance.def.requires_caller_location(fx.tcx) {
// Pass the caller location for `#[track_caller]`.
let caller_location = fx.get_caller_location(source_info);
- call_args.extend(
- adjust_arg_for_abi(fx, caller_location, &fn_abi.args[1], false).into_iter(),
- );
+ call_args.extend(adjust_arg_for_abi(
+ fx,
+ caller_location,
+ &fn_abi.args[1],
+ false,
+ ));
}
let func_ref = fx.get_function_ref(drop_instance);
- fx.bcx.ins().call(func_ref, &call_args);
- // FIXME implement cleanup on exceptions
- fx.bcx.ins().jump(ret_block, &[]);
+ codegen_call_with_unwind_action(
+ fx,
+ source_info.span,
+ CallTarget::Direct(func_ref),
+ unwind,
+ &call_args,
+ Some(ret_block),
+ );
+ }
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum CallTarget {
+ Direct(FuncRef),
+ Indirect(SigRef, Value),
+}
+
+pub(crate) fn codegen_call_with_unwind_action(
+ fx: &mut FunctionCx<'_, '_, '_>,
+ span: Span,
+ func_ref: CallTarget,
+ mut unwind: UnwindAction,
+ call_args: &[Value],
+ target_block: Option,
+) -> SmallVec<[Value; 2]> {
+ let sig_ref = match func_ref {
+ CallTarget::Direct(func_ref) => fx.bcx.func.dfg.ext_funcs[func_ref].signature,
+ CallTarget::Indirect(sig_ref, _func_ptr) => sig_ref,
+ };
+
+ if target_block.is_some() {
+ assert!(fx.bcx.func.dfg.signatures[sig_ref].returns.is_empty());
+ }
+
+ if cfg!(not(feature = "unwinding")) {
+ unwind = UnwindAction::Unreachable;
+ }
+
+ match unwind {
+ UnwindAction::Continue | UnwindAction::Unreachable => {
+ let call_inst = match func_ref {
+ CallTarget::Direct(func_ref) => fx.bcx.ins().call(func_ref, call_args),
+ CallTarget::Indirect(sig, func_ptr) => {
+ fx.bcx.ins().call_indirect(sig, func_ptr, call_args)
+ }
+ };
+
+ if let Some(target_block) = target_block {
+ fx.bcx.ins().jump(target_block, &[]);
+ smallvec![]
+ } else {
+ fx.bcx
+ .func
+ .dfg
+ .inst_results(call_inst)
+ .iter()
+ .copied()
+ .collect::>()
+ }
+ }
+ UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) => {
+ let returns_types = fx.bcx.func.dfg.signatures[sig_ref]
+ .returns
+ .iter()
+ .map(|return_param| return_param.value_type)
+ .collect::>();
+
+ let fallthrough_block = fx.bcx.create_block();
+ let fallthrough_block_call_args = returns_types
+ .iter()
+ .enumerate()
+ .map(|(i, _)| BlockArg::TryCallRet(i.try_into().unwrap()))
+ .collect::>();
+ let fallthrough_block_call = fx.bcx.func.dfg.block_call(
+ target_block.unwrap_or(fallthrough_block),
+ &fallthrough_block_call_args,
+ );
+ let pre_cleanup_block = fx.bcx.create_block();
+ let pre_cleanup_block_call =
+ fx.bcx.func.dfg.block_call(pre_cleanup_block, &[BlockArg::TryCallExn(0)]);
+ let exception_table = fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new(
+ sig_ref,
+ fallthrough_block_call,
+ [ExceptionTableItem::Tag(
+ ExceptionTag::with_number(EXCEPTION_HANDLER_CLEANUP).unwrap(),
+ pre_cleanup_block_call,
+ )],
+ ));
+
+ match func_ref {
+ CallTarget::Direct(func_ref) => {
+ fx.bcx.ins().try_call(func_ref, call_args, exception_table);
+ }
+ CallTarget::Indirect(_sig, func_ptr) => {
+ fx.bcx.ins().try_call_indirect(func_ptr, call_args, exception_table);
+ }
+ }
+
+ fx.bcx.seal_block(pre_cleanup_block);
+ fx.bcx.switch_to_block(pre_cleanup_block);
+ fx.bcx.set_cold_block(pre_cleanup_block);
+ match unwind {
+ UnwindAction::Continue | UnwindAction::Unreachable => unreachable!(),
+ UnwindAction::Cleanup(cleanup) => {
+ let exception_ptr =
+ fx.bcx.append_block_param(pre_cleanup_block, fx.pointer_type);
+ fx.bcx.def_var(fx.exception_slot, exception_ptr);
+ let cleanup_block = fx.get_block(cleanup);
+ fx.bcx.ins().jump(cleanup_block, &[]);
+ }
+ UnwindAction::Terminate(reason) => {
+ // FIXME dedup terminate blocks
+ fx.bcx.append_block_param(pre_cleanup_block, fx.pointer_type);
+
+ codegen_unwind_terminate(fx, span, reason);
+ }
+ }
+
+ if target_block.is_none() {
+ fx.bcx.seal_block(fallthrough_block);
+ fx.bcx.switch_to_block(fallthrough_block);
+ let returns = returns_types
+ .into_iter()
+ .map(|ty| fx.bcx.append_block_param(fallthrough_block, ty))
+ .collect();
+ fx.bcx.ins().nop();
+ returns
+ } else {
+ smallvec![]
}
}
}
diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs
index 7a909a740b054..44b63aa95f83c 100644
--- a/src/abi/pass_mode.rs
+++ b/src/abi/pass_mode.rs
@@ -209,12 +209,7 @@ pub(super) fn to_casted_value<'tcx>(
cast_target_to_abi_params(cast)
.into_iter()
.map(|(offset, param)| {
- let val = ptr.offset_i64(fx, offset.bytes() as i64).load(
- fx,
- param.value_type,
- MemFlags::new(),
- );
- val
+ ptr.offset_i64(fx, offset.bytes() as i64).load(fx, param.value_type, MemFlags::new())
})
.collect()
}
diff --git a/src/base.rs b/src/base.rs
index 7d50548b40262..0d3b38d52c8da 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -12,6 +12,8 @@ use rustc_middle::ty::TypeVisitableExt;
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
use rustc_middle::ty::print::with_no_trimmed_paths;
+use rustc_session::config::OutputFilenames;
+use rustc_span::Symbol;
use crate::constant::ConstantCx;
use crate::debuginfo::{FunctionDebugContext, TypeDebugContext};
@@ -25,11 +27,13 @@ pub(crate) struct CodegenedFunction {
func: Function,
clif_comments: CommentWriter,
func_debug_cx: Option,
+ inline_asm: String,
}
pub(crate) fn codegen_fn<'tcx>(
tcx: TyCtxt<'tcx>,
- cx: &mut crate::CodegenCx,
+ cgu_name: Symbol,
+ mut debug_context: Option<&mut DebugContext>,
type_dbg: &mut TypeDebugContext<'tcx>,
cached_func: Function,
module: &mut dyn Module,
@@ -60,7 +64,9 @@ pub(crate) fn codegen_fn<'tcx>(
func.clear();
func.name = UserFuncName::user(0, func_id.as_u32());
func.signature = sig;
- func.collect_debug_info();
+ if debug_context.is_some() {
+ func.collect_debug_info();
+ }
let mut bcx = FunctionBuilder::new(&mut func, &mut func_ctx);
@@ -74,23 +80,27 @@ pub(crate) fn codegen_fn<'tcx>(
// Make FunctionCx
let target_config = module.target_config();
let pointer_type = target_config.pointer_type();
+ assert_eq!(pointer_ty(tcx), pointer_type);
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance, fn_abi);
- let func_debug_cx = if let Some(debug_context) = &mut cx.debug_context {
+ let func_debug_cx = if let Some(debug_context) = debug_context.as_deref_mut() {
Some(debug_context.define_function(tcx, type_dbg, instance, fn_abi, &symbol_name, mir.span))
} else {
None
};
+ let exception_slot = bcx.declare_var(pointer_type);
+
let mut fx = FunctionCx {
- cx,
module,
+ debug_context,
tcx,
target_config,
pointer_type,
constants_cx: ConstantCx::new(),
func_debug_cx,
+ cgu_name,
instance,
symbol_name,
mir,
@@ -100,9 +110,11 @@ pub(crate) fn codegen_fn<'tcx>(
block_map,
local_map: IndexVec::with_capacity(mir.local_decls.len()),
caller_location: None, // set by `codegen_fn_prelude`
+ exception_slot,
clif_comments,
- next_ssa_var: 0,
+ inline_asm: String::new(),
+ inline_asm_index: 0,
};
tcx.prof.generic_activity("codegen clif ir").run(|| codegen_fn_body(&mut fx, start_block));
@@ -113,10 +125,11 @@ pub(crate) fn codegen_fn<'tcx>(
let symbol_name = fx.symbol_name;
let clif_comments = fx.clif_comments;
let func_debug_cx = fx.func_debug_cx;
+ let inline_asm = fx.inline_asm;
fx.constants_cx.finalize(fx.tcx, &mut *fx.module);
- if cx.should_write_ir {
+ if crate::pretty_clif::should_write_ir(tcx.sess) {
crate::pretty_clif::write_clif_file(
tcx.output_filenames(()),
&symbol_name,
@@ -130,20 +143,24 @@ pub(crate) fn codegen_fn<'tcx>(
// Verify function
verify_func(tcx, &clif_comments, &func);
- CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx }
+ CodegenedFunction { symbol_name, func_id, func, clif_comments, func_debug_cx, inline_asm }
}
pub(crate) fn compile_fn(
- cx: &mut crate::CodegenCx,
profiler: &SelfProfilerRef,
+ output_filenames: &OutputFilenames,
+ should_write_ir: bool,
cached_context: &mut Context,
module: &mut dyn Module,
+ debug_context: Option<&mut DebugContext>,
+ global_asm: &mut String,
codegened_func: CodegenedFunction,
) {
let _timer =
profiler.generic_activity_with_arg("compile function", &*codegened_func.symbol_name);
let clif_comments = codegened_func.clif_comments;
+ global_asm.push_str(&codegened_func.inline_asm);
// Store function in context
let context = cached_context;
@@ -180,7 +197,7 @@ pub(crate) fn compile_fn(
// Define function
profiler.generic_activity("define function").run(|| {
- context.want_disasm = cx.should_write_ir;
+ context.want_disasm = should_write_ir;
match module.define_function(codegened_func.func_id, context) {
Ok(()) => {}
Err(ModuleError::Compilation(CodegenError::ImplLimitExceeded)) => {
@@ -210,10 +227,10 @@ pub(crate) fn compile_fn(
}
});
- if cx.should_write_ir {
+ if should_write_ir {
// Write optimized function to file for debugging
crate::pretty_clif::write_clif_file(
- &cx.output_filenames,
+ output_filenames,
&codegened_func.symbol_name,
"opt",
module.isa(),
@@ -223,7 +240,7 @@ pub(crate) fn compile_fn(
if let Some(disasm) = &context.compiled_code().unwrap().vcode {
crate::pretty_clif::write_ir_file(
- &cx.output_filenames,
+ output_filenames,
&format!("{}.vcode", codegened_func.symbol_name),
|file| file.write_all(disasm.as_bytes()),
)
@@ -231,7 +248,6 @@ pub(crate) fn compile_fn(
}
// Define debuginfo for function
- let debug_context = &mut cx.debug_context;
profiler.generic_activity("generate debug info").run(|| {
if let Some(debug_context) = debug_context {
codegened_func.func_debug_cx.unwrap().finalize(
@@ -250,12 +266,12 @@ fn verify_func(tcx: TyCtxt<'_>, writer: &crate::pretty_clif::CommentWriter, func
tcx.prof.generic_activity("verify clif ir").run(|| {
let flags = cranelift_codegen::settings::Flags::new(cranelift_codegen::settings::builder());
- match cranelift_codegen::verify_function(&func, &flags) {
+ match cranelift_codegen::verify_function(func, &flags) {
Ok(_) => {}
Err(err) => {
tcx.dcx().err(format!("{:?}", err));
let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error(
- &func,
+ func,
Some(Box::new(writer)),
err,
);
@@ -295,11 +311,11 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
}
if bb_data.is_cleanup {
- // Unwinding after panicking is not supported
- continue;
+ if cfg!(not(feature = "unwinding")) {
+ continue;
+ }
- // FIXME Once unwinding is supported and Cranelift supports marking blocks as cold, do
- // so for cleanup blocks.
+ fx.bcx.set_cold_block(block);
}
fx.bcx.ins().nop();
@@ -369,7 +385,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
fx.bcx.ins().nop();
match &**msg {
- AssertKind::BoundsCheck { ref len, ref index } => {
+ AssertKind::BoundsCheck { len, index } => {
let len = codegen_operand(fx, len).load_scalar(fx);
let index = codegen_operand(fx, index).load_scalar(fx);
let location = fx.get_caller_location(source_info).load_scalar(fx);
@@ -382,7 +398,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
source_info.span,
);
}
- AssertKind::MisalignedPointerDereference { ref required, ref found } => {
+ AssertKind::MisalignedPointerDereference { required, found } => {
let required = codegen_operand(fx, required).load_scalar(fx);
let found = codegen_operand(fx, found).load_scalar(fx);
let location = fx.get_caller_location(source_info).load_scalar(fx);
@@ -538,14 +554,22 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
template,
operands,
*options,
- targets.get(0).copied(),
+ targets.first().copied(),
);
}
TerminatorKind::UnwindTerminate(reason) => {
codegen_unwind_terminate(fx, source_info.span, *reason);
}
TerminatorKind::UnwindResume => {
- // FIXME implement unwinding
+ if cfg!(feature = "unwinding") {
+ let exception_ptr = fx.bcx.use_var(fx.exception_slot);
+ fx.lib_call(
+ "_Unwind_Resume",
+ vec![AbiParam::new(fx.pointer_type)],
+ vec![],
+ &[exception_ptr],
+ );
+ }
fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
}
TerminatorKind::Unreachable => {
@@ -929,7 +953,7 @@ fn codegen_stmt<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, cur_block: Block, stmt:
| StatementKind::AscribeUserType(..) => {}
StatementKind::Coverage { .. } => unreachable!(),
- StatementKind::Intrinsic(ref intrinsic) => match &**intrinsic {
+ StatementKind::Intrinsic(intrinsic) => match &**intrinsic {
// We ignore `assume` intrinsics, they are only useful for optimizations
NonDivergingIntrinsic::Assume(_) => {}
NonDivergingIntrinsic::CopyNonOverlapping(mir::CopyNonOverlapping {
@@ -1060,7 +1084,7 @@ pub(crate) fn codegen_panic_nounwind<'tcx>(
msg_str: &str,
span: Span,
) {
- let msg_ptr = fx.anonymous_str(msg_str);
+ let msg_ptr = crate::constant::pointer_for_anonymous_str(fx, msg_str);
let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap());
let args = [msg_ptr, msg_len];
@@ -1085,7 +1109,7 @@ fn codegen_panic_inner<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
lang_item: rustc_hir::LangItem,
args: &[Value],
- _unwind: UnwindAction,
+ unwind: UnwindAction,
span: Span,
) {
fx.bcx.set_cold_block(fx.bcx.current_block().unwrap());
@@ -1101,14 +1125,23 @@ fn codegen_panic_inner<'tcx>(
let symbol_name = fx.tcx.symbol_name(instance).name;
- // FIXME implement cleanup on exceptions
+ let sig = Signature {
+ params: args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(),
+ returns: vec![],
+ call_conv: fx.target_config.default_call_conv,
+ };
+ let func_id = fx.module.declare_function(symbol_name, Linkage::Import, &sig).unwrap();
+ let func_ref = fx.module.declare_func_in_func(func_id, fx.bcx.func);
+ if fx.clif_comments.enabled() {
+ fx.add_comment(func_ref, format!("{:?}", symbol_name));
+ }
- fx.lib_call(
- symbol_name,
- args.iter().map(|&arg| AbiParam::new(fx.bcx.func.dfg.value_type(arg))).collect(),
- vec![],
- args,
- );
+ let nop_inst = fx.bcx.ins().nop();
+ if fx.clif_comments.enabled() {
+ fx.add_comment(nop_inst, format!("panic {}", symbol_name));
+ }
+
+ codegen_call_with_unwind_action(fx, span, CallTarget::Direct(func_ref), unwind, args, None);
fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap());
}
diff --git a/src/codegen_f16_f128.rs b/src/codegen_f16_f128.rs
index c0f6d9d853db2..91f7220667ff9 100644
--- a/src/codegen_f16_f128.rs
+++ b/src/codegen_f16_f128.rs
@@ -1,5 +1,6 @@
use rustc_target::spec::Arch;
+use crate::compiler_builtins::CMP_RESULT_TY;
use crate::prelude::*;
pub(crate) fn f16_to_f32(fx: &mut FunctionCx<'_, '_, '_>, value: Value) -> Value {
@@ -74,15 +75,11 @@ pub(crate) fn fcmp(fx: &mut FunctionCx<'_, '_, '_>, cc: FloatCC, lhs: Value, rhs
let res = fx.lib_call(
name,
vec![AbiParam::new(types::F128), AbiParam::new(types::F128)],
- // FIXME(rust-lang/compiler-builtins#919): This should be `I64` on non-AArch64
- // architectures, but switching it before compiler-builtins is fixed causes test
- // failures.
- vec![AbiParam::new(types::I32)],
+ vec![AbiParam::new(CMP_RESULT_TY)],
&[lhs, rhs],
)[0];
- let zero = fx.bcx.ins().iconst(types::I32, 0);
- let res = fx.bcx.ins().icmp(int_cc, res, zero);
- res
+ let zero = fx.bcx.ins().iconst(CMP_RESULT_TY, 0);
+ fx.bcx.ins().icmp(int_cc, res, zero)
}
_ => unreachable!("{ty:?}"),
}
diff --git a/src/common.rs b/src/common.rs
index de3d2f31af103..38676eaac3d56 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -1,11 +1,12 @@
use cranelift_codegen::isa::TargetFrontendConfig;
-use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
+use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
use rustc_abi::{Float, Integer, Primitive};
use rustc_index::IndexVec;
use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::layout::{
self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
};
+use rustc_span::Symbol;
use rustc_span::source_map::Spanned;
use rustc_target::callconv::FnAbi;
use rustc_target::spec::{Arch, HasTargetSpec, Target};
@@ -256,7 +257,7 @@ pub(crate) fn create_wrapper_function(
.map(|param| func.dfg.append_block_param(block, param.value_type))
.collect::>();
- let callee_func_ref = module.declare_func_in_func(callee_func_id, &mut bcx.func);
+ let callee_func_ref = module.declare_func_in_func(callee_func_id, bcx.func);
let call_inst = bcx.ins().call(callee_func_ref, &args);
let results = bcx.inst_results(call_inst).to_vec(); // Clone to prevent borrow error
@@ -268,14 +269,15 @@ pub(crate) fn create_wrapper_function(
}
pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
- pub(crate) cx: &'clif mut crate::CodegenCx,
pub(crate) module: &'m mut dyn Module,
+ pub(crate) debug_context: Option<&'clif mut DebugContext>,
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) target_config: TargetFrontendConfig, // Cached from module
pub(crate) pointer_type: Type, // Cached from module
pub(crate) constants_cx: ConstantCx,
pub(crate) func_debug_cx: Option,
+ pub(crate) cgu_name: Symbol,
pub(crate) instance: Instance<'tcx>,
pub(crate) symbol_name: String,
pub(crate) mir: &'tcx Body<'tcx>,
@@ -288,10 +290,13 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
/// When `#[track_caller]` is used, the implicit caller location is stored in this variable.
pub(crate) caller_location: Option>,
+ /// During cleanup the exception pointer will be stored in this variable.
+ pub(crate) exception_slot: Variable,
+
pub(crate) clif_comments: crate::pretty_clif::CommentWriter,
- /// This should only be accessed by `CPlace::new_var`.
- pub(crate) next_ssa_var: u32,
+ pub(crate) inline_asm: String,
+ pub(crate) inline_asm_index: u32,
}
impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
@@ -369,7 +374,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer {
assert!(
- size % align == 0,
+ size.is_multiple_of(align),
"size must be a multiple of alignment (size={size}, align={align})"
);
@@ -379,7 +384,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
kind: StackSlotKind::ExplicitSlot,
// FIXME Don't force the size to a multiple of bytes once Cranelift gets
// a way to specify stack slot alignment.
- size: (size + abi_align - 1) / abi_align * abi_align,
+ size: size.div_ceil(abi_align) * abi_align,
align_shift: 4,
});
Pointer::stack_slot(stack_slot)
@@ -401,7 +406,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
}
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
- if let Some(debug_context) = &mut self.cx.debug_context {
+ if let Some(debug_context) = &mut self.debug_context {
let (file_id, line, column) =
debug_context.get_span_loc(self.tcx, self.mir.span, source_info.span);
@@ -417,21 +422,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty())
})
}
-
- pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value {
- let mut data = DataDescription::new();
- data.define(msg.as_bytes().to_vec().into_boxed_slice());
- let msg_id = self.module.declare_anonymous_data(false, false).unwrap();
-
- // Ignore DuplicateDefinition error, as the data will be the same
- let _ = self.module.define_data(msg_id, &data);
-
- let local_msg_id = self.module.declare_data_in_func(msg_id, self.bcx.func);
- if self.clif_comments.enabled() {
- self.add_comment(local_msg_id, msg);
- }
- self.bcx.ins().global_value(self.pointer_type, local_msg_id)
- }
}
pub(crate) struct FullyMonomorphizedLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs
index 6eea19211fa1b..ca9157daae584 100644
--- a/src/compiler_builtins.rs
+++ b/src/compiler_builtins.rs
@@ -3,11 +3,34 @@ use std::ffi::c_int;
#[cfg(feature = "jit")]
use std::ffi::c_void;
+use cranelift_codegen::ir::{Type, types};
+
// FIXME replace with core::ffi::c_size_t once stabilized
#[allow(non_camel_case_types)]
#[cfg(feature = "jit")]
type size_t = usize;
+// Needs to stay in sync with compiler-builtins
+
+// Aarch64 uses `int` rather than a pointer-sized value.
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
+#[cfg(feature = "jit")]
+type CmpResult = i32;
+#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
+pub(crate) const CMP_RESULT_TY: Type = types::I32;
+
+// In compiler-rt, LLP64 ABIs use `long long` and everything else uses `long`. In effect,
+// this means the return value is always pointer-sized.
+#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))]
+#[cfg(feature = "jit")]
+type CmpResult = isize;
+#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))]
+#[cfg(target_pointer_width = "32")]
+pub(crate) const CMP_RESULT_TY: Type = types::I32;
+#[cfg(not(any(target_arch = "aarch64", target_arch = "arm64ec")))]
+#[cfg(target_pointer_width = "64")]
+pub(crate) const CMP_RESULT_TY: Type = types::I64;
+
macro_rules! builtin_functions {
(
$register:ident;
@@ -18,7 +41,7 @@ macro_rules! builtin_functions {
) => {
#[cfg(feature = "jit")]
#[allow(improper_ctypes)]
- extern "C" {
+ unsafe extern "C" {
$(
$(#[$attr])?
fn $name($($arg_name: $arg_ty),*) -> $ret_ty;
@@ -85,15 +108,18 @@ builtin_functions! {
fn __divtf3(a: f128, b: f128) -> f128;
fn fmodf(a: f32, b: f32) -> f32;
fn fmod(a: f64, b: f64) -> f64;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn fmodf128(a: f128, b: f128) -> f128;
// float comparison
- fn __eqtf2(a: f128, b: f128) -> i32;
- fn __netf2(a: f128, b: f128) -> i32;
- fn __lttf2(a: f128, b: f128) -> i32;
- fn __letf2(a: f128, b: f128) -> i32;
- fn __gttf2(a: f128, b: f128) -> i32;
- fn __getf2(a: f128, b: f128) -> i32;
+ fn __eqtf2(a: f128, b: f128) -> CmpResult;
+ fn __netf2(a: f128, b: f128) -> CmpResult;
+ fn __lttf2(a: f128, b: f128) -> CmpResult;
+ fn __letf2(a: f128, b: f128) -> CmpResult;
+ fn __gttf2(a: f128, b: f128) -> CmpResult;
+ fn __getf2(a: f128, b: f128) -> CmpResult;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn fminimumf128(a: f128, b: f128) -> f128;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn fmaximumf128(a: f128, b: f128) -> f128;
// Cranelift float libcalls
fn fmaf(a: f32, b: f32, c: f32) -> f32;
@@ -127,16 +153,27 @@ builtin_functions! {
fn sin(f: f64) -> f64;
fn cosf(f: f32) -> f32;
fn cos(f: f64) -> f64;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn fmaf128(a: f128, b: f128, c: f128) -> f128;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn floorf16(f: f16) -> f16;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn floorf128(f: f128) -> f128;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn ceilf16(f: f16) -> f16;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn ceilf128(f: f128) -> f128;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn truncf16(f: f16) -> f16;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn truncf128(f: f128) -> f128;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn rintf16(f: f16) -> f16;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn rintf128(f: f128) -> f128;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn sqrtf16(f: f16) -> f16;
+ #[cfg(not(all(target_os = "windows", target_env = "gnu")))]
fn sqrtf128(f: f128) -> f128;
// FIXME(f16_f128): Add other float intrinsics as compiler-builtins gains support (meaning they
// are available on all targets).
diff --git a/src/config.rs b/src/config.rs
index d328b33a704f5..31bc0374460f4 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,5 +1,5 @@
/// Configuration of cg_clif as passed in through `-Cllvm-args` and various env vars.
-#[derive(Clone, Debug)]
+#[derive(Debug)]
pub struct BackendConfig {
/// Should the crate be AOT compiled or JIT executed.
///
diff --git a/src/constant.rs b/src/constant.rs
index 3243e12e69999..2b65b82906818 100644
--- a/src/constant.rs
+++ b/src/constant.rs
@@ -3,6 +3,7 @@
use std::cmp::Ordering;
use cranelift_module::*;
+use rustc_const_eval::interpret::CTFE_ALLOC_SALT;
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::interpret::{
@@ -64,7 +65,7 @@ pub(crate) fn codegen_tls_ref<'tcx>(
// For a declaration the stated mutability doesn't matter.
false,
);
- let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+ let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
if fx.clif_comments.enabled() {
fx.add_comment(local_data_id, format!("tls {:?}", def_id));
}
@@ -110,7 +111,7 @@ pub(crate) fn codegen_const_value<'tcx>(
ConstValue::Scalar(x) => match x {
Scalar::Int(int) => {
if fx.clif_type(layout.ty).is_some() {
- return CValue::const_val(fx, layout, int);
+ CValue::const_val(fx, layout, int)
} else {
let raw_val = int.size().truncate(int.to_bits(int.size()));
let val = match int.size().bytes() {
@@ -140,11 +141,7 @@ pub(crate) fn codegen_const_value<'tcx>(
let base_addr = match fx.tcx.global_alloc(alloc_id) {
GlobalAlloc::Memory(alloc) => {
if alloc.inner().len() == 0 {
- let val = alloc.inner().align.bytes().wrapping_add(offset.bytes());
- fx.bcx.ins().iconst(
- fx.pointer_type,
- fx.tcx.truncate_to_target_usize(val) as i64,
- )
+ fx.bcx.ins().iconst(fx.pointer_type, alloc.inner().align.bytes() as i64)
} else {
let data_id = data_id_for_alloc_id(
&mut fx.constants_cx,
@@ -153,17 +150,16 @@ pub(crate) fn codegen_const_value<'tcx>(
alloc.inner().mutability,
);
let local_data_id =
- fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+ fx.module.declare_data_in_func(data_id, fx.bcx.func);
if fx.clif_comments.enabled() {
fx.add_comment(local_data_id, format!("{:?}", alloc_id));
}
- fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
+ fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id)
}
}
GlobalAlloc::Function { instance, .. } => {
let func_id = crate::abi::import_function(fx.tcx, fx.module, instance);
- let local_func_id =
- fx.module.declare_func_in_func(func_id, &mut fx.bcx.func);
+ let local_func_id = fx.module.declare_func_in_func(func_id, fx.bcx.func);
fx.bcx.ins().func_addr(fx.pointer_type, local_func_id)
}
GlobalAlloc::VTable(ty, dyn_ty) => {
@@ -176,9 +172,8 @@ pub(crate) fn codegen_const_value<'tcx>(
fx.tcx.instantiate_bound_regions_with_erased(principal)
}),
);
- let local_data_id =
- fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
- fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
+ let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
+ fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id)
}
GlobalAlloc::TypeId { .. } => {
return CValue::const_val(
@@ -194,16 +189,26 @@ pub(crate) fn codegen_const_value<'tcx>(
// For a declaration the stated mutability doesn't matter.
false,
);
- let local_data_id =
- fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+ let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
if fx.clif_comments.enabled() {
fx.add_comment(local_data_id, format!("{:?}", def_id));
}
- fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
+ if fx
+ .tcx
+ .codegen_fn_attrs(def_id)
+ .flags
+ .contains(CodegenFnAttrFlags::THREAD_LOCAL)
+ {
+ fx.bcx.ins().tls_value(fx.pointer_type, local_data_id)
+ } else {
+ fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id)
+ }
}
};
let val = if offset.bytes() != 0 {
- fx.bcx.ins().iadd_imm(base_addr, i64::try_from(offset.bytes()).unwrap())
+ fx.bcx
+ .ins()
+ .iadd_imm(base_addr, fx.tcx.truncate_to_target_usize(offset.bytes()) as i64)
} else {
base_addr
};
@@ -211,32 +216,28 @@ pub(crate) fn codegen_const_value<'tcx>(
}
},
ConstValue::Indirect { alloc_id, offset } => CValue::by_ref(
- pointer_for_allocation(fx, alloc_id)
+ Pointer::new(pointer_for_allocation(fx, alloc_id))
.offset_i64(fx, i64::try_from(offset.bytes()).unwrap()),
layout,
),
ConstValue::Slice { alloc_id, meta } => {
- let ptr = pointer_for_allocation(fx, alloc_id).get_addr(fx);
+ let ptr = pointer_for_allocation(fx, alloc_id);
let len = fx.bcx.ins().iconst(fx.pointer_type, meta as i64);
CValue::by_val_pair(ptr, len, layout)
}
}
}
-fn pointer_for_allocation<'tcx>(
- fx: &mut FunctionCx<'_, '_, 'tcx>,
- alloc_id: AllocId,
-) -> crate::pointer::Pointer {
+fn pointer_for_allocation<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, alloc_id: AllocId) -> Value {
let alloc = fx.tcx.global_alloc(alloc_id).unwrap_memory();
let data_id =
data_id_for_alloc_id(&mut fx.constants_cx, fx.module, alloc_id, alloc.inner().mutability);
- let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
+ let local_data_id = fx.module.declare_data_in_func(data_id, fx.bcx.func);
if fx.clif_comments.enabled() {
fx.add_comment(local_data_id, format!("{:?}", alloc_id));
}
- let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id);
- crate::pointer::Pointer::new(global_ptr)
+ fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id)
}
fn data_id_for_alloc_id(
@@ -262,6 +263,11 @@ pub(crate) fn data_id_for_vtable<'tcx>(
data_id_for_alloc_id(cx, module, alloc_id, Mutability::Not)
}
+pub(crate) fn pointer_for_anonymous_str(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) -> Value {
+ let alloc_id = fx.tcx.allocate_bytes_dedup(msg.as_bytes(), CTFE_ALLOC_SALT);
+ pointer_for_allocation(fx, alloc_id)
+}
+
fn data_id_for_static(
tcx: TyCtxt<'_>,
module: &mut dyn Module,
@@ -345,7 +351,7 @@ fn data_id_for_static(
Linkage::Import
};
- let data_id = match module.declare_data(
+ match module.declare_data(
symbol_name,
linkage,
definition_writable,
@@ -356,9 +362,7 @@ fn data_id_for_static(
"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) {
@@ -368,6 +372,8 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
continue;
}
+ let mut data = DataDescription::new();
+
let (data_id, alloc, section_name) = match todo_item {
TodoItem::Alloc(alloc_id) => {
let alloc = match tcx.global_alloc(alloc_id) {
@@ -386,7 +392,10 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
(data_id, alloc, None)
}
TodoItem::Static(def_id) => {
- let section_name = tcx.codegen_fn_attrs(def_id).link_section;
+ let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
+ let section_name = codegen_fn_attrs.link_section;
+
+ data.set_used(codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER));
let alloc = tcx.eval_static_initializer(def_id).unwrap();
@@ -401,7 +410,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
}
};
- let mut data = DataDescription::new();
let alloc = alloc.inner();
data.set_align(alloc.align.bytes());
@@ -594,7 +602,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
{
return None;
}
- StatementKind::Intrinsic(ref intrinsic) => match **intrinsic {
+ StatementKind::Intrinsic(intrinsic) => match **intrinsic {
NonDivergingIntrinsic::CopyNonOverlapping(..) => return None,
NonDivergingIntrinsic::Assume(..) => {}
},
diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs
index 0f4696b9337e7..8016c5a3005a2 100644
--- a/src/debuginfo/emit.rs
+++ b/src/debuginfo/emit.rs
@@ -96,7 +96,7 @@ impl WriterRelocate {
if jit_module.declarations().get_function_decl(func_id).name.as_deref()
== Some("rust_eh_personality")
{
- extern "C" {
+ unsafe extern "C" {
fn rust_eh_personality() -> !;
}
rust_eh_personality as *const u8
@@ -222,12 +222,12 @@ impl Writer for WriterRelocate {
gimli::DW_EH_PE_absptr => {
self.relocs.push(DebugReloc {
offset: self.len() as u32,
- size: size.into(),
+ size,
name: DebugRelocName::Symbol(symbol),
addend,
kind: object::RelocationKind::Absolute,
});
- self.write_udata(0, size.into())
+ self.write_udata(0, size)
}
_ => Err(gimli::write::Error::UnsupportedPointerEncoding(eh_pe)),
},
diff --git a/src/debuginfo/gcc_except_table.rs b/src/debuginfo/gcc_except_table.rs
new file mode 100644
index 0000000000000..ff1c6aacd2f98
--- /dev/null
+++ b/src/debuginfo/gcc_except_table.rs
@@ -0,0 +1,271 @@
+use gimli::write::{Address, Writer};
+use gimli::{DW_EH_PE_omit, DW_EH_PE_uleb128, Encoding, LittleEndian};
+
+pub(super) struct GccExceptTable {
+ pub call_sites: CallSiteTable,
+ pub actions: ActionTable,
+ pub type_info: TypeInfoTable,
+}
+
+impl GccExceptTable {
+ pub(super) fn write(
+ &self,
+ w: &mut W,
+ encoding: Encoding,
+ ) -> gimli::write::Result<()> {
+ // lpStartEncoding
+ w.write_u8(DW_EH_PE_omit.0)?;
+ // lpStart (omitted)
+ let type_info_padding = if self.type_info.type_info.is_empty() {
+ // ttypeEncoding
+ w.write_u8(DW_EH_PE_omit.0)?;
+ None
+ } else {
+ // ttypeEncoding
+ w.write_u8(self.type_info.ttype_encoding.0)?;
+
+ // classInfoOffset
+ let class_info_offset_field_offset = w.len() as u64;
+
+ // Note: The offset in classInfoOffset is relative to position right after classInfoOffset
+ // itself.
+ let class_info_offset_no_padding = self.call_sites.encoded_size()
+ + self.actions.encoded_size()
+ + self.type_info.encoded_size(encoding);
+
+ let type_info_is_aligned = |type_info_padding: u64| {
+ (class_info_offset_field_offset
+ + gimli::leb128::write::uleb128_size(
+ class_info_offset_no_padding + type_info_padding,
+ ) as u64
+ + self.call_sites.encoded_size()
+ + self.actions.encoded_size()
+ + type_info_padding)
+ .is_multiple_of(4)
+ };
+
+ let mut type_info_padding = 0;
+ while !type_info_is_aligned(type_info_padding) {
+ type_info_padding += 1;
+ }
+
+ w.write_uleb128(class_info_offset_no_padding + type_info_padding)?;
+
+ Some(type_info_padding)
+ };
+
+ // call site table
+ self.call_sites.write(w)?;
+
+ // action table
+ self.actions.write(w)?;
+
+ // align to 4 bytes
+ if let Some(type_info_padding) = type_info_padding {
+ for _ in 0..type_info_padding {
+ w.write_u8(0)?;
+ }
+ // In this case we calculated the expected padding amount and used it to write the
+ // classInfoOffset field. Assert that the expected value matched the actual value to catch
+ // any inconsistency.
+ assert!(w.len().is_multiple_of(4), "type_info must be aligned to 4 bytes");
+ } else {
+ while !w.len().is_multiple_of(4) {
+ w.write_u8(0)?;
+ }
+ }
+
+ // type_info
+ self.type_info.write(w, encoding)?;
+
+ // exception specs (unused for rust)
+
+ // align to 4 bytes
+ while !w.len().is_multiple_of(4) {
+ w.write_u8(0)?;
+ }
+
+ Ok(())
+ }
+}
+
+pub(super) struct CallSiteTable(pub Vec);
+
+impl CallSiteTable {
+ fn encoded_size(&self) -> u64 {
+ let mut len = LenWriter(0);
+ self.write(&mut len).unwrap();
+ len.0 as u64
+ }
+
+ fn write(&self, w: &mut W) -> gimli::write::Result<()> {
+ let callsite_table_length = self.0.iter().map(|call_site| call_site.encoded_size()).sum();
+
+ // callsiteEncoding
+ w.write_u8(DW_EH_PE_uleb128.0)?;
+ // callsiteTableLength
+ w.write_uleb128(callsite_table_length)?;
+
+ for call_site in &self.0 {
+ call_site.write(w)?;
+ }
+
+ Ok(())
+ }
+}
+
+pub(super) struct CallSite {
+ pub start: u64,
+ pub length: u64,
+ pub landing_pad: u64,
+ pub action_entry: Option,
+}
+
+impl CallSite {
+ fn encoded_size(&self) -> u64 {
+ let mut len = LenWriter(0);
+ self.write(&mut len).unwrap();
+ len.0 as u64
+ }
+
+ fn write(&self, w: &mut W) -> gimli::write::Result<()> {
+ w.write_uleb128(self.start)?;
+ w.write_uleb128(self.length)?;
+ w.write_uleb128(self.landing_pad)?;
+ w.write_uleb128(match self.action_entry {
+ Some(action_offset) => action_offset.0 + 1,
+ None => 0,
+ })?;
+ Ok(())
+ }
+}
+
+pub(super) struct ActionTable {
+ actions: Vec,
+ encoded_length: u64,
+}
+
+impl ActionTable {
+ pub(super) fn new() -> ActionTable {
+ ActionTable { actions: vec![], encoded_length: 0 }
+ }
+
+ pub(super) fn add(&mut self, action: Action) -> ActionOffset {
+ let id = ActionOffset(self.encoded_length);
+ self.encoded_length += action.encoded_size(self.encoded_length);
+ self.actions.push(action);
+ id
+ }
+
+ fn encoded_size(&self) -> u64 {
+ let mut len = LenWriter(0);
+ self.write(&mut len).unwrap();
+ len.0 as u64
+ }
+
+ fn write(&self, w: &mut W) -> gimli::write::Result<()> {
+ let action_table_start = w.len() as u64;
+ for action in &self.actions {
+ action.write(w, w.len() as u64 - action_table_start)?;
+ }
+
+ Ok(())
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(super) struct ActionOffset(u64);
+
+pub(super) struct Action {
+ pub(super) kind: ActionKind,
+ pub(super) next_action: Option,
+}
+
+impl Action {
+ fn encoded_size(&self, action_table_offset: u64) -> u64 {
+ let mut len = LenWriter(0);
+ self.write(&mut len, action_table_offset).unwrap();
+ len.0 as u64
+ }
+
+ fn write(&self, w: &mut W, action_table_offset: u64) -> gimli::write::Result<()> {
+ // ttypeIndex
+ let ttype_index = match self.kind {
+ ActionKind::Catch(type_info_id) => type_info_id.0 as i64 + 1,
+ };
+ w.write_sleb128(ttype_index)?;
+ // actionOffset
+ let action_offset_field_offset =
+ action_table_offset + gimli::leb128::write::sleb128_size(ttype_index) as u64;
+ w.write_sleb128(match self.next_action {
+ Some(next_action_offset) => {
+ next_action_offset.0 as i64 - action_offset_field_offset as i64
+ }
+ None => 0,
+ })?;
+ Ok(())
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(super) enum ActionKind {
+ Catch(TypeInfoId),
+}
+
+pub(super) struct TypeInfoTable {
+ ttype_encoding: gimli::DwEhPe,
+ type_info: Vec,
+}
+
+impl TypeInfoTable {
+ pub(super) fn new(ttype_encoding: gimli::DwEhPe) -> TypeInfoTable {
+ TypeInfoTable { ttype_encoding, type_info: vec![] }
+ }
+
+ pub(super) fn add(&mut self, type_info: Address) -> TypeInfoId {
+ let id = TypeInfoId(self.type_info.len() as u64);
+ self.type_info.push(type_info);
+ id
+ }
+
+ fn encoded_size(&self, encoding: Encoding) -> u64 {
+ let mut len = LenWriter(0);
+ self.write(&mut len, encoding).unwrap();
+ len.0 as u64
+ }
+
+ fn write(&self, w: &mut W, encoding: Encoding) -> gimli::write::Result<()> {
+ for &type_info in self.type_info.iter().rev() {
+ w.write_eh_pointer(type_info, self.ttype_encoding, encoding.address_size)?;
+ }
+
+ Ok(())
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(super) struct TypeInfoId(u64);
+
+struct LenWriter(usize);
+
+impl Writer for LenWriter {
+ type Endian = LittleEndian;
+
+ fn endian(&self) -> LittleEndian {
+ LittleEndian
+ }
+
+ fn len(&self) -> usize {
+ self.0
+ }
+
+ fn write(&mut self, bytes: &[u8]) -> gimli::write::Result<()> {
+ self.0 += bytes.len();
+ Ok(())
+ }
+
+ fn write_at(&mut self, offset: usize, bytes: &[u8]) -> gimli::write::Result<()> {
+ assert!(offset + bytes.len() < self.0);
+ Ok(())
+ }
+}
diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs
index fa7b39c836f64..6fe22f5c6dd9b 100644
--- a/src/debuginfo/line_info.rs
+++ b/src/debuginfo/line_info.rs
@@ -6,9 +6,7 @@ use std::path::{Component, Path};
use cranelift_codegen::MachSrcLoc;
use cranelift_codegen::binemit::CodeOffset;
use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
-use rustc_span::{
- FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm, hygiene,
-};
+use rustc_span::{FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHashAlgorithm, hygiene};
use crate::debuginfo::FunctionDebugContext;
use crate::debuginfo::emit::address_for_func;
@@ -44,21 +42,27 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
}
}
-const MD5_LEN: usize = 16;
-
-fn make_file_info(hash: SourceFileHash) -> Option {
- if hash.kind == SourceFileHashAlgorithm::Md5 {
- let mut buf = [0u8; MD5_LEN];
- buf.copy_from_slice(hash.hash_bytes());
- Some(FileInfo {
- timestamp: 0,
- size: 0,
- md5: buf,
- source: None, // FIXME implement -Zembed-source
- })
- } else {
- None
+fn make_file_info(source_file: &SourceFile, embed_source: bool) -> Option {
+ let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5;
+ let has_source = embed_source && source_file.src.is_some();
+
+ if !has_md5 && !has_source {
+ return None;
+ }
+
+ let mut info = FileInfo::default();
+
+ if has_md5 {
+ info.md5.copy_from_slice(source_file.src_hash.hash_bytes());
}
+
+ if embed_source {
+ if let Some(src) = &source_file.src {
+ info.source = Some(LineString::String(src.as_bytes().to_vec()));
+ }
+ }
+
+ Some(info)
}
impl DebugContext {
@@ -105,15 +109,19 @@ impl DebugContext {
let file_name =
LineString::new(file_name, line_program.encoding(), line_strings);
- let info = make_file_info(source_file.src_hash);
+ let info = make_file_info(source_file, self.embed_source);
- line_program.file_has_md5 &= info.is_some();
+ let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5;
+ line_program.file_has_md5 &= has_md5;
line_program.add_file(file_name, dir_id, info)
}
filename => {
- let dir_id = line_program.default_directory();
+ // For anonymous sources, create an empty directory instead of using the default
+ let empty_dir = LineString::new(b"", line_program.encoding(), line_strings);
+ let dir_id = line_program.add_directory(empty_dir);
+
let dummy_file_name = LineString::new(
- filename.display(self.filename_display_preference).to_string().into_bytes(),
+ filename.prefer_remapped_unconditionally().to_string().into_bytes(),
line_program.encoding(),
line_strings,
);
diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs
index 4c438742f3d22..494002f525c84 100644
--- a/src/debuginfo/mod.rs
+++ b/src/debuginfo/mod.rs
@@ -1,6 +1,7 @@
//! Handling of everything related to debuginfo.
mod emit;
+mod gcc_except_table;
mod line_info;
mod object;
mod types;
@@ -19,12 +20,13 @@ use rustc_codegen_ssa::debuginfo::type_names;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefIdMap;
use rustc_session::Session;
+use rustc_session::config::DebugInfo;
use rustc_span::{FileNameDisplayPreference, SourceFileHash, StableSourceFileId};
use rustc_target::callconv::FnAbi;
pub(crate) use self::emit::{DebugReloc, DebugRelocName};
pub(crate) use self::types::TypeDebugContext;
-pub(crate) use self::unwind::UnwindContext;
+pub(crate) use self::unwind::{EXCEPTION_HANDLER_CATCH, EXCEPTION_HANDLER_CLEANUP, UnwindContext};
use crate::debuginfo::emit::{address_for_data, address_for_func};
use crate::prelude::*;
@@ -43,6 +45,7 @@ pub(crate) struct DebugContext {
array_size_type: UnitEntryId,
filename_display_preference: FileNameDisplayPreference,
+ embed_source: bool,
}
pub(crate) struct FunctionDebugContext {
@@ -52,22 +55,37 @@ pub(crate) struct FunctionDebugContext {
}
impl DebugContext {
- pub(crate) fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, cgu_name: &str) -> Self {
+ pub(crate) fn new(
+ tcx: TyCtxt<'_>,
+ isa: &dyn TargetIsa,
+ force_disable_debuginfo: bool,
+ cgu_name: &str,
+ ) -> Option {
+ if tcx.sess.opts.debuginfo == DebugInfo::None
+ || force_disable_debuginfo
+ || tcx.sess.target.options.is_like_windows
+ {
+ return None;
+ }
+
+ let mut requested_dwarf_version = tcx.sess.dwarf_version();
+ if tcx.sess.target.is_like_darwin && requested_dwarf_version > 4 {
+ // Apple’s shipped debuggers still expect DWARF <= 4 by default.
+ // Stay on v4 unless the user explicitly opts into a feature that
+ // only works with v5 (e.g. -Zembed-source).
+ if !tcx.sess.opts.unstable_opts.embed_source {
+ requested_dwarf_version = 4;
+ }
+ }
+
let encoding = Encoding {
format: Format::Dwarf32,
- // FIXME this should be configurable
- // macOS doesn't seem to support DWARF > 3
- // 5 version is required for md5 file hash
- version: if tcx.sess.target.is_like_darwin {
- 3
- } else {
- // FIXME change to version 5 once the gdb and lldb shipping with the latest debian
- // support it.
- 4
- },
+ version: requested_dwarf_version as u16,
address_size: isa.frontend_config().pointer_bytes(),
};
+ let embed_source = tcx.sess.opts.unstable_opts.embed_source && encoding.version >= 5;
+
let endian = match isa.endianness() {
Endianness::Little => RunTimeEndian::Little,
Endianness::Big => RunTimeEndian::Big,
@@ -106,10 +124,14 @@ impl DebugContext {
encoding,
LineEncoding::default(),
LineString::new(comp_dir.as_bytes(), encoding, &mut dwarf.line_strings),
+ None,
LineString::new(name.as_bytes(), encoding, &mut dwarf.line_strings),
file_info,
);
line_program.file_has_md5 = file_has_md5;
+ if embed_source {
+ line_program.file_has_source = true;
+ }
dwarf.unit.line_program = line_program;
@@ -145,7 +167,7 @@ impl DebugContext {
AttributeValue::Udata(isa.frontend_config().pointer_bytes().into()),
);
- DebugContext {
+ Some(DebugContext {
endian,
dwarf,
unit_range_list: RangeList(Vec::new()),
@@ -154,7 +176,8 @@ impl DebugContext {
namespace_map: DefIdMap::default(),
array_size_type,
filename_display_preference,
- }
+ embed_source,
+ })
}
fn item_namespace(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> UnitEntryId {
diff --git a/src/debuginfo/types.rs b/src/debuginfo/types.rs
index 0d49f32373caa..a292429cdfad9 100644
--- a/src/debuginfo/types.rs
+++ b/src/debuginfo/types.rs
@@ -56,7 +56,7 @@ impl DebugContext {
// ty::FnDef(..) | ty::FnPtr(..)
// ty::Closure(..)
// ty::Adt(def, ..)
- ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, *components),
+ ty::Tuple(components) => self.tuple_type(tcx, type_dbg, ty, components),
// ty::Param(_)
// FIXME implement remaining types and add unreachable!() to the fallback branch
_ => self.placeholder_for_type(tcx, type_dbg, ty),
@@ -152,7 +152,7 @@ impl DebugContext {
components: &'tcx [Ty<'tcx>],
) -> UnitEntryId {
let components = components
- .into_iter()
+ .iter()
.map(|&ty| (ty, self.debug_type(tcx, type_dbg, ty)))
.collect::>();
diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs
index 74b82a7139ab0..ecaf88a26259e 100644
--- a/src/debuginfo/unwind.rs
+++ b/src/debuginfo/unwind.rs
@@ -1,15 +1,23 @@
//! Unwind info generation (`.eh_frame`)
+use cranelift_codegen::FinalizedMachExceptionHandler;
use cranelift_codegen::ir::Endianness;
use cranelift_codegen::isa::unwind::UnwindInfo;
+use cranelift_module::DataId;
use cranelift_object::ObjectProduct;
-use gimli::RunTimeEndian;
-use gimli::write::{CieId, EhFrame, FrameTable, Section};
+use gimli::write::{Address, CieId, EhFrame, FrameTable, Section};
+use gimli::{Encoding, Format, RunTimeEndian};
-use super::emit::address_for_func;
+use super::emit::{DebugRelocName, address_for_data, address_for_func};
+use super::gcc_except_table::{
+ Action, ActionKind, ActionTable, CallSite, CallSiteTable, GccExceptTable, TypeInfoTable,
+};
use super::object::WriteDebugInfo;
use crate::prelude::*;
+pub(crate) const EXCEPTION_HANDLER_CLEANUP: u32 = 0;
+pub(crate) const EXCEPTION_HANDLER_CATCH: u32 = 1;
+
pub(crate) struct UnwindContext {
endian: RunTimeEndian,
frame_table: FrameTable,
@@ -25,10 +33,79 @@ impl UnwindContext {
let mut frame_table = FrameTable::default();
let cie_id = if let Some(mut cie) = module.isa().create_systemv_cie() {
- if pic_eh_frame {
- cie.fde_address_encoding =
- gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0);
+ let ptr_encoding = if pic_eh_frame {
+ gimli::DwEhPe(gimli::DW_EH_PE_pcrel.0 | gimli::DW_EH_PE_sdata4.0)
+ } else {
+ gimli::DW_EH_PE_absptr
+ };
+
+ cie.fde_address_encoding = ptr_encoding;
+
+ // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204
+ if cfg!(feature = "unwinding") {
+ let code_ptr_encoding = if pic_eh_frame {
+ if module.isa().triple().architecture == target_lexicon::Architecture::X86_64 {
+ gimli::DwEhPe(
+ gimli::DW_EH_PE_indirect.0
+ | gimli::DW_EH_PE_pcrel.0
+ | gimli::DW_EH_PE_sdata4.0,
+ )
+ } else if let target_lexicon::Architecture::Aarch64(_) =
+ module.isa().triple().architecture
+ {
+ gimli::DwEhPe(
+ gimli::DW_EH_PE_indirect.0
+ | gimli::DW_EH_PE_pcrel.0
+ | gimli::DW_EH_PE_sdata8.0,
+ )
+ } else {
+ todo!()
+ }
+ } else {
+ gimli::DwEhPe(gimli::DW_EH_PE_indirect.0 | gimli::DW_EH_PE_absptr.0)
+ };
+
+ cie.lsda_encoding = Some(ptr_encoding);
+
+ // FIXME use eh_personality lang item instead
+ let personality = module
+ .declare_function(
+ "rust_eh_personality",
+ Linkage::Import,
+ &Signature {
+ params: vec![
+ AbiParam::new(types::I32),
+ AbiParam::new(types::I32),
+ AbiParam::new(types::I64),
+ AbiParam::new(module.target_config().pointer_type()),
+ AbiParam::new(module.target_config().pointer_type()),
+ ],
+ returns: vec![AbiParam::new(types::I32)],
+ call_conv: module.target_config().default_call_conv,
+ },
+ )
+ .unwrap();
+
+ // Use indirection here to support PIC the case where rust_eh_personality is defined in
+ // another DSO.
+ let personality_ref = module
+ .declare_data("DW.ref.rust_eh_personality", Linkage::Local, false, false)
+ .unwrap();
+
+ let mut personality_ref_data = DataDescription::new();
+ // Note: Must not use define_zeroinit. The unwinder can't handle this being in the .bss
+ // section.
+ let pointer_bytes = usize::from(module.target_config().pointer_bytes());
+ personality_ref_data.define(vec![0; pointer_bytes].into_boxed_slice());
+ let personality_func_ref =
+ module.declare_func_in_data(personality, &mut personality_ref_data);
+ personality_ref_data.write_function_addr(0, personality_func_ref);
+
+ module.define_data(personality_ref, &personality_ref_data).unwrap();
+
+ cie.personality = Some((code_ptr_encoding, address_for_data(personality_ref)));
}
+
Some(frame_table.add_cie(cie))
} else {
None
@@ -63,8 +140,100 @@ impl UnwindContext {
match unwind_info {
UnwindInfo::SystemV(unwind_info) => {
- self.frame_table
- .add_fde(self.cie_id.unwrap(), unwind_info.to_fde(address_for_func(func_id)));
+ let mut fde = unwind_info.to_fde(address_for_func(func_id));
+
+ // FIXME only add personality function and lsda when necessary: https://github.com/rust-lang/rust/blob/1f76d219c906f0112bb1872f33aa977164c53fa6/compiler/rustc_codegen_ssa/src/mir/mod.rs#L200-L204
+ if cfg!(feature = "unwinding") {
+ // FIXME use unique symbol name derived from function name
+ let lsda = module.declare_anonymous_data(false, false).unwrap();
+
+ let encoding = Encoding {
+ format: Format::Dwarf32,
+ version: 1,
+ address_size: module.isa().frontend_config().pointer_bytes(),
+ };
+
+ let mut gcc_except_table_data = GccExceptTable {
+ call_sites: CallSiteTable(vec![]),
+ actions: ActionTable::new(),
+ type_info: TypeInfoTable::new(gimli::DW_EH_PE_udata4),
+ };
+
+ let catch_type = gcc_except_table_data.type_info.add(Address::Constant(0));
+ let catch_action = gcc_except_table_data
+ .actions
+ .add(Action { kind: ActionKind::Catch(catch_type), next_action: None });
+
+ for call_site in context.compiled_code().unwrap().buffer.call_sites() {
+ if call_site.exception_handlers.is_empty() {
+ gcc_except_table_data.call_sites.0.push(CallSite {
+ start: u64::from(call_site.ret_addr - 1),
+ length: 1,
+ landing_pad: 0,
+ action_entry: None,
+ });
+ }
+ for &handler in call_site.exception_handlers {
+ match handler {
+ FinalizedMachExceptionHandler::Tag(tag, landingpad) => {
+ match tag.as_u32() {
+ EXCEPTION_HANDLER_CLEANUP => {
+ gcc_except_table_data.call_sites.0.push(CallSite {
+ start: u64::from(call_site.ret_addr - 1),
+ length: 1,
+ landing_pad: u64::from(landingpad),
+ action_entry: None,
+ })
+ }
+ EXCEPTION_HANDLER_CATCH => {
+ gcc_except_table_data.call_sites.0.push(CallSite {
+ start: u64::from(call_site.ret_addr - 1),
+ length: 1,
+ landing_pad: u64::from(landingpad),
+ action_entry: Some(catch_action),
+ })
+ }
+ _ => unreachable!(),
+ }
+ }
+ _ => unreachable!(),
+ }
+ }
+ }
+
+ let mut gcc_except_table = super::emit::WriterRelocate::new(self.endian);
+
+ gcc_except_table_data.write(&mut gcc_except_table, encoding).unwrap();
+
+ let mut data = DataDescription::new();
+ data.define(gcc_except_table.writer.into_vec().into_boxed_slice());
+ data.set_segment_section("", ".gcc_except_table");
+
+ for reloc in &gcc_except_table.relocs {
+ match reloc.name {
+ DebugRelocName::Section(_id) => unreachable!(),
+ DebugRelocName::Symbol(id) => {
+ let id = id.try_into().unwrap();
+ if id & 1 << 31 == 0 {
+ let func_ref = module
+ .declare_func_in_data(FuncId::from_u32(id), &mut data);
+ data.write_function_addr(reloc.offset, func_ref);
+ } else {
+ let gv = module.declare_data_in_data(
+ DataId::from_u32(id & !(1 << 31)),
+ &mut data,
+ );
+ data.write_data_addr(reloc.offset, gv, 0);
+ }
+ }
+ };
+ }
+
+ module.define_data(lsda, &data).unwrap();
+ fde.lsda = Some(address_for_data(lsda));
+ }
+
+ self.frame_table.add_fde(self.cie_id.unwrap(), fde);
}
UnwindInfo::WindowsX64(_) | UnwindInfo::WindowsArm64(_) => {
// Windows does not have debug info for its unwind info.
@@ -116,7 +285,7 @@ impl UnwindContext {
// Everything after this line up to the end of the file is loosely based on
// https://github.com/bytecodealliance/wasmtime/blob/4471a82b0c540ff48960eca6757ccce5b1b5c3e4/crates/jit/src/unwind/systemv.rs
#[cfg(target_os = "macos")]
- {
+ unsafe {
// On macOS, `__register_frame` takes a pointer to a single FDE
let start = eh_frame.as_ptr();
let end = start.add(eh_frame.len());
@@ -138,12 +307,12 @@ impl UnwindContext {
#[cfg(not(target_os = "macos"))]
{
// On other platforms, `__register_frame` will walk the FDEs until an entry of length 0
- __register_frame(eh_frame.as_ptr());
+ unsafe { __register_frame(eh_frame.as_ptr()) };
}
}
}
-extern "C" {
+unsafe extern "C" {
// libunwind import
fn __register_frame(fde: *const u8);
}
diff --git a/src/driver/aot.rs b/src/driver/aot.rs
index 7bf1efc10653f..760e23f2171bc 100644
--- a/src/driver/aot.rs
+++ b/src/driver/aot.rs
@@ -24,9 +24,8 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::mono::{CodegenUnit, MonoItem, MonoItemData, Visibility};
use rustc_session::Session;
-use rustc_session::config::{DebugInfo, OutFileName, OutputFilenames, OutputType};
+use rustc_session::config::{OutFileName, OutputFilenames, OutputType};
-use crate::CodegenCx;
use crate::base::CodegenedFunction;
use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken};
use crate::debuginfo::TypeDebugContext;
@@ -98,8 +97,8 @@ impl OngoingCodegen {
sess,
&module_regular.name,
&[
- ("o", &module_regular.object.as_ref().unwrap()),
- ("asm.o", &module_global_asm.object.as_ref().unwrap()),
+ ("o", module_regular.object.as_ref().unwrap()),
+ ("asm.o", module_global_asm.object.as_ref().unwrap()),
],
&[],
)
@@ -107,7 +106,7 @@ impl OngoingCodegen {
rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir(
sess,
&module_regular.name,
- &[("o", &module_regular.object.as_ref().unwrap())],
+ &[("o", module_regular.object.as_ref().unwrap())],
&[],
)
};
@@ -309,7 +308,7 @@ fn produce_final_output_artifacts(
module.for_each_output(|path, ty| {
if sess.opts.output_types.contains_key(&ty) {
let descr = ty.shorthand();
- sess.dcx().emit_artifact_notification(&path, descr);
+ sess.dcx().emit_artifact_notification(path, descr);
}
});
}
@@ -451,8 +450,8 @@ fn reuse_workproduct_for_cgu(
tcx.sess.invocation_temp.as_deref(),
);
let source_file_regular = rustc_incremental::in_incr_comp_dir_sess(
- &tcx.sess,
- &work_product.saved_files.get("o").expect("no saved object file in work product"),
+ tcx.sess,
+ work_product.saved_files.get("o").expect("no saved object file in work product"),
);
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_regular, &obj_out_regular) {
@@ -467,7 +466,7 @@ fn reuse_workproduct_for_cgu(
let obj_out_global_asm =
crate::global_asm::add_file_stem_postfix(obj_out_regular.clone(), ".asm");
let source_file_global_asm = if let Some(asm_o) = work_product.saved_files.get("asm.o") {
- let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(&tcx.sess, asm_o);
+ let source_file_global_asm = rustc_incremental::in_incr_comp_dir_sess(tcx.sess, asm_o);
if let Err(err) = rustc_fs_util::link_or_copy(&source_file_global_asm, &obj_out_global_asm)
{
return Err(format!(
@@ -511,18 +510,14 @@ fn codegen_cgu_content(
tcx: TyCtxt<'_>,
module: &mut dyn Module,
cgu_name: rustc_span::Symbol,
-) -> (CodegenCx, Vec) {
+) -> (Option, Vec, String) {
let _timer = tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str());
let cgu = tcx.codegen_unit(cgu_name);
let mono_items = cgu.items_in_deterministic_order(tcx);
- let mut cx = crate::CodegenCx::new(
- tcx,
- module.isa(),
- tcx.sess.opts.debuginfo != DebugInfo::None,
- cgu_name,
- );
+ let mut debug_context = DebugContext::new(tcx, module.isa(), false, cgu_name.as_str());
+ let mut global_asm = String::new();
let mut type_dbg = TypeDebugContext::default();
super::predefine_mono_items(tcx, module, &mono_items);
let mut codegened_functions = vec![];
@@ -532,7 +527,7 @@ fn codegen_cgu_content(
let flags = tcx.codegen_instance_attrs(instance.def).flags;
if flags.contains(CodegenFnAttrFlags::NAKED) {
rustc_codegen_ssa::mir::naked_asm::codegen_naked_asm(
- &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm },
+ &mut GlobalAsmContext { tcx, global_asm: &mut global_asm },
instance,
MonoItemData {
linkage: RLinkage::External,
@@ -548,7 +543,8 @@ fn codegen_cgu_content(
}
let codegened_function = crate::base::codegen_fn(
tcx,
- &mut cx,
+ cgu_name,
+ debug_context.as_mut(),
&mut type_dbg,
Function::new(),
module,
@@ -558,13 +554,13 @@ fn codegen_cgu_content(
}
MonoItem::Static(def_id) => {
let data_id = crate::constant::codegen_static(tcx, module, def_id);
- if let Some(debug_context) = &mut cx.debug_context {
+ if let Some(debug_context) = debug_context.as_mut() {
debug_context.define_static(tcx, &mut type_dbg, def_id, data_id);
}
}
MonoItem::GlobalAsm(item_id) => {
rustc_codegen_ssa::base::codegen_global_asm(
- &mut GlobalAsmContext { tcx, global_asm: &mut cx.global_asm },
+ &mut GlobalAsmContext { tcx, global_asm: &mut global_asm },
item_id,
);
}
@@ -572,7 +568,7 @@ fn codegen_cgu_content(
}
crate::main_shim::maybe_create_entry_wrapper(tcx, module, false, cgu.is_primary());
- (cx, codegened_functions)
+ (debug_context, codegened_functions, global_asm)
}
fn module_codegen(
@@ -585,13 +581,17 @@ fn module_codegen(
) -> OngoingModuleCodegen {
let mut module = make_module(tcx.sess, cgu_name.as_str().to_string());
- let (mut cx, codegened_functions) = codegen_cgu_content(tcx, &mut module, cgu_name);
+ let (mut debug_context, codegened_functions, mut global_asm) =
+ codegen_cgu_content(tcx, &mut module, cgu_name);
let cgu_name = cgu_name.as_str().to_owned();
let producer = crate::debuginfo::producer(tcx.sess);
let profiler = tcx.prof.clone();
+ let invocation_temp = tcx.sess.invocation_temp.clone();
+ let output_filenames = tcx.output_filenames(()).clone();
+ let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess);
OngoingModuleCodegen::Async(std::thread::spawn(move || {
profiler.clone().generic_activity_with_arg("compile functions", &*cgu_name).run(|| {
@@ -602,10 +602,13 @@ fn module_codegen(
let mut cached_context = Context::new();
for codegened_func in codegened_functions {
crate::base::compile_fn(
- &mut cx,
&profiler,
+ &output_filenames,
+ should_write_ir,
&mut cached_context,
&mut module,
+ debug_context.as_mut(),
+ &mut global_asm,
codegened_func,
);
}
@@ -616,8 +619,8 @@ fn module_codegen(
crate::global_asm::compile_global_asm(
&global_asm_config,
&cgu_name,
- &cx.global_asm,
- cx.invocation_temp.as_deref(),
+ global_asm,
+ invocation_temp.as_deref(),
)
})?;
@@ -625,11 +628,11 @@ fn module_codegen(
profiler.generic_activity_with_arg("write object file", &*cgu_name).run(|| {
emit_cgu(
&global_asm_config.output_filenames,
- cx.invocation_temp.as_deref(),
+ invocation_temp.as_deref(),
&profiler,
cgu_name,
module,
- cx.debug_context,
+ debug_context,
global_asm_object_file,
&producer,
)
@@ -681,7 +684,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box {
// Calculate the CGU reuse
let cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
- cgus.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::>()
+ cgus.iter().map(|cgu| determine_cgu_reuse(tcx, cgu)).collect::>()
});
rustc_codegen_ssa::assert_module_sources::assert_module_sources(tcx, &|cgu_reuse_tracker| {
@@ -695,7 +698,7 @@ pub(crate) fn run_aot(tcx: TyCtxt<'_>) -> Box {
let disable_incr_cache = disable_incr_cache();
let (todo_cgus, done_cgus) =
- cgus.into_iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] {
+ cgus.iter().enumerate().partition::, _>(|&(i, _)| match cgu_reuse[i] {
_ if disable_incr_cache => true,
CguReuse::No => true,
CguReuse::PreLto | CguReuse::PostLto => false,
diff --git a/src/driver/jit.rs b/src/driver/jit.rs
index fec46bf26975d..9dba46363936f 100644
--- a/src/driver/jit.rs
+++ b/src/driver/jit.rs
@@ -9,14 +9,14 @@ use rustc_codegen_ssa::CrateInfo;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::mono::MonoItem;
use rustc_session::Session;
+use rustc_session::config::OutputFilenames;
use rustc_span::sym;
-use crate::CodegenCx;
use crate::debuginfo::TypeDebugContext;
use crate::prelude::*;
use crate::unwind_module::UnwindModule;
-fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) {
+fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, Option) {
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
let isa = crate::build_isa(tcx.sess, true);
@@ -25,7 +25,7 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) {
jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info));
let mut jit_module = UnwindModule::new(JITModule::new(jit_builder), false);
- let cx = crate::CodegenCx::new(tcx, jit_module.isa(), false, sym::dummy_cgu_name);
+ let cx = DebugContext::new(tcx, jit_module.isa(), false, "dummy_cgu_name");
crate::allocator::codegen(tcx, &mut jit_module);
@@ -33,13 +33,13 @@ fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule, CodegenCx) {
}
pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! {
- // FIXME error on check mode or crate types other than bin in CodegenBackend::init()
-
if !tcx.crate_types().contains(&rustc_session::config::CrateType::Executable) {
tcx.dcx().fatal("can't jit non-executable crate");
}
- let (mut jit_module, mut cx) = create_jit_module(tcx);
+ let output_filenames = tcx.output_filenames(());
+ let should_write_ir = crate::pretty_clif::should_write_ir(tcx.sess);
+ let (mut jit_module, mut debug_context) = create_jit_module(tcx);
let mut cached_context = Context::new();
let cgus = tcx.collect_and_partition_mono_items(()).codegen_units;
@@ -58,7 +58,9 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! {
MonoItem::Fn(inst) => {
codegen_and_compile_fn(
tcx,
- &mut cx,
+ &output_filenames,
+ should_write_ir,
+ debug_context.as_mut(),
&mut cached_context,
&mut jit_module,
inst,
@@ -75,10 +77,6 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! {
}
});
- if !cx.global_asm.is_empty() {
- tcx.dcx().fatal("Inline asm is not supported in JIT mode");
- }
-
crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, true, true);
tcx.dcx().abort_if_errors();
@@ -120,7 +118,9 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec) -> ! {
fn codegen_and_compile_fn<'tcx>(
tcx: TyCtxt<'tcx>,
- cx: &mut crate::CodegenCx,
+ output_filenames: &OutputFilenames,
+ should_write_ir: bool,
+ mut debug_context: Option<&mut DebugContext>,
cached_context: &mut Context,
module: &mut dyn Module,
instance: Instance<'tcx>,
@@ -141,13 +141,28 @@ fn codegen_and_compile_fn<'tcx>(
let cached_func = std::mem::replace(&mut cached_context.func, Function::new());
let codegened_func = crate::base::codegen_fn(
tcx,
- cx,
+ sym::dummy_cgu_name,
+ debug_context.as_deref_mut(),
&mut TypeDebugContext::default(),
cached_func,
module,
instance,
);
- crate::base::compile_fn(cx, &tcx.prof, cached_context, module, codegened_func);
+
+ let mut global_asm = String::new();
+ crate::base::compile_fn(
+ &tcx.prof,
+ output_filenames,
+ should_write_ir,
+ cached_context,
+ module,
+ debug_context.as_deref_mut(),
+ &mut global_asm,
+ codegened_func,
+ );
+ if !global_asm.is_empty() {
+ tcx.dcx().fatal("Inline asm is not supported in JIT mode");
+ }
});
}
diff --git a/src/driver/mod.rs b/src/driver/mod.rs
index 8f83c30b598d8..9f2b7b4b09f22 100644
--- a/src/driver/mod.rs
+++ b/src/driver/mod.rs
@@ -38,16 +38,12 @@ fn predefine_mono_items<'tcx>(
.codegen_instance_attrs(instance.def)
.flags
.contains(CodegenFnAttrFlags::NAKED);
- module
- .declare_function(
- name,
- // Naked functions are defined in a separate object
- // file from the codegen unit rustc expects them to
- // be defined in.
- if is_naked { Linkage::Import } else { linkage },
- &sig,
- )
- .unwrap();
+ if is_naked {
+ // Naked functions are defined in a separate object
+ // file, so they can be declared on the fly.
+ continue;
+ }
+ module.declare_function(name, linkage, &sig).unwrap();
}
MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {}
}
diff --git a/src/global_asm.rs b/src/global_asm.rs
index 1306c6aa5179c..8d8cdb14dbc6b 100644
--- a/src/global_asm.rs
+++ b/src/global_asm.rs
@@ -171,7 +171,7 @@ impl GlobalAsmConfig {
pub(crate) fn compile_global_asm(
config: &GlobalAsmConfig,
cgu_name: &str,
- global_asm: &str,
+ global_asm: String,
invocation_temp: Option<&str>,
) -> Result