diff --git a/compiler/rustc_codegen_cranelift/.cirrus.yml b/compiler/rustc_codegen_cranelift/.cirrus.yml index ee5de8b42f465..3ed89beceb7fe 100644 --- a/compiler/rustc_codegen_cranelift/.cirrus.yml +++ b/compiler/rustc_codegen_cranelift/.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/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml index 6ad041a796c92..170c7126c296b 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml +++ b/compiler/rustc_codegen_cranelift/.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/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml index d92e0fdce99a8..0930b924d1773 100644 --- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml +++ b/compiler/rustc_codegen_cranelift/.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/compiler/rustc_codegen_cranelift/.vscode/settings.json b/compiler/rustc_codegen_cranelift/.vscode/settings.json index 68bd93aea8901..2a3ec5e1c905a 100644 --- a/compiler/rustc_codegen_cranelift/.vscode/settings.json +++ b/compiler/rustc_codegen_cranelift/.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/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index b893a2be9a2cb..09b6c6b87c300 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index 9066e4dbbb528..f2001123e579d 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md index 4d1e4d843ffeb..c5436cf67c80a 100644 --- a/compiler/rustc_codegen_cranelift/Readme.md +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs b/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs index 43025137bc6bb..5a393a217c278 100644 --- a/compiler/rustc_codegen_cranelift/build_system/abi_cafe.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/bench.rs b/compiler/rustc_codegen_cranelift/build_system/bench.rs index 8359b7b527903..192cb499536f1 100644 --- a/compiler/rustc_codegen_cranelift/build_system/bench.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs index bf7cf1c0a346f..b9fa0ff2d94c3 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs index 00955998e703d..70504ee8007d2 100644 --- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs +++ b/compiler/rustc_codegen_cranelift/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,14 @@ 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"); + .arg("-Cstrip=debuginfo") + .arg("--check-cfg=cfg(support_panic_unwind)"); + 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 +82,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 +97,7 @@ pub(crate) fn build_sysroot( }, &cg_clif_dylib_path, sysroot_kind, + panic_unwind_support, ) .install_into_sysroot(dist_dir); } @@ -134,19 +141,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 +196,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 +226,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 +267,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/compiler/rustc_codegen_cranelift/build_system/main.rs b/compiler/rustc_codegen_cranelift/build_system/main.rs index 3ff9751a3ef2d..fc00931283002 100644 --- a/compiler/rustc_codegen_cranelift/build_system/main.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs b/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs index 5b71504e90a4f..2fa827498de93 100644 --- a/compiler/rustc_codegen_cranelift/build_system/rustc_info.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index eec89c026b26a..dd8cf929bc2f0 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/usage.txt b/compiler/rustc_codegen_cranelift/build_system/usage.txt index 5c333fe2db596..6c98087e52399 100644 --- a/compiler/rustc_codegen_cranelift/build_system/usage.txt +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs index d9807155a3d5d..3266aa0ce8b64 100644 --- a/compiler/rustc_codegen_cranelift/build_system/utils.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/config.txt b/compiler/rustc_codegen_cranelift/config.txt index 6ae4767adfdf5..85748a4f8a789 100644 --- a/compiler/rustc_codegen_cranelift/config.txt +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/example/example.rs b/compiler/rustc_codegen_cranelift/example/example.rs index 769d262b9ebb5..2e15f06f8fc7e 100644 --- a/compiler/rustc_codegen_cranelift/example/example.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index 304d0d648561e..b522ea1937166 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs b/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs index a9388814a7f59..10549cd2a41e2 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core_hello_world.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/example/neon.rs b/compiler/rustc_codegen_cranelift/example/neon.rs index 704f866e2c4f5..fb3e10a41c025 100644 --- a/compiler/rustc_codegen_cranelift/example/neon.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/example/raw-dylib.rs b/compiler/rustc_codegen_cranelift/example/raw-dylib.rs index 4711884f76af6..5f5bde7d4dc5e 100644 --- a/compiler/rustc_codegen_cranelift/example/raw-dylib.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index 5d83066cffb88..c569ef0ef8297 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch b/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch index 357b8d306cf6a..853acab2773b5 100644 --- a/compiler/rustc_codegen_cranelift/patches/0028-sysroot_tests-Disable-long-running-tests.patch +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain index 150bb562f74a7..17c2cc5ac6609 100644 --- a/compiler/rustc_codegen_cranelift/rust-toolchain +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs b/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs index e6c63bf5e6508..e391cc7f75a92 100644 --- a/compiler/rustc_codegen_cranelift/scripts/cargo-clif.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs index 528031af82a84..15d929d0f5a51 100644 --- a/compiler/rustc_codegen_cranelift/scripts/rustc-clif.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs b/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs index 6ebe060d8bbd1..dc5bef18cda8c 100644 --- a/compiler/rustc_codegen_cranelift/scripts/rustdoc-clif.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/scripts/rustup.sh b/compiler/rustc_codegen_cranelift/scripts/rustup.sh index 152c243aa6adc..fdfd03029b160 100755 --- a/compiler/rustc_codegen_cranelift/scripts/rustup.sh +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh b/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh index 492f4dc445277..c16cb4e538fe4 100644 --- a/compiler/rustc_codegen_cranelift/scripts/setup_rust_fork.sh +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh b/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh index 62f1cc6a8933b..b5af585a732e3 100755 --- a/compiler/rustc_codegen_cranelift/scripts/test_rustc_tests.sh +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index d7f17795815de..9ac282df5b5ea 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs b/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs index 7a909a740b054..44b63aa95f83c 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 7d50548b40262..0d3b38d52c8da 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs b/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs index c0f6d9d853db2..91f7220667ff9 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_f16_f128.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index de3d2f31af103..38676eaac3d56 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs index 6eea19211fa1b..ca9157daae584 100644 --- a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/config.rs b/compiler/rustc_codegen_cranelift/src/config.rs index d328b33a704f5..31bc0374460f4 100644 --- a/compiler/rustc_codegen_cranelift/src/config.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 3243e12e69999..2b65b82906818 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs index 0f4696b9337e7..8016c5a3005a2 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/emit.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/debuginfo/gcc_except_table.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/gcc_except_table.rs new file mode 100644 index 0000000000000..ff1c6aacd2f98 --- /dev/null +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index fa7b39c836f64..6fe22f5c6dd9b 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index 4c438742f3d22..494002f525c84 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs index 0d49f32373caa..a292429cdfad9 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs index 74b82a7139ab0..ecaf88a26259e 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/unwind.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs index 7bf1efc10653f..760e23f2171bc 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/driver/jit.rs b/compiler/rustc_codegen_cranelift/src/driver/jit.rs index fec46bf26975d..9dba46363936f 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/jit.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/driver/mod.rs b/compiler/rustc_codegen_cranelift/src/driver/mod.rs index 8f83c30b598d8..9f2b7b4b09f22 100644 --- a/compiler/rustc_codegen_cranelift/src/driver/mod.rs +++ b/compiler/rustc_codegen_cranelift/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/compiler/rustc_codegen_cranelift/src/global_asm.rs b/compiler/rustc_codegen_cranelift/src/global_asm.rs index 1306c6aa5179c..8d8cdb14dbc6b 100644 --- a/compiler/rustc_codegen_cranelift/src/global_asm.rs +++ b/compiler/rustc_codegen_cranelift/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, String> { if global_asm.is_empty() { @@ -205,6 +205,9 @@ pub(crate) fn compile_global_asm( return Err(format!("Failed to assemble `{}`", global_asm)); } } else { + // Escape { and } + let global_asm = global_asm.replace('{', "{{").replace('}', "}}"); + let mut child = Command::new(std::env::current_exe().unwrap()) // Avoid a warning about the jobserver fd not being passed .env_remove("CARGO_MAKEFLAGS") diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index 120d6ff9e38e0..08cabe9d695c3 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -7,6 +7,7 @@ use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::LangItem; use rustc_span::sym; use rustc_target::asm::*; +use rustc_target::spec::Arch; use target_lexicon::BinaryFormat; use crate::prelude::*; @@ -51,6 +52,26 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( return; } + if fx.tcx.sess.target.arch == Arch::S390x + && template.len() == 3 + && template[0] == InlineAsmTemplatePiece::String("stfle 0(".into()) + && let InlineAsmTemplatePiece::Placeholder { operand_idx: 0, modifier: None, span: _ } = + template[1] + && template[2] == InlineAsmTemplatePiece::String(")".into()) + { + // FIXME no inline asm support for s390x yet, but stdarch needs it for feature detection + match destination { + Some(destination) => { + let destination_block = fx.get_block(destination); + fx.bcx.ins().jump(destination_block, &[]); + } + None => { + fx.bcx.ins().trap(TrapCode::user(1 /* unreachable */).unwrap()); + } + } + return; + } + let operands = operands .iter() .map(|operand| match *operand { @@ -103,11 +124,12 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>( // be exported from the main codegen unit and may thus be unreachable from the // object file created by an external assembler. let wrapper_name = format!( - "__inline_asm_{}_wrapper_n{}", - fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.cx.inline_asm_index + "{}__inline_asm_{}_wrapper_n{}", + fx.symbol_name, + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.inline_asm_index, ); - fx.cx.inline_asm_index += 1; + fx.inline_asm_index += 1; let sig = get_function_sig(fx.tcx, fx.target_config.default_call_conv, instance); create_wrapper_function(fx.module, sig, &wrapper_name, symbol.name); @@ -166,14 +188,15 @@ pub(crate) fn codegen_inline_asm_inner<'tcx>( asm_gen.allocate_stack_slots(); let asm_name = format!( - "__inline_asm_{}_n{}", - fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"), - fx.cx.inline_asm_index + "{}__inline_asm_{}_n{}", + fx.symbol_name, + fx.cgu_name.as_str().replace('.', "__").replace('-', "_"), + fx.inline_asm_index, ); - fx.cx.inline_asm_index += 1; + fx.inline_asm_index += 1; let generated_asm = asm_gen.generate_asm_wrapper(&asm_name); - fx.cx.global_asm.push_str(&generated_asm); + fx.inline_asm.push_str(&generated_asm); let mut inputs = Vec::new(); let mut outputs = Vec::new(); @@ -546,20 +569,6 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> { .emit(&mut generated_asm, InlineAsmArch::X86_64, *modifier) .unwrap(), }, - InlineAsmArch::AArch64 => match reg { - InlineAsmReg::AArch64(reg) if reg.vreg_index().is_some() => { - // rustc emits v0 rather than q0 - reg.emit( - &mut generated_asm, - InlineAsmArch::AArch64, - Some(modifier.unwrap_or('q')), - ) - .unwrap() - } - _ => reg - .emit(&mut generated_asm, InlineAsmArch::AArch64, *modifier) - .unwrap(), - }, _ => reg.emit(&mut generated_asm, self.arch, *modifier).unwrap(), } } @@ -827,6 +836,7 @@ fn call_inline_asm<'tcx>( } let stack_slot_addr = stack_slot.get_addr(fx); + // FIXME use try_call once unwinding inline assembly is supported fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]); for (offset, place) in outputs { diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index ed40901ac9b8b..a78c6e0a4e7ac 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -3,7 +3,7 @@ macro_rules! intrinsic_args { ($fx:expr, $args:expr => ($($arg:tt),*); $intrinsic:expr) => { - #[allow(unused_parens)] + #[allow(unused_parens, clippy::unused_unit)] let ($($arg),*) = if let [$($arg),*] = $args { ($(codegen_operand($fx, &($arg).node)),*) } else { @@ -17,17 +17,21 @@ mod llvm_aarch64; mod llvm_x86; mod simd; -use cranelift_codegen::ir::AtomicRmwOp; +use cranelift_codegen::ir::{ + AtomicRmwOp, BlockArg, ExceptionTableData, ExceptionTableItem, ExceptionTag, +}; use rustc_middle::ty; use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_span::source_map::Spanned; use rustc_span::{Symbol, sym}; +use rustc_target::spec::PanicStrategy; pub(crate) use self::llvm::codegen_llvm_intrinsic_call; use crate::cast::clif_intcast; use crate::codegen_f16_f128; +use crate::debuginfo::EXCEPTION_HANDLER_CATCH; use crate::prelude::*; fn bug_on_incorrect_arg_count(intrinsic: impl std::fmt::Display) -> ! { @@ -479,7 +483,7 @@ fn codegen_float_intrinsic_call<'tcx>( }; let input_tys: Vec<_> = vec![AbiParam::new(clif_ty), lib_call_arg_param(fx.tcx, types::I32, true)]; - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; let ret_val = if intrinsic == sym::powif16 { codegen_f16_f128::f32_to_f16(fx, ret_val) } else { @@ -501,7 +505,7 @@ fn codegen_float_intrinsic_call<'tcx>( } _ => { let input_tys: Vec<_> = args.iter().map(|_| AbiParam::new(clif_ty)).collect(); - let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], &args)[0]; + let ret_val = fx.lib_call(name, input_tys, vec![AbiParam::new(clif_ty)], args)[0]; CValue::by_val(ret_val, fx.layout_of(ty)) } }; @@ -1337,23 +1341,75 @@ fn codegen_regular_intrinsic_call<'tcx>( } sym::catch_unwind => { + let ret_block = fx.get_block(destination.unwrap()); + intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic); let f = f.load_scalar(fx); let data = data.load_scalar(fx); - let _catch_fn = catch_fn.load_scalar(fx); + let catch_fn = catch_fn.load_scalar(fx); - // FIXME once unwinding is supported, change this to actually catch panics let f_sig = fx.bcx.func.import_signature(Signature { call_conv: fx.target_config.default_call_conv, params: vec![AbiParam::new(pointer_ty(fx.tcx))], returns: vec![], }); - fx.bcx.ins().call_indirect(f_sig, f, &[data]); + if cfg!(not(feature = "unwinding")) + || fx.tcx.sess.panic_strategy() == PanicStrategy::Abort + { + fx.bcx.ins().call_indirect(f_sig, f, &[data]); + + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); + ret.write_cvalue(fx, ret_val); + + fx.bcx.ins().jump(ret_block, &[]); + } else { + let catch_fn_sig = fx.bcx.func.import_signature(Signature { + call_conv: fx.target_config.default_call_conv, + params: vec![ + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + returns: vec![], + }); + + let fallthrough_block = fx.bcx.create_block(); + let fallthrough_block_call = fx.bcx.func.dfg.block_call(fallthrough_block, &[]); + let catch_block = fx.bcx.create_block(); + let catch_block_call = + fx.bcx.func.dfg.block_call(catch_block, &[BlockArg::TryCallExn(0)]); + let exception_table = + fx.bcx.func.dfg.exception_tables.push(ExceptionTableData::new( + f_sig, + fallthrough_block_call, + [ExceptionTableItem::Tag( + ExceptionTag::with_number(EXCEPTION_HANDLER_CATCH).unwrap(), + catch_block_call, + )], + )); + + fx.bcx.ins().try_call_indirect(f, &[data], exception_table); + + fx.bcx.seal_block(fallthrough_block); + fx.bcx.switch_to_block(fallthrough_block); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); + ret.write_cvalue(fx, ret_val); + fx.bcx.ins().jump(ret_block, &[]); + + fx.bcx.seal_block(catch_block); + fx.bcx.switch_to_block(catch_block); + fx.bcx.set_cold_block(catch_block); + let exception = fx.bcx.append_block_param(catch_block, pointer_ty(fx.tcx)); + fx.bcx.ins().call_indirect(catch_fn_sig, catch_fn, &[data, exception]); + let layout = fx.layout_of(fx.tcx.types.i32); + let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 1), layout); + ret.write_cvalue(fx, ret_val); + fx.bcx.ins().jump(ret_block, &[]); + } - let layout = fx.layout_of(fx.tcx.types.i32); - let ret_val = CValue::by_val(fx.bcx.ins().iconst(types::I32, 0), layout); - ret.write_cvalue(fx, ret_val); + return Ok(()); } sym::fadd_fast diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index ca41381f0abc7..0bce31beb8b87 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -813,7 +813,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( Endian::Big => lane_count - 1 - lane, Endian::Little => lane, }; - let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(mask_lane) as i64); + let m_lane = fx.bcx.ins().ushr_imm(m, mask_lane.cast_signed()); let m_lane = fx.bcx.ins().band_imm(m_lane, 1); let a_lane = a.value_lane(fx, lane).load_scalar(fx); let b_lane = b.value_lane(fx, lane).load_scalar(fx); @@ -1059,6 +1059,15 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let ret_lane_layout = fx.layout_of(ret_lane_ty); let ptr_val = ptr.load_scalar(fx); + let alignment = generic_args[3].expect_const().to_value().valtree.unwrap_branch()[0] + .unwrap_leaf() + .to_simd_alignment(); + + let memflags = match alignment { + SimdAlign::Unaligned => MemFlags::new().with_notrap(), + _ => MemFlags::trusted(), + }; + for lane_idx in 0..ret_lane_count { let val_lane = val.value_lane(fx, lane_idx).load_scalar(fx); let mask_lane = mask.value_lane(fx, lane_idx).load_scalar(fx); @@ -1074,12 +1083,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( fx.bcx.switch_to_block(if_enabled); let offset = lane_idx as i32 * lane_clif_ty.bytes() as i32; - let res = fx.bcx.ins().load( - lane_clif_ty, - MemFlags::trusted(), - ptr_val, - Offset32::new(offset), - ); + let res = fx.bcx.ins().load(lane_clif_ty, memflags, ptr_val, Offset32::new(offset)); fx.bcx.ins().jump(next, &[res.into()]); fx.bcx.switch_to_block(if_disabled); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index b63773053d3fd..4745243a6eab1 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -17,6 +17,7 @@ extern crate rustc_middle; extern crate rustc_abi; extern crate rustc_ast; extern crate rustc_codegen_ssa; +extern crate rustc_const_eval; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_fs_util; @@ -35,6 +36,7 @@ extern crate rustc_target; extern crate rustc_driver; use std::any::Any; +use std::cell::OnceCell; use std::env; use std::sync::Arc; @@ -120,41 +122,8 @@ impl String> Drop for PrintOnPanic { } } -/// The codegen context holds any information shared between the codegen of individual functions -/// inside a single codegen unit with the exception of the Cranelift [`Module`](cranelift_module::Module). -struct CodegenCx { - output_filenames: Arc, - invocation_temp: Option, - should_write_ir: bool, - global_asm: String, - inline_asm_index: usize, - debug_context: Option, - cgu_name: Symbol, -} - -impl CodegenCx { - fn new(tcx: TyCtxt<'_>, isa: &dyn TargetIsa, debug_info: bool, cgu_name: Symbol) -> Self { - assert_eq!(pointer_ty(tcx), isa.pointer_type()); - - let debug_context = if debug_info && !tcx.sess.target.options.is_like_windows { - Some(DebugContext::new(tcx, isa, cgu_name.as_str())) - } else { - None - }; - CodegenCx { - output_filenames: tcx.output_filenames(()).clone(), - invocation_temp: tcx.sess.invocation_temp.clone(), - should_write_ir: crate::pretty_clif::should_write_ir(tcx), - global_asm: String::new(), - inline_asm_index: 0, - debug_context, - cgu_name, - } - } -} - pub struct CraneliftCodegenBackend { - pub config: Option, + pub config: OnceCell, } impl CodegenBackend for CraneliftCodegenBackend { @@ -180,6 +149,15 @@ impl CodegenBackend for CraneliftCodegenBackend { sess.dcx() .fatal("`-Cinstrument-coverage` is LLVM specific and not supported by Cranelift"); } + + let config = self.config.get_or_init(|| { + BackendConfig::from_opts(&sess.opts.cg.llvm_args) + .unwrap_or_else(|err| sess.dcx().fatal(err)) + }); + + if config.jit_mode && !sess.opts.output_types.should_codegen() { + sess.dcx().fatal("JIT mode doesn't work with `cargo check`"); + } } fn target_config(&self, sess: &Session) -> TargetConfig { @@ -202,36 +180,23 @@ impl CodegenBackend for CraneliftCodegenBackend { // FIXME do `unstable_target_features` properly let unstable_target_features = target_features.clone(); - // FIXME(f16_f128): LLVM 20 (currently used by `rustc`) passes `f128` in XMM registers on - // Windows, whereas LLVM 21+ and Cranelift pass it indirectly. This means that `f128` won't - // work when linking against a LLVM-built sysroot. - let has_reliable_f128 = !sess.target.is_like_windows; - let has_reliable_f16 = match sess.target.arch { - // FIXME(f16_f128): LLVM 20 does not support `f16` on s390x, meaning the required - // builtins are not available in `compiler-builtins`. - Arch::S390x => false, - // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU - // targets due to GCC using a different ABI than LLVM. Therefore `f16` won't be - // available when using a LLVM-built sysroot. - Arch::X86_64 - if sess.target.os == "windows" - && sess.target.env == "gnu" - && sess.target.abi != "llvm" => - { - false - } - _ => true, - }; + // FIXME(f16_f128): `rustc_codegen_llvm` currently disables support on Windows GNU + // targets due to GCC using a different ABI than LLVM. Therefore `f16` and `f128` + // won't be available when using a LLVM-built sysroot. + let has_reliable_f16_f128 = !(sess.target.arch == Arch::X86_64 + && sess.target.os == "windows" + && sess.target.env == "gnu" + && sess.target.abi != "llvm"); TargetConfig { target_features, unstable_target_features, // `rustc_codegen_cranelift` polyfills functionality not yet // available in Cranelift. - has_reliable_f16, - has_reliable_f16_math: has_reliable_f16, - has_reliable_f128, - has_reliable_f128_math: has_reliable_f128, + has_reliable_f16: has_reliable_f16_f128, + has_reliable_f16_math: has_reliable_f16_f128, + has_reliable_f128: has_reliable_f16_f128, + has_reliable_f128_math: has_reliable_f16_f128, } } @@ -241,13 +206,10 @@ impl CodegenBackend for CraneliftCodegenBackend { fn codegen_crate(&self, tcx: TyCtxt<'_>) -> Box { info!("codegen crate {}", tcx.crate_name(LOCAL_CRATE)); - let config = self.config.clone().unwrap_or_else(|| { - BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) - .unwrap_or_else(|err| tcx.sess.dcx().fatal(err)) - }); + let config = self.config.get().unwrap(); if config.jit_mode { #[cfg(feature = "jit")] - driver::jit::run_jit(tcx, config.jit_args); + driver::jit::run_jit(tcx, config.jit_args.clone()); #[cfg(not(feature = "jit"))] tcx.dcx().fatal("jit support was disabled when compiling rustc_codegen_cranelift"); @@ -294,8 +256,8 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { flags_builder.set("enable_verifier", enable_verifier).unwrap(); flags_builder.set("regalloc_checker", enable_verifier).unwrap(); - let mut frame_ptr = sess.target.options.frame_pointer.clone(); - frame_ptr.ratchet(sess.opts.cg.force_frame_pointers); + let frame_ptr = + { sess.target.options.frame_pointer }.ratchet(sess.opts.cg.force_frame_pointers); let preserve_frame_pointer = frame_ptr != rustc_target::spec::FramePointer::MayOmit; flags_builder .set("preserve_frame_pointers", if preserve_frame_pointer { "true" } else { "false" }) @@ -391,7 +353,7 @@ fn build_isa(sess: &Session, jit: bool) -> Arc { } /// This is the entrypoint for a hot plugged rustc_codegen_cranelift -#[no_mangle] +#[unsafe(no_mangle)] pub fn __rustc_codegen_backend() -> Box { - Box::new(CraneliftCodegenBackend { config: None }) + Box::new(CraneliftCodegenBackend { config: OnceCell::new() }) } diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index bf756860b6499..c3e4bf1f0c275 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -93,7 +93,7 @@ pub(crate) fn maybe_create_entry_wrapper( let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type()); let arg_sigpipe = bcx.ins().iconst(types::I8, sigpipe as i64); - let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func); + let main_func_ref = m.declare_func_in_func(main_func_id, bcx.func); let result = if ignore_lang_start_wrapper { // ignoring #[lang = "start"] as we are running in the jit @@ -123,7 +123,7 @@ pub(crate) fn maybe_create_entry_wrapper( let report_sig = get_function_sig(tcx, m.target_config().default_call_conv, report); let report_func_id = m.declare_function(report_name, Linkage::Import, &report_sig).unwrap(); - let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func); + let report_func_ref = m.declare_func_in_func(report_func_id, bcx.func); // FIXME do proper abi handling instead of expecting the pass mode to be identical // for returns and arguments. @@ -148,7 +148,7 @@ pub(crate) fn maybe_create_entry_wrapper( let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref); - let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func); + let func_ref = m.declare_func_in_func(start_func_id, bcx.func); let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]); bcx.inst_results(call_inst)[0] diff --git a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs index 9400ae9fcff0f..2878fa7aa298a 100644 --- a/compiler/rustc_codegen_cranelift/src/pretty_clif.rs +++ b/compiler/rustc_codegen_cranelift/src/pretty_clif.rs @@ -64,6 +64,7 @@ use cranelift_codegen::ir::Fact; use cranelift_codegen::ir::entities::AnyEntity; use cranelift_codegen::write::{FuncWriter, PlainWriter}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_session::Session; use rustc_session::config::{OutputFilenames, OutputType}; use rustc_target::callconv::FnAbi; @@ -83,7 +84,7 @@ impl CommentWriter { instance: Instance<'tcx>, fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>, ) -> Self { - let enabled = should_write_ir(tcx); + let enabled = should_write_ir(tcx.sess); let global_comments = if enabled { with_no_trimmed_paths!({ vec![ @@ -247,8 +248,8 @@ impl FunctionCx<'_, '_, '_> { } } -pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { - tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) +pub(crate) fn should_write_ir(sess: &Session) -> bool { + sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } pub(crate) fn write_ir_file( @@ -311,7 +312,7 @@ impl fmt::Debug for FunctionCx<'_, '_, '_> { ::cranelift_codegen::write::decorate_function( &mut &self.clif_comments, &mut clif, - &self.bcx.func, + self.bcx.func, ) .unwrap(); writeln!(f, "\n{}", clif) diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index c97eb3874b02c..3dbb689cccd26 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -134,7 +134,7 @@ pub(crate) fn coerce_unsized_into<'tcx>( (ty::Pat(a, _), ty::Pat(b, _)) => { let src = src.cast_pat_ty_to_base(fx.layout_of(*a)); let dst = dst.place_transmute_type(fx, *b); - return coerce_unsized_into(fx, src, dst); + coerce_unsized_into(fx, src, dst) } (&ty::Ref(..), &ty::Ref(..)) | (&ty::Ref(..), &ty::RawPtr(..)) diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 9dcd4a33d44f6..5b76a4cb97793 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -310,13 +310,13 @@ impl<'tcx> CValue<'tcx> { fx.bcx.ins().iconst(clif_ty, raw_val as i64) } ty::Float(FloatTy::F16) => { - fx.bcx.ins().f16const(Ieee16::with_bits(u16::try_from(const_val).unwrap())) + fx.bcx.ins().f16const(Ieee16::with_bits(u16::from(const_val))) } ty::Float(FloatTy::F32) => { - fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap())) + fx.bcx.ins().f32const(Ieee32::with_bits(u32::from(const_val))) } ty::Float(FloatTy::F64) => { - fx.bcx.ins().f64const(Ieee64::with_bits(u64::try_from(const_val).unwrap())) + fx.bcx.ins().f64const(Ieee64::with_bits(u64::from(const_val))) } ty::Float(FloatTy::F128) => { let value = fx @@ -324,7 +324,7 @@ impl<'tcx> CValue<'tcx> { .func .dfg .constants - .insert(Ieee128::with_bits(u128::try_from(const_val).unwrap()).into()); + .insert(Ieee128::with_bits(u128::from(const_val)).into()); fx.bcx.ins().f128const(value) } _ => panic!( @@ -401,9 +401,7 @@ impl<'tcx> CPlace<'tcx> { local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let var = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap()); + let var = fx.bcx.declare_var(fx.clif_type(layout.ty).unwrap()); CPlace { inner: CPlaceInner::Var(local, var), layout } } @@ -412,14 +410,9 @@ impl<'tcx> CPlace<'tcx> { local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let var1 = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - let var2 = Variable::from_u32(fx.next_ssa_var); - fx.next_ssa_var += 1; - let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap(); - fx.bcx.declare_var(var1, ty1); - fx.bcx.declare_var(var2, ty2); + let var1 = fx.bcx.declare_var(ty1); + let var2 = fx.bcx.declare_var(ty2); CPlace { inner: CPlaceInner::VarPair(local, var1, var2), layout } } diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs index 423cc8d225be1..b5d241d8f39f2 100644 --- a/compiler/rustc_codegen_cranelift/src/vtable.rs +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -84,5 +84,5 @@ pub(crate) fn get_vtable<'tcx>( if fx.clif_comments.enabled() { fx.add_comment(local_data_id, "vtable"); } - fx.bcx.ins().global_value(fx.pointer_type, local_data_id) + fx.bcx.ins().symbol_value(fx.pointer_type, local_data_id) } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 6a1721df1642e..c8bd215a1cb42 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -576,6 +576,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "foldhash", "gimli", "hashbrown", + "heck", "indexmap", "libc", "libloading", @@ -596,8 +597,9 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ "syn", "target-lexicon", "unicode-ident", - "wasmtime-jit-icache-coherence", - "wasmtime-math", + "wasmtime-internal-jit-icache-coherence", + "wasmtime-internal-math", + "windows-link", "windows-sys", "windows-targets", "windows_aarch64_gnullvm",