Merge commit 'a0b865dc87' into sync_cg_clif-2025-11-08
This commit is contained in:
parent
2073d1209d
commit
c90a9d836b
58 changed files with 1664 additions and 832 deletions
44
.cirrus.yml
44
.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
|
||||
|
|
|
|||
2
.github/workflows/abi-cafe.yml
vendored
2
.github/workflows/abi-cafe.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
6
.github/workflows/main.yml
vendored
6
.github/workflows/main.yml
vendored
|
|
@ -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:
|
||||
|
|
|
|||
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
|
|
@ -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": [],
|
||||
},
|
||||
|
|
|
|||
290
Cargo.lock
generated
290
Cargo.lock
generated
|
|
@ -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 = "indexmap"
|
||||
version = "2.7.0"
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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"
|
||||
|
|
|
|||
31
Cargo.toml
31
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
|
||||
|
|
|
|||
19
Readme.md
19
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ pub(crate) fn build_sysroot(
|
|||
bootstrap_host_compiler: &Compiler,
|
||||
rustup_toolchain_name: Option<&str>,
|
||||
target_triple: String,
|
||||
panic_unwind_support: bool,
|
||||
) -> Compiler {
|
||||
let _guard = LogGroup::guard("Build sysroot");
|
||||
|
||||
|
|
@ -48,10 +49,13 @@ pub(crate) fn build_sysroot(
|
|||
let mut build_cargo_wrapper_cmd = Command::new(&bootstrap_host_compiler.rustc);
|
||||
let wrapper_path = dist_dir.join(&wrapper_name);
|
||||
build_cargo_wrapper_cmd
|
||||
.arg(dirs.source_dir.join("scripts").join(&format!("{wrapper}.rs")))
|
||||
.arg(dirs.source_dir.join("scripts").join(format!("{wrapper}.rs")))
|
||||
.arg("-o")
|
||||
.arg(&wrapper_path)
|
||||
.arg("-Cstrip=debuginfo");
|
||||
if panic_unwind_support {
|
||||
build_cargo_wrapper_cmd.arg("--cfg").arg("support_panic_unwind");
|
||||
}
|
||||
if let Some(rustup_toolchain_name) = &rustup_toolchain_name {
|
||||
build_cargo_wrapper_cmd
|
||||
.env("TOOLCHAIN_NAME", rustup_toolchain_name)
|
||||
|
|
@ -77,6 +81,7 @@ pub(crate) fn build_sysroot(
|
|||
bootstrap_host_compiler.clone(),
|
||||
&cg_clif_dylib_path,
|
||||
sysroot_kind,
|
||||
panic_unwind_support,
|
||||
);
|
||||
host.install_into_sysroot(dist_dir);
|
||||
|
||||
|
|
@ -91,6 +96,7 @@ pub(crate) fn build_sysroot(
|
|||
},
|
||||
&cg_clif_dylib_path,
|
||||
sysroot_kind,
|
||||
panic_unwind_support,
|
||||
)
|
||||
.install_into_sysroot(dist_dir);
|
||||
}
|
||||
|
|
@ -134,19 +140,20 @@ impl SysrootTarget {
|
|||
static STDLIB_SRC: RelPath = RelPath::build("stdlib");
|
||||
static STANDARD_LIBRARY: CargoProject =
|
||||
CargoProject::new(&RelPath::build("stdlib/library/sysroot"), "stdlib_target");
|
||||
static RTSTARTUP_SYSROOT: RelPath = RelPath::build("rtstartup");
|
||||
|
||||
fn build_sysroot_for_triple(
|
||||
dirs: &Dirs,
|
||||
compiler: Compiler,
|
||||
cg_clif_dylib_path: &CodegenBackend,
|
||||
sysroot_kind: SysrootKind,
|
||||
panic_unwind_support: bool,
|
||||
) -> SysrootTarget {
|
||||
match sysroot_kind {
|
||||
SysrootKind::None => build_rtstartup(dirs, &compiler)
|
||||
.unwrap_or(SysrootTarget { triple: compiler.triple, libs: vec![] }),
|
||||
SysrootKind::None => SysrootTarget { triple: compiler.triple, libs: vec![] },
|
||||
SysrootKind::Llvm => build_llvm_sysroot_for_triple(compiler),
|
||||
SysrootKind::Clif => build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path),
|
||||
SysrootKind::Clif => {
|
||||
build_clif_sysroot_for_triple(dirs, compiler, cg_clif_dylib_path, panic_unwind_support)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -188,25 +195,28 @@ fn build_clif_sysroot_for_triple(
|
|||
dirs: &Dirs,
|
||||
mut compiler: Compiler,
|
||||
cg_clif_dylib_path: &CodegenBackend,
|
||||
panic_unwind_support: bool,
|
||||
) -> SysrootTarget {
|
||||
let mut target_libs = SysrootTarget { triple: compiler.triple.clone(), libs: vec![] };
|
||||
|
||||
if let Some(rtstartup_target_libs) = build_rtstartup(dirs, &compiler) {
|
||||
rtstartup_target_libs.install_into_sysroot(&RTSTARTUP_SYSROOT.to_path(dirs));
|
||||
|
||||
target_libs.libs.extend(rtstartup_target_libs.libs);
|
||||
}
|
||||
|
||||
let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(&compiler.triple).join("release");
|
||||
|
||||
if !config::get_bool("keep_sysroot") {
|
||||
let sysroot_src_orig = get_default_sysroot(&compiler.rustc).join("lib/rustlib/src/rust");
|
||||
assert!(sysroot_src_orig.exists());
|
||||
|
||||
apply_patches(dirs, "stdlib", &sysroot_src_orig, &STDLIB_SRC.to_path(dirs));
|
||||
|
||||
// Cleanup the deps dir, but keep build scripts and the incremental cache for faster
|
||||
// recompilation as they are not affected by changes in cg_clif.
|
||||
ensure_empty_dir(&build_dir.join("deps"));
|
||||
}
|
||||
|
||||
// Build sysroot
|
||||
let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned(), "-Cpanic=abort".to_owned()];
|
||||
let mut rustflags = vec!["-Zforce-unstable-if-unmarked".to_owned()];
|
||||
if !panic_unwind_support {
|
||||
rustflags.push("-Cpanic=abort".to_owned());
|
||||
}
|
||||
match cg_clif_dylib_path {
|
||||
CodegenBackend::Local(path) => {
|
||||
rustflags.push(format!("-Zcodegen-backend={}", path.to_str().unwrap()));
|
||||
|
|
@ -215,9 +225,7 @@ fn build_clif_sysroot_for_triple(
|
|||
rustflags.push(format!("-Zcodegen-backend={name}"));
|
||||
}
|
||||
};
|
||||
// Necessary for MinGW to find rsbegin.o and rsend.o
|
||||
rustflags.push("--sysroot".to_owned());
|
||||
rustflags.push(RTSTARTUP_SYSROOT.to_path(dirs).to_str().unwrap().to_owned());
|
||||
rustflags.push("--sysroot=/dev/null".to_owned());
|
||||
|
||||
// Incremental compilation by default disables mir inlining. This leads to both a decent
|
||||
// compile perf and a significant runtime perf regression. As such forcefully enable mir
|
||||
|
|
@ -258,38 +266,3 @@ fn build_clif_sysroot_for_triple(
|
|||
|
||||
target_libs
|
||||
}
|
||||
|
||||
fn build_rtstartup(dirs: &Dirs, compiler: &Compiler) -> Option<SysrootTarget> {
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<Vec<_>>(),
|
||||
&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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
let version_info = Command::new(rustc)
|
||||
.stderr(Stdio::inherit())
|
||||
.args(["--print", "host-tuple"])
|
||||
.output()
|
||||
.unwrap()
|
||||
.lines()
|
||||
.to_owned()
|
||||
.find(|line| line.starts_with("host"))
|
||||
.unwrap()
|
||||
.split(":")
|
||||
.nth(1)
|
||||
.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",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ impl CargoProject {
|
|||
pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
|
||||
let src = src.as_ref();
|
||||
let dst = dst.as_ref();
|
||||
if let Err(_) = fs::hard_link(src, dst) {
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -77,12 +77,16 @@ pub fn use_size_of() -> usize {
|
|||
}
|
||||
|
||||
pub unsafe fn use_copy_intrinsic(src: *const u8, dst: *mut u8) {
|
||||
intrinsics::copy::<u8>(src, dst, 1);
|
||||
unsafe {
|
||||
intrinsics::copy::<u8>(src, dst, 1);
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn use_copy_intrinsic_ref(src: *const u8, dst: *mut u8) {
|
||||
let copy2 = &intrinsics::copy::<u8>;
|
||||
copy2(src, dst, 1);
|
||||
unsafe {
|
||||
let copy2 = &intrinsics::copy::<u8>;
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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<T: ?Sized>(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<T: ?Sized> Deref for Box<T> {
|
|||
|
||||
#[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<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub unsafe fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
|
||||
pub unsafe fn size_of_val<T: ?crate::Sized>(val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub const fn align_of<T>() -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub unsafe fn align_of_val<T: ?::Sized>(val: *const T) -> usize;
|
||||
pub unsafe fn align_of_val<T: ?crate::Sized>(val: *const T) -> usize;
|
||||
#[rustc_intrinsic]
|
||||
pub unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||
#[rustc_intrinsic]
|
||||
|
|
@ -661,7 +663,7 @@ pub mod intrinsics {
|
|||
#[rustc_intrinsic]
|
||||
pub unsafe fn ctlz_nonzero<T>(x: T) -> u32;
|
||||
#[rustc_intrinsic]
|
||||
pub const fn needs_drop<T: ?::Sized>() -> bool;
|
||||
pub const fn needs_drop<T: ?crate::Sized>() -> bool;
|
||||
#[rustc_intrinsic]
|
||||
pub fn bitreverse<T>(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<T> 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]
|
||||
|
|
|
|||
|
|
@ -124,9 +124,11 @@ static mut NUM: u8 = 6 * 7;
|
|||
static NUM_REF: &'static u8 = unsafe { &*&raw const NUM };
|
||||
|
||||
unsafe fn zeroed<T>() -> 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>() -> 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);
|
||||
}
|
||||
|
||||
Thread { handle: thread }
|
||||
}
|
||||
|
||||
if pthread_create(&mut thread, &attr, f, 0 as *mut c_void) != 0 {
|
||||
assert!(false);
|
||||
#[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);
|
||||
}
|
||||
|
||||
Thread { handle }
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (handle as u64) == 0 {
|
||||
assert!(false);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
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 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]);
|
||||
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_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();
|
||||
test_mm_extract_epi8();
|
||||
test_mm_insert_epi16();
|
||||
test_mm_shuffle_epi8();
|
||||
|
||||
#[cfg(not(jit))]
|
||||
test_mm_cmpestri();
|
||||
#[cfg(not(jit))]
|
||||
test_mm_cmpestri();
|
||||
|
||||
test_mm256_shuffle_epi8();
|
||||
test_mm256_permute2x128_si256();
|
||||
test_mm256_permutevar8x32_epi32();
|
||||
test_mm256_shuffle_epi8();
|
||||
test_mm256_permute2x128_si256();
|
||||
test_mm256_permutevar8x32_epi32();
|
||||
|
||||
#[rustfmt::skip]
|
||||
#[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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2025-06-24"
|
||||
channel = "nightly-2025-11-08"
|
||||
components = ["rust-src", "rustc-dev", "llvm-tools"]
|
||||
profile = "minimal"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ fn main() {
|
|||
|
||||
let passed_args = std::env::args_os().skip(1).collect::<Vec<_>>();
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ fn main() {
|
|||
|
||||
let passed_args = std::env::args_os().skip(1).collect::<Vec<_>>();
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -50,23 +50,24 @@ EOF
|
|||
|
||||
cat <<EOF | git apply -
|
||||
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
|
||||
index cf4ef4ee310..fe78560fcaf 100644
|
||||
index a656927b1f6..44fc5546fac 100644
|
||||
--- a/src/bootstrap/src/core/config/config.rs
|
||||
+++ b/src/bootstrap/src/core/config/config.rs
|
||||
@@ -3138,13 +3138,6 @@ fn parse_download_ci_llvm(
|
||||
);
|
||||
}
|
||||
|
||||
- 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."
|
||||
- );
|
||||
- }
|
||||
-
|
||||
// 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)
|
||||
@@ -2249,14 +2249,6 @@ pub fn parse_download_ci_llvm<'a>(
|
||||
);
|
||||
}
|
||||
|
||||
- #[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(&dwn_ctx.host_target, asserts)
|
||||
}
|
||||
EOF
|
||||
|
||||
popd
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
208
src/abi/mod.rs
208
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<Operand<'tcx>>],
|
||||
destination: Place<'tcx>,
|
||||
target: Option<BasicBlock>,
|
||||
_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::<SmallVec<[Value; 2]>>()
|
||||
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<Block>,
|
||||
) -> 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::<SmallVec<[Value; 2]>>()
|
||||
}
|
||||
}
|
||||
UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) => {
|
||||
let returns_types = fx.bcx.func.dfg.signatures[sig_ref]
|
||||
.returns
|
||||
.iter()
|
||||
.map(|return_param| return_param.value_type)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
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::<Vec<_>>();
|
||||
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![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
99
src/base.rs
99
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<FunctionDebugContext>,
|
||||
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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:?}"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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::<Vec<Value>>();
|
||||
|
||||
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<FunctionDebugContext>,
|
||||
|
||||
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<CValue<'tcx>>,
|
||||
|
||||
/// 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 <abi_align> 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>);
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -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(..) => {}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
},
|
||||
|
|
|
|||
271
src/debuginfo/gcc_except_table.rs
Normal file
271
src/debuginfo/gcc_except_table.rs
Normal file
|
|
@ -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<W: Writer>(
|
||||
&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<CallSite>);
|
||||
|
||||
impl CallSiteTable {
|
||||
fn encoded_size(&self) -> u64 {
|
||||
let mut len = LenWriter(0);
|
||||
self.write(&mut len).unwrap();
|
||||
len.0 as u64
|
||||
}
|
||||
|
||||
fn write<W: Writer>(&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<ActionOffset>,
|
||||
}
|
||||
|
||||
impl CallSite {
|
||||
fn encoded_size(&self) -> u64 {
|
||||
let mut len = LenWriter(0);
|
||||
self.write(&mut len).unwrap();
|
||||
len.0 as u64
|
||||
}
|
||||
|
||||
fn write<W: Writer>(&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<Action>,
|
||||
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<W: Writer>(&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<ActionOffset>,
|
||||
}
|
||||
|
||||
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<W: Writer>(&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<Address>,
|
||||
}
|
||||
|
||||
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<W: Writer>(&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(())
|
||||
}
|
||||
}
|
||||
|
|
@ -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(source_file: &SourceFile, embed_source: bool) -> Option<FileInfo> {
|
||||
let has_md5 = source_file.src_hash.kind == SourceFileHashAlgorithm::Md5;
|
||||
let has_source = embed_source && source_file.src.is_some();
|
||||
|
||||
fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
|
||||
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
|
||||
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,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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<Self> {
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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::<Vec<_>>();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<CodegenedFunction>) {
|
||||
) -> (Option<DebugContext>, Vec<CodegenedFunction>, 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<OngoingCodegen> {
|
|||
|
||||
// Calculate the CGU reuse
|
||||
let cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
|
||||
cgus.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect::<Vec<_>>()
|
||||
cgus.iter().map(|cgu| determine_cgu_reuse(tcx, cgu)).collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
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<OngoingCodegen> {
|
|||
|
||||
let disable_incr_cache = disable_incr_cache();
|
||||
let (todo_cgus, done_cgus) =
|
||||
cgus.into_iter().enumerate().partition::<Vec<_>, _>(|&(i, _)| match cgu_reuse[i] {
|
||||
cgus.iter().enumerate().partition::<Vec<_>, _>(|&(i, _)| match cgu_reuse[i] {
|
||||
_ if disable_incr_cache => true,
|
||||
CguReuse::No => true,
|
||||
CguReuse::PreLto | CguReuse::PostLto => false,
|
||||
|
|
|
|||
|
|
@ -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<JITModule>, CodegenCx) {
|
||||
fn create_jit_module(tcx: TyCtxt<'_>) -> (UnwindModule<JITModule>, Option<DebugContext>) {
|
||||
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<JITModule>, 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<JITModule>, CodegenCx) {
|
|||
}
|
||||
|
||||
pub(crate) fn run_jit(tcx: TyCtxt<'_>, jit_args: Vec<String>) -> ! {
|
||||
// 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<String>) -> ! {
|
|||
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<String>) -> ! {
|
|||
}
|
||||
});
|
||||
|
||||
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<String>) -> ! {
|
|||
|
||||
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");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(_) => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Option<PathBuf>, 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")
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
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, &[]);
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
sym::fadd_fast
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
96
src/lib.rs
96
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<F: Fn() -> String> Drop for PrintOnPanic<F> {
|
|||
}
|
||||
}
|
||||
|
||||
/// 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<OutputFilenames>,
|
||||
invocation_temp: Option<String>,
|
||||
should_write_ir: bool,
|
||||
global_asm: String,
|
||||
inline_asm_index: usize,
|
||||
debug_context: Option<DebugContext>,
|
||||
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<BackendConfig>,
|
||||
pub config: OnceCell<BackendConfig>,
|
||||
}
|
||||
|
||||
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<dyn Any> {
|
||||
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<dyn TargetIsa + 'static> {
|
|||
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<dyn TargetIsa + 'static> {
|
|||
}
|
||||
|
||||
/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
|
||||
#[no_mangle]
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
|
||||
Box::new(CraneliftCodegenBackend { config: None })
|
||||
Box::new(CraneliftCodegenBackend { config: OnceCell::new() })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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(..))
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue