Merge commit '266e96785a' into sync_cg_clif-2022-10-23

This commit is contained in:
bjorn3 2022-10-23 16:22:55 +02:00
commit e54a13f18b
45 changed files with 1041 additions and 634 deletions

View file

@ -29,7 +29,11 @@ jobs:
matrix: matrix:
include: include:
- os: ubuntu-latest - os: ubuntu-latest
env:
TARGET_TRIPLE: x86_64-unknown-linux-gnu
- os: macos-latest - os: macos-latest
env:
TARGET_TRIPLE: x86_64-apple-darwin
# cross-compile from Linux to Windows using mingw # cross-compile from Linux to Windows using mingw
- os: ubuntu-latest - os: ubuntu-latest
env: env:
@ -112,7 +116,7 @@ jobs:
if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu' if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu'
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: cg_clif-${{ runner.os }} name: cg_clif-${{ matrix.env.TARGET_TRIPLE }}
path: cg_clif.tar.xz path: cg_clif.tar.xz
- name: Upload prebuilt cg_clif (cross compile) - name: Upload prebuilt cg_clif (cross compile)
@ -122,56 +126,89 @@ jobs:
name: cg_clif-${{ runner.os }}-cross-x86_64-mingw name: cg_clif-${{ runner.os }}-cross-x86_64-mingw
path: cg_clif.tar.xz path: cg_clif.tar.xz
build_windows: windows:
runs-on: windows-latest runs-on: ${{ matrix.os }}
timeout-minutes: 60 timeout-minutes: 60
strategy:
fail-fast: false
matrix:
include:
# Native Windows build with MSVC
- os: windows-latest
env:
TARGET_TRIPLE: x86_64-pc-windows-msvc
# cross-compile from Windows to Windows MinGW
- os: windows-latest
env:
TARGET_TRIPLE: x86_64-pc-windows-gnu
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
#- name: Cache cargo installed crates - name: Cache cargo installed crates
# uses: actions/cache@v2 uses: actions/cache@v2
# with: with:
# path: ~/.cargo/bin path: ~/.cargo/bin
# key: ${{ runner.os }}-cargo-installed-crates key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-installed-crates
#- name: Cache cargo registry and index - name: Cache cargo registry and index
# uses: actions/cache@v2 uses: actions/cache@v2
# with: with:
# path: | path: |
# ~/.cargo/registry ~/.cargo/registry
# ~/.cargo/git ~/.cargo/git
# key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
#- name: Cache cargo target dir - name: Cache cargo target dir
# uses: actions/cache@v2 uses: actions/cache@v2
# with: with:
# path: target path: target
# key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
- name: Set MinGW as the default toolchain
if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
run: rustup set default-host x86_64-pc-windows-gnu
- name: Prepare dependencies - name: Prepare dependencies
run: | run: |
git config --global user.email "user@example.com" git config --global user.email "user@example.com"
git config --global user.name "User" git config --global user.name "User"
git config --global core.autocrlf false git config --global core.autocrlf false
rustup set default-host x86_64-pc-windows-gnu
rustc y.rs -o y.exe -g rustc y.rs -o y.exe -g
./y.exe prepare ./y.exe prepare
- name: Build without unstable features
env:
TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }}
# This is the config rust-lang/rust uses for builds
run: ./y.rs build --no-unstable-features
- name: Build - name: Build
#name: Test run: ./y.rs build --sysroot none
- name: Test
run: | run: |
# Enable backtraces for easier debugging # Enable backtraces for easier debugging
#$Env:RUST_BACKTRACE=1 $Env:RUST_BACKTRACE=1
# Reduce amount of benchmark runs as they are slow # Reduce amount of benchmark runs as they are slow
#$Env:COMPILE_RUNS=2 $Env:COMPILE_RUNS=2
#$Env:RUN_RUNS=2 $Env:RUN_RUNS=2
# Enable extra checks # Enable extra checks
#$Env:CG_CLIF_ENABLE_VERIFIER=1 $Env:CG_CLIF_ENABLE_VERIFIER=1
./y.exe build # WIP Disable some tests
# This fails due to some weird argument handling by hyperfine, not an actual regression
# more of a build system issue
(Get-Content config.txt) -replace '(bench.simple-raytracer)', '# $1' | Out-File config.txt
# This fails with a different output than expected
(Get-Content config.txt) -replace '(test.regex-shootout-regex-dna)', '# $1' | Out-File config.txt
./y.exe test
- name: Package prebuilt cg_clif - name: Package prebuilt cg_clif
# don't use compression as xzip isn't supported by tar on windows and bzip2 hangs # don't use compression as xzip isn't supported by tar on windows and bzip2 hangs
@ -180,5 +217,5 @@ jobs:
- name: Upload prebuilt cg_clif - name: Upload prebuilt cg_clif
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2
with: with:
name: cg_clif-${{ runner.os }} name: cg_clif-${{ matrix.env.TARGET_TRIPLE }}
path: cg_clif.tar path: cg_clif.tar

View file

@ -15,8 +15,4 @@ perf.data.old
/build_sysroot/compiler-builtins /build_sysroot/compiler-builtins
/build_sysroot/rustc_version /build_sysroot/rustc_version
/rust /rust
/rand /download
/regex
/simple-raytracer
/portable-simd
/abi-checker

View file

@ -7,7 +7,7 @@
"rust-analyzer.cargo.features": ["unstable-features"], "rust-analyzer.cargo.features": ["unstable-features"],
"rust-analyzer.linkedProjects": [ "rust-analyzer.linkedProjects": [
"./Cargo.toml", "./Cargo.toml",
//"./build_sysroot/sysroot_src/src/libstd/Cargo.toml", //"./build_sysroot/sysroot_src/library/std/Cargo.toml",
{ {
"roots": [ "roots": [
"./example/mini_core.rs", "./example/mini_core.rs",
@ -36,10 +36,10 @@
] ]
}, },
{ {
"roots": ["./scripts/filter_profile.rs"], "roots": ["./example/std_example.rs"],
"crates": [ "crates": [
{ {
"root_module": "./scripts/filter_profile.rs", "root_module": "./example/std_example.rs",
"edition": "2018", "edition": "2018",
"deps": [{ "crate": 1, "name": "std" }], "deps": [{ "crate": 1, "name": "std" }],
"cfg": [], "cfg": [],

View file

@ -24,6 +24,12 @@ name = "ar"
version = "0.8.0" version = "0.8.0"
source = "git+https://github.com/bjorn3/rust-ar.git?branch=do_not_remove_cg_clif_ranlib#de9ab0e56bf3a208381d342aa5b60f9ff2891648" source = "git+https://github.com/bjorn3/rust-ar.git?branch=do_not_remove_cg_clif_ranlib#de9ab0e56bf3a208381d342aa5b60f9ff2891648"
[[package]]
name = "arrayvec"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -36,6 +42,12 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -50,19 +62,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "cranelift-bforest" name = "cranelift-bforest"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93945adbccc8d731503d3038814a51e8317497c9e205411820348132fa01a358" checksum = "44409ccf2d0f663920cab563d2b79fcd6b2e9a2bcc6e929fef76c8f82ad6c17a"
dependencies = [ dependencies = [
"cranelift-entity", "cranelift-entity",
] ]
[[package]] [[package]]
name = "cranelift-codegen" name = "cranelift-codegen"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b482acc9d0d0d1ad3288a90a8150ee648be3dce8dc8c8669ff026f72debdc31" checksum = "98de2018ad96eb97f621f7d6b900a0cc661aec8d02ea4a50e56ecb48e5a2fcaf"
dependencies = [ dependencies = [
"arrayvec",
"bumpalo",
"cranelift-bforest", "cranelift-bforest",
"cranelift-codegen-meta", "cranelift-codegen-meta",
"cranelift-codegen-shared", "cranelift-codegen-shared",
@ -77,30 +91,30 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-codegen-meta" name = "cranelift-codegen-meta"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9ec188d71e663192ef9048f204e410a7283b609942efc9fcc77da6d496edbb8" checksum = "5287ce36e6c4758fbaf298bd1a8697ad97a4f2375a3d1b61142ea538db4877e5"
dependencies = [ dependencies = [
"cranelift-codegen-shared", "cranelift-codegen-shared",
] ]
[[package]] [[package]]
name = "cranelift-codegen-shared" name = "cranelift-codegen-shared"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ad794b1b1c2c7bd9f7b76cfe0f084eaf7753e55d56191c3f7d89e8fa4978b99" checksum = "2855c24219e2f08827f3f4ffb2da92e134ae8d8ecc185b11ec8f9878cf5f588e"
[[package]] [[package]]
name = "cranelift-entity" name = "cranelift-entity"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "342da0d5056f4119d3c311c4aab2460ceb6ee6e127bb395b76dd2279a09ea7a5" checksum = "0b65673279d75d34bf11af9660ae2dbd1c22e6d28f163f5c72f4e1dc56d56103"
[[package]] [[package]]
name = "cranelift-frontend" name = "cranelift-frontend"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfff792f775b07d4d9cfe9f1c767ce755c6cbadda1bbd6db18a1c75ff9f7376a" checksum = "3ed2b3d7a4751163f6c4a349205ab1b7d9c00eecf19dcea48592ef1f7688eefc"
dependencies = [ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"log", "log",
@ -110,15 +124,15 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-isle" name = "cranelift-isle"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d51089478849f2ac8ef60a8a2d5346c8d4abfec0e45ac5b24530ef9f9499e1e" checksum = "3be64cecea9d90105fc6a2ba2d003e98c867c1d6c4c86cc878f97ad9fb916293"
[[package]] [[package]]
name = "cranelift-jit" name = "cranelift-jit"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "095936e41720f86004b4c57ce88e6a13af28646bb3a6fb4afbebd5ae90c50029" checksum = "f98ed42a70a0c9c388e34ec9477f57fc7300f541b1e5136a0e2ea02b1fac6015"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cranelift-codegen", "cranelift-codegen",
@ -134,9 +148,9 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-module" name = "cranelift-module"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "704a1aea4723d97eafe0fb7af110f6f6868b1ac95f5380bbc9adb2a3b8cf97e8" checksum = "d658ac7f156708bfccb647216cc8b9387469f50d352ba4ad80150541e4ae2d49"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cranelift-codegen", "cranelift-codegen",
@ -144,9 +158,9 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-native" name = "cranelift-native"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "885debe62f2078638d6585f54c9f05f5c2008f22ce5a2a9100ada785fc065dbd" checksum = "c4a03a6ac1b063e416ca4b93f6247978c991475e8271465340caa6f92f3c16a4"
dependencies = [ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"libc", "libc",
@ -155,9 +169,9 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-object" name = "cranelift-object"
version = "0.87.0" version = "0.88.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aac1310cf1081ae8eca916c92cd163b977c77cab6e831fa812273c26ff921816" checksum = "eef0b4119b645b870a43a036d76c0ada3a076b1f82e8b8487659304c8b09049b"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cranelift-codegen", "cranelift-codegen",
@ -232,9 +246,9 @@ checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.6.7" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"winapi", "winapi",

View file

@ -8,19 +8,19 @@ crate-type = ["dylib"]
[dependencies] [dependencies]
# These have to be in sync with each other # These have to be in sync with each other
cranelift-codegen = { version = "0.87.0", features = ["unwind", "all-arch"] } cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
cranelift-frontend = "0.87.0" cranelift-frontend = "0.88.1"
cranelift-module = "0.87.0" cranelift-module = "0.88.1"
cranelift-native = "0.87.0" cranelift-native = "0.88.1"
cranelift-jit = { version = "0.87.0", optional = true } cranelift-jit = { version = "0.88.1", optional = true }
cranelift-object = "0.87.0" cranelift-object = "0.88.1"
target-lexicon = "0.12.0" target-lexicon = "0.12.0"
gimli = { version = "0.26.0", default-features = false, features = ["write"]} gimli = { version = "0.26.0", default-features = false, features = ["write"]}
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" } ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
indexmap = "1.9.1" indexmap = "1.9.1"
libloading = { version = "0.6.0", optional = true } libloading = { version = "0.7.3", optional = true }
once_cell = "1.10.0" once_cell = "1.10.0"
smallvec = "1.8.1" smallvec = "1.8.1"

View file

@ -55,10 +55,20 @@ dependencies = [
] ]
[[package]] [[package]]
name = "compiler_builtins" name = "cfg-if"
version = "0.1.79" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f873ce2bd3550b0b565f878b3d04ea8253f4259dc3d20223af2e1ba86f5ecca" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-core",
]
[[package]]
name = "compiler_builtins"
version = "0.1.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18cd7635fea7bb481ea543b392789844c1ad581299da70184c7175ce3af76603"
dependencies = [ dependencies = [
"rustc-std-workspace-core", "rustc-std-workspace-core",
] ]
@ -123,9 +133,9 @@ dependencies = [
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.2.5" version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "897cd85af6387be149f55acf168e41be176a02de7872403aaab184afc2f327e6" checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [ dependencies = [
"compiler_builtins", "compiler_builtins",
"libc", "libc",
@ -135,9 +145,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.132" version = "0.2.135"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5" checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
dependencies = [ dependencies = [
"rustc-std-workspace-core", "rustc-std-workspace-core",
] ]
@ -182,7 +192,7 @@ name = "panic_abort"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"alloc", "alloc",
"cfg-if", "cfg-if 0.1.10",
"compiler_builtins", "compiler_builtins",
"core", "core",
"libc", "libc",
@ -193,7 +203,7 @@ name = "panic_unwind"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"alloc", "alloc",
"cfg-if", "cfg-if 0.1.10",
"compiler_builtins", "compiler_builtins",
"core", "core",
"libc", "libc",
@ -245,7 +255,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"addr2line", "addr2line",
"alloc", "alloc",
"cfg-if", "cfg-if 1.0.0",
"compiler_builtins", "compiler_builtins",
"core", "core",
"dlmalloc", "dlmalloc",
@ -267,7 +277,7 @@ dependencies = [
name = "std_detect" name = "std_detect"
version = "0.1.5" version = "0.1.5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if 1.0.0",
"compiler_builtins", "compiler_builtins",
"libc", "libc",
"rustc-std-workspace-alloc", "rustc-std-workspace-alloc",
@ -289,7 +299,7 @@ dependencies = [
name = "test" name = "test"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"cfg-if", "cfg-if 0.1.10",
"core", "core",
"getopts", "getopts",
"libc", "libc",
@ -301,9 +311,9 @@ dependencies = [
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.9" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
dependencies = [ dependencies = [
"compiler_builtins", "compiler_builtins",
"rustc-std-workspace-core", "rustc-std-workspace-core",
@ -315,7 +325,7 @@ name = "unwind"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if 0.1.10",
"compiler_builtins", "compiler_builtins",
"core", "core",
"libc", "libc",

View file

@ -0,0 +1,52 @@
use std::env;
use std::path::Path;
use super::build_sysroot;
use super::config;
use super::prepare;
use super::utils::{cargo_command, spawn_and_wait};
use super::SysrootKind;
pub(crate) fn run(
channel: &str,
sysroot_kind: SysrootKind,
target_dir: &Path,
cg_clif_dylib: &Path,
host_triple: &str,
target_triple: &str,
) {
if !config::get_bool("testsuite.abi-cafe") {
eprintln!("[SKIP] abi-cafe");
return;
}
if host_triple != target_triple {
eprintln!("[SKIP] abi-cafe (cross-compilation not supported)");
return;
}
eprintln!("Building sysroot for abi-cafe");
build_sysroot::build_sysroot(
channel,
sysroot_kind,
target_dir,
cg_clif_dylib,
host_triple,
target_triple,
);
eprintln!("Running abi-cafe");
let abi_cafe_path = prepare::ABI_CAFE.source_dir();
env::set_current_dir(abi_cafe_path.clone()).unwrap();
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
let mut cmd = cargo_command("cargo", "run", Some(target_triple), &abi_cafe_path);
cmd.arg("--");
cmd.arg("--pairs");
cmd.args(pairs);
cmd.arg("--add-rustc-codegen-backend");
cmd.arg(format!("cgclif:{}", cg_clif_dylib.display()));
spawn_and_wait(cmd);
}

View file

@ -1,60 +0,0 @@
use super::build_sysroot;
use super::config;
use super::utils::spawn_and_wait;
use build_system::SysrootKind;
use std::env;
use std::path::Path;
use std::process::Command;
pub(crate) fn run(
channel: &str,
sysroot_kind: SysrootKind,
target_dir: &Path,
cg_clif_build_dir: &Path,
host_triple: &str,
target_triple: &str,
) {
if !config::get_bool("testsuite.abi-checker") {
eprintln!("[SKIP] abi-checker");
return;
}
if host_triple != target_triple {
eprintln!("[SKIP] abi-checker (cross-compilation not supported)");
return;
}
eprintln!("Building sysroot for abi-checker");
build_sysroot::build_sysroot(
channel,
sysroot_kind,
target_dir,
cg_clif_build_dir,
host_triple,
target_triple,
);
eprintln!("Running abi-checker");
let mut abi_checker_path = env::current_dir().unwrap();
abi_checker_path.push("abi-checker");
env::set_current_dir(abi_checker_path.clone()).unwrap();
let build_dir = abi_checker_path.parent().unwrap().join("build");
let cg_clif_dylib_path = build_dir.join(if cfg!(windows) { "bin" } else { "lib" }).join(
env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX,
);
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
let mut cmd = Command::new("cargo");
cmd.arg("run");
cmd.arg("--target");
cmd.arg(target_triple);
cmd.arg("--");
cmd.arg("--pairs");
cmd.args(pairs);
cmd.arg("--add-rustc-codegen-backend");
cmd.arg(format!("cgclif:{}", cg_clif_dylib_path.display()));
spawn_and_wait(cmd);
}

View file

@ -1,16 +1,16 @@
use std::env; use std::env;
use std::path::{Path, PathBuf}; use std::path::PathBuf;
use std::process::Command;
use super::utils::is_ci; use super::rustc_info::get_file_name;
use super::utils::{cargo_command, is_ci};
pub(crate) fn build_backend( pub(crate) fn build_backend(
channel: &str, channel: &str,
host_triple: &str, host_triple: &str,
use_unstable_features: bool, use_unstable_features: bool,
) -> PathBuf { ) -> PathBuf {
let mut cmd = Command::new("cargo"); let source_dir = std::env::current_dir().unwrap();
cmd.arg("build").arg("--target").arg(host_triple); let mut cmd = cargo_command("cargo", "build", Some(host_triple), &source_dir);
cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode
@ -41,5 +41,9 @@ pub(crate) fn build_backend(
eprintln!("[BUILD] rustc_codegen_cranelift"); eprintln!("[BUILD] rustc_codegen_cranelift");
super::utils::spawn_and_wait(cmd); super::utils::spawn_and_wait(cmd);
Path::new("target").join(host_triple).join(channel) source_dir
.join("target")
.join(host_triple)
.join(channel)
.join(get_file_name("rustc_codegen_cranelift", "dylib"))
} }

View file

@ -3,14 +3,14 @@ use std::path::{Path, PathBuf};
use std::process::{self, Command}; use std::process::{self, Command};
use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name}; use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
use super::utils::{spawn_and_wait, try_hard_link}; use super::utils::{cargo_command, spawn_and_wait, try_hard_link};
use super::SysrootKind; use super::SysrootKind;
pub(crate) fn build_sysroot( pub(crate) fn build_sysroot(
channel: &str, channel: &str,
sysroot_kind: SysrootKind, sysroot_kind: SysrootKind,
target_dir: &Path, target_dir: &Path,
cg_clif_build_dir: &Path, cg_clif_dylib_src: &Path,
host_triple: &str, host_triple: &str,
target_triple: &str, target_triple: &str,
) { ) {
@ -23,7 +23,6 @@ pub(crate) fn build_sysroot(
fs::create_dir_all(target_dir.join("lib")).unwrap(); fs::create_dir_all(target_dir.join("lib")).unwrap();
// Copy the backend // Copy the backend
let cg_clif_dylib = get_file_name("rustc_codegen_cranelift", "dylib");
let cg_clif_dylib_path = target_dir let cg_clif_dylib_path = target_dir
.join(if cfg!(windows) { .join(if cfg!(windows) {
// Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the // Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
@ -32,8 +31,8 @@ pub(crate) fn build_sysroot(
} else { } else {
"lib" "lib"
}) })
.join(&cg_clif_dylib); .join(get_file_name("rustc_codegen_cranelift", "dylib"));
try_hard_link(cg_clif_build_dir.join(cg_clif_dylib), &cg_clif_dylib_path); try_hard_link(cg_clif_dylib_src, &cg_clif_dylib_path);
// Build and copy rustc and cargo wrappers // Build and copy rustc and cargo wrappers
for wrapper in ["rustc-clif", "cargo-clif"] { for wrapper in ["rustc-clif", "cargo-clif"] {
@ -186,10 +185,10 @@ fn build_clif_sysroot_for_triple(
} }
// Build sysroot // Build sysroot
let mut build_cmd = Command::new("cargo"); let mut build_cmd = cargo_command("cargo", "build", Some(triple), Path::new("build_sysroot"));
build_cmd.arg("build").arg("--target").arg(triple).current_dir("build_sysroot");
let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string(); let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap())); rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
rustflags.push_str(&format!(" --sysroot={}", target_dir.to_str().unwrap()));
if channel == "release" { if channel == "release" {
build_cmd.arg("--release"); build_cmd.arg("--release");
rustflags.push_str(" -Zmir-opt-level=3"); rustflags.push_str(" -Zmir-opt-level=3");

View file

@ -1,4 +1,5 @@
use std::{fs, process}; use std::fs;
use std::process;
fn load_config_file() -> Vec<(String, Option<String>)> { fn load_config_file() -> Vec<(String, Option<String>)> {
fs::read_to_string("config.txt") fs::read_to_string("config.txt")

View file

@ -4,7 +4,7 @@ use std::process;
use self::utils::is_ci; use self::utils::is_ci;
mod abi_checker; mod abi_cafe;
mod build_backend; mod build_backend;
mod build_sysroot; mod build_sysroot;
mod config; mod config;
@ -122,32 +122,23 @@ pub fn main() {
host_triple.clone() host_triple.clone()
}; };
if target_triple.ends_with("-msvc") { let cg_clif_dylib = build_backend::build_backend(channel, &host_triple, use_unstable_features);
eprintln!("The MSVC toolchain is not yet supported by rustc_codegen_cranelift.");
eprintln!("Switch to the MinGW toolchain for Windows support.");
eprintln!("Hint: You can use `rustup set default-host x86_64-pc-windows-gnu` to");
eprintln!("set the global default target to MinGW");
process::exit(1);
}
let cg_clif_build_dir =
build_backend::build_backend(channel, &host_triple, use_unstable_features);
match command { match command {
Command::Test => { Command::Test => {
tests::run_tests( tests::run_tests(
channel, channel,
sysroot_kind, sysroot_kind,
&target_dir, &target_dir,
&cg_clif_build_dir, &cg_clif_dylib,
&host_triple, &host_triple,
&target_triple, &target_triple,
); );
abi_checker::run( abi_cafe::run(
channel, channel,
sysroot_kind, sysroot_kind,
&target_dir, &target_dir,
&cg_clif_build_dir, &cg_clif_dylib,
&host_triple, &host_triple,
&target_triple, &target_triple,
); );
@ -157,7 +148,7 @@ pub fn main() {
channel, channel,
sysroot_kind, sysroot_kind,
&target_dir, &target_dir,
&cg_clif_build_dir, &cg_clif_dylib,
&host_triple, &host_triple,
&target_triple, &target_triple,
); );

View file

@ -1,64 +1,67 @@
use std::env; use std::env;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::ffi::OsString;
use std::fs; use std::fs;
use std::path::Path; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version}; use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
use super::utils::{copy_dir_recursively, spawn_and_wait}; use super::utils::{cargo_command, copy_dir_recursively, spawn_and_wait};
pub(crate) const ABI_CAFE: GitRepo = GitRepo::github(
"Gankra",
"abi-cafe",
"4c6dc8c9c687e2b3a760ff2176ce236872b37212",
"abi-cafe",
);
pub(crate) const RAND: GitRepo =
GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
pub(crate) const REGEX: GitRepo =
GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex");
pub(crate) const PORTABLE_SIMD: GitRepo = GitRepo::github(
"rust-lang",
"portable-simd",
"d5cd4a8112d958bd3a252327e0d069a6363249bd",
"portable-simd",
);
pub(crate) const SIMPLE_RAYTRACER: GitRepo = GitRepo::github(
"ebobby",
"simple-raytracer",
"804a7a21b9e673a482797aa289a18ed480e4d813",
"<none>",
);
pub(crate) fn prepare() { pub(crate) fn prepare() {
if Path::new("download").exists() {
std::fs::remove_dir_all(Path::new("download")).unwrap();
}
std::fs::create_dir_all(Path::new("download")).unwrap();
prepare_sysroot(); prepare_sysroot();
// FIXME maybe install this only locally?
eprintln!("[INSTALL] hyperfine"); eprintln!("[INSTALL] hyperfine");
Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap(); Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
clone_repo_shallow_github( ABI_CAFE.fetch();
"abi-checker", RAND.fetch();
"Gankra", REGEX.fetch();
"abi-checker", PORTABLE_SIMD.fetch();
"a2232d45f202846f5c02203c9f27355360f9a2ff", SIMPLE_RAYTRACER.fetch();
);
apply_patches("abi-checker", Path::new("abi-checker"));
clone_repo_shallow_github(
"rand",
"rust-random",
"rand",
"0f933f9c7176e53b2a3c7952ded484e1783f0bf1",
);
apply_patches("rand", Path::new("rand"));
clone_repo_shallow_github(
"regex",
"rust-lang",
"regex",
"341f207c1071f7290e3f228c710817c280c8dca1",
);
clone_repo_shallow_github(
"portable-simd",
"rust-lang",
"portable-simd",
"b8d6b6844602f80af79cd96401339ec594d472d8",
);
apply_patches("portable-simd", Path::new("portable-simd"));
clone_repo_shallow_github(
"simple-raytracer",
"ebobby",
"simple-raytracer",
"804a7a21b9e673a482797aa289a18ed480e4d813",
);
eprintln!("[LLVM BUILD] simple-raytracer"); eprintln!("[LLVM BUILD] simple-raytracer");
let mut build_cmd = Command::new("cargo"); let build_cmd = cargo_command("cargo", "build", None, &SIMPLE_RAYTRACER.source_dir());
build_cmd.arg("build").env_remove("CARGO_TARGET_DIR").current_dir("simple-raytracer");
spawn_and_wait(build_cmd); spawn_and_wait(build_cmd);
fs::copy( fs::copy(
Path::new("simple-raytracer/target/debug").join(get_file_name("main", "bin")), SIMPLE_RAYTRACER
Path::new("simple-raytracer").join(get_file_name("raytracer_cg_llvm", "bin")), .source_dir()
.join("target")
.join("debug")
.join(get_file_name("main", "bin")),
SIMPLE_RAYTRACER.source_dir().join(get_file_name("raytracer_cg_llvm", "bin")),
) )
.unwrap(); .unwrap();
} }
@ -90,38 +93,78 @@ fn prepare_sysroot() {
apply_patches("sysroot", &sysroot_src); apply_patches("sysroot", &sysroot_src);
} }
pub(crate) struct GitRepo {
url: GitRepoUrl,
rev: &'static str,
patch_name: &'static str,
}
enum GitRepoUrl {
Github { user: &'static str, repo: &'static str },
}
impl GitRepo {
const fn github(
user: &'static str,
repo: &'static str,
rev: &'static str,
patch_name: &'static str,
) -> GitRepo {
GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
}
pub(crate) fn source_dir(&self) -> PathBuf {
match self.url {
GitRepoUrl::Github { user: _, repo } => {
std::env::current_dir().unwrap().join("download").join(repo)
}
}
}
fn fetch(&self) {
match self.url {
GitRepoUrl::Github { user, repo } => {
clone_repo_shallow_github(&self.source_dir(), user, repo, self.rev);
}
}
apply_patches(self.patch_name, &self.source_dir());
}
}
#[allow(dead_code)] #[allow(dead_code)]
fn clone_repo(target_dir: &str, repo: &str, rev: &str) { fn clone_repo(download_dir: &Path, repo: &str, rev: &str) {
eprintln!("[CLONE] {}", repo); eprintln!("[CLONE] {}", repo);
// Ignore exit code as the repo may already have been checked out // Ignore exit code as the repo may already have been checked out
Command::new("git").arg("clone").arg(repo).arg(target_dir).spawn().unwrap().wait().unwrap(); Command::new("git").arg("clone").arg(repo).arg(&download_dir).spawn().unwrap().wait().unwrap();
let mut clean_cmd = Command::new("git"); let mut clean_cmd = Command::new("git");
clean_cmd.arg("checkout").arg("--").arg(".").current_dir(target_dir); clean_cmd.arg("checkout").arg("--").arg(".").current_dir(&download_dir);
spawn_and_wait(clean_cmd); spawn_and_wait(clean_cmd);
let mut checkout_cmd = Command::new("git"); let mut checkout_cmd = Command::new("git");
checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(target_dir); checkout_cmd.arg("checkout").arg("-q").arg(rev).current_dir(download_dir);
spawn_and_wait(checkout_cmd); spawn_and_wait(checkout_cmd);
} }
fn clone_repo_shallow_github(target_dir: &str, username: &str, repo: &str, rev: &str) { fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &str) {
if cfg!(windows) { if cfg!(windows) {
// Older windows doesn't have tar or curl by default. Fall back to using git. // Older windows doesn't have tar or curl by default. Fall back to using git.
clone_repo(target_dir, &format!("https://github.com/{}/{}.git", username, repo), rev); clone_repo(download_dir, &format!("https://github.com/{}/{}.git", user, repo), rev);
return; return;
} }
let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", username, repo, rev); let downloads_dir = std::env::current_dir().unwrap().join("download");
let archive_file = format!("{}.tar.gz", rev);
let archive_dir = format!("{}-{}", repo, rev);
eprintln!("[DOWNLOAD] {}/{} from {}", username, repo, archive_url); let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", user, repo, rev);
let archive_file = downloads_dir.join(format!("{}.tar.gz", rev));
let archive_dir = downloads_dir.join(format!("{}-{}", repo, rev));
eprintln!("[DOWNLOAD] {}/{} from {}", user, repo, archive_url);
// Remove previous results if they exists // Remove previous results if they exists
let _ = std::fs::remove_file(&archive_file); let _ = std::fs::remove_file(&archive_file);
let _ = std::fs::remove_dir_all(&archive_dir); let _ = std::fs::remove_dir_all(&archive_dir);
let _ = std::fs::remove_dir_all(target_dir); let _ = std::fs::remove_dir_all(&download_dir);
// Download zip archive // Download zip archive
let mut download_cmd = Command::new("curl"); let mut download_cmd = Command::new("curl");
@ -130,13 +173,13 @@ fn clone_repo_shallow_github(target_dir: &str, username: &str, repo: &str, rev:
// Unpack tar archive // Unpack tar archive
let mut unpack_cmd = Command::new("tar"); let mut unpack_cmd = Command::new("tar");
unpack_cmd.arg("xf").arg(&archive_file); unpack_cmd.arg("xf").arg(&archive_file).current_dir(downloads_dir);
spawn_and_wait(unpack_cmd); spawn_and_wait(unpack_cmd);
// Rename unpacked dir to the expected name // Rename unpacked dir to the expected name
std::fs::rename(archive_dir, target_dir).unwrap(); std::fs::rename(archive_dir, &download_dir).unwrap();
init_git_repo(Path::new(target_dir)); init_git_repo(&download_dir);
// Cleanup // Cleanup
std::fs::remove_file(archive_file).unwrap(); std::fs::remove_file(archive_file).unwrap();
@ -156,14 +199,20 @@ fn init_git_repo(repo_dir: &Path) {
spawn_and_wait(git_commit_cmd); spawn_and_wait(git_commit_cmd);
} }
fn get_patches(crate_name: &str) -> Vec<OsString> { fn get_patches(source_dir: &Path, crate_name: &str) -> Vec<PathBuf> {
let mut patches: Vec<_> = fs::read_dir("patches") let mut patches: Vec<_> = fs::read_dir(source_dir.join("patches"))
.unwrap() .unwrap()
.map(|entry| entry.unwrap().path()) .map(|entry| entry.unwrap().path())
.filter(|path| path.extension() == Some(OsStr::new("patch"))) .filter(|path| path.extension() == Some(OsStr::new("patch")))
.map(|path| path.file_name().unwrap().to_owned()) .filter(|path| {
.filter(|file_name| { path.file_name()
file_name.to_str().unwrap().split_once("-").unwrap().1.starts_with(crate_name) .unwrap()
.to_str()
.unwrap()
.split_once("-")
.unwrap()
.1
.starts_with(crate_name)
}) })
.collect(); .collect();
patches.sort(); patches.sort();
@ -171,11 +220,18 @@ fn get_patches(crate_name: &str) -> Vec<OsString> {
} }
fn apply_patches(crate_name: &str, target_dir: &Path) { fn apply_patches(crate_name: &str, target_dir: &Path) {
for patch in get_patches(crate_name) { if crate_name == "<none>" {
eprintln!("[PATCH] {:?} <- {:?}", target_dir.file_name().unwrap(), patch); return;
let patch_arg = env::current_dir().unwrap().join("patches").join(patch); }
for patch in get_patches(&std::env::current_dir().unwrap(), crate_name) {
eprintln!(
"[PATCH] {:?} <- {:?}",
target_dir.file_name().unwrap(),
patch.file_name().unwrap()
);
let mut apply_patch_cmd = Command::new("git"); let mut apply_patch_cmd = Command::new("git");
apply_patch_cmd.arg("am").arg(patch_arg).arg("-q").current_dir(target_dir); apply_patch_cmd.arg("am").arg(patch).arg("-q").current_dir(target_dir);
spawn_and_wait(apply_patch_cmd); spawn_and_wait(apply_patch_cmd);
} }
} }

View file

@ -1,7 +1,8 @@
use super::build_sysroot; use super::build_sysroot;
use super::config; use super::config;
use super::prepare;
use super::rustc_info::get_wrapper_file_name; use super::rustc_info::get_wrapper_file_name;
use super::utils::{spawn_and_wait, spawn_and_wait_with_input}; use super::utils::{cargo_command, hyperfine_command, spawn_and_wait, spawn_and_wait_with_input};
use build_system::SysrootKind; use build_system::SysrootKind;
use std::env; use std::env;
use std::ffi::OsStr; use std::ffi::OsStr;
@ -217,103 +218,95 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
TestCase::new("test.rust-random/rand", &|runner| { TestCase::new("test.rust-random/rand", &|runner| {
runner.in_dir(["rand"], |runner| { runner.in_dir(prepare::RAND.source_dir(), |runner| {
runner.run_cargo(["clean"]); runner.run_cargo("clean", []);
if runner.host_triple == runner.target_triple { if runner.host_triple == runner.target_triple {
eprintln!("[TEST] rust-random/rand"); eprintln!("[TEST] rust-random/rand");
runner.run_cargo(["test", "--workspace"]); runner.run_cargo("test", ["--workspace"]);
} else { } else {
eprintln!("[AOT] rust-random/rand"); eprintln!("[AOT] rust-random/rand");
runner.run_cargo([ runner.run_cargo("build", ["--workspace", "--tests"]);
"build",
"--workspace",
"--target",
&runner.target_triple,
"--tests",
]);
} }
}); });
}), }),
TestCase::new("bench.simple-raytracer", &|runner| { TestCase::new("bench.simple-raytracer", &|runner| {
runner.in_dir(["simple-raytracer"], |runner| { runner.in_dir(prepare::SIMPLE_RAYTRACER.source_dir(), |runner| {
let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()); let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()).parse().unwrap();
if runner.host_triple == runner.target_triple { if runner.host_triple == runner.target_triple {
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer"); eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
let mut bench_compile = Command::new("hyperfine"); let prepare = runner.cargo_command("clean", []);
bench_compile.arg("--runs");
bench_compile.arg(&run_runs);
bench_compile.arg("--warmup");
bench_compile.arg("1");
bench_compile.arg("--prepare");
bench_compile.arg(format!("{:?}", runner.cargo_command(["clean"])));
if cfg!(windows) { let llvm_build_cmd = cargo_command("cargo", "build", None, Path::new("."));
bench_compile.arg("cmd /C \"set RUSTFLAGS= && cargo build\"");
} else { let cargo_clif = runner
bench_compile.arg("RUSTFLAGS='' cargo build"); .root_dir
} .clone()
.join("build")
.join(get_wrapper_file_name("cargo-clif", "bin"));
let clif_build_cmd = cargo_command(cargo_clif, "build", None, Path::new("."));
let bench_compile =
hyperfine_command(1, run_runs, Some(prepare), llvm_build_cmd, clif_build_cmd);
bench_compile.arg(format!("{:?}", runner.cargo_command(["build"])));
spawn_and_wait(bench_compile); spawn_and_wait(bench_compile);
eprintln!("[BENCH RUN] ebobby/simple-raytracer"); eprintln!("[BENCH RUN] ebobby/simple-raytracer");
fs::copy(PathBuf::from("./target/debug/main"), PathBuf::from("raytracer_cg_clif")) fs::copy(PathBuf::from("./target/debug/main"), PathBuf::from("raytracer_cg_clif"))
.unwrap(); .unwrap();
let mut bench_run = Command::new("hyperfine"); let bench_run = hyperfine_command(
bench_run.arg("--runs"); 0,
bench_run.arg(&run_runs); run_runs,
bench_run.arg(PathBuf::from("./raytracer_cg_llvm")); None,
bench_run.arg(PathBuf::from("./raytracer_cg_clif")); Command::new("./raytracer_cg_llvm"),
Command::new("./raytracer_cg_clif"),
);
spawn_and_wait(bench_run); spawn_and_wait(bench_run);
} else { } else {
runner.run_cargo(["clean"]); runner.run_cargo("clean", []);
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)"); eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
eprintln!("[COMPILE] ebobby/simple-raytracer"); eprintln!("[COMPILE] ebobby/simple-raytracer");
runner.run_cargo(["build", "--target", &runner.target_triple]); runner.run_cargo("build", []);
eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)"); eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
} }
}); });
}), }),
TestCase::new("test.libcore", &|runner| { TestCase::new("test.libcore", &|runner| {
runner.in_dir(["build_sysroot", "sysroot_src", "library", "core", "tests"], |runner| { runner.in_dir(
runner.run_cargo(["clean"]); std::env::current_dir()
.unwrap()
.join("build_sysroot")
.join("sysroot_src")
.join("library")
.join("core")
.join("tests"),
|runner| {
runner.run_cargo("clean", []);
if runner.host_triple == runner.target_triple { if runner.host_triple == runner.target_triple {
runner.run_cargo(["test"]); runner.run_cargo("test", []);
} else { } else {
eprintln!("Cross-Compiling: Not running tests"); eprintln!("Cross-Compiling: Not running tests");
runner.run_cargo(["build", "--target", &runner.target_triple, "--tests"]); runner.run_cargo("build", ["--tests"]);
} }
}); },
);
}), }),
TestCase::new("test.regex-shootout-regex-dna", &|runner| { TestCase::new("test.regex-shootout-regex-dna", &|runner| {
runner.in_dir(["regex"], |runner| { runner.in_dir(prepare::REGEX.source_dir(), |runner| {
runner.run_cargo(["clean"]); runner.run_cargo("clean", []);
// newer aho_corasick versions throw a deprecation warning // newer aho_corasick versions throw a deprecation warning
let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags); let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
let mut build_cmd = runner.cargo_command([ let mut build_cmd = runner.cargo_command("build", ["--example", "shootout-regex-dna"]);
"build",
"--example",
"shootout-regex-dna",
"--target",
&runner.target_triple,
]);
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone()); build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
spawn_and_wait(build_cmd); spawn_and_wait(build_cmd);
if runner.host_triple == runner.target_triple { if runner.host_triple == runner.target_triple {
let mut run_cmd = runner.cargo_command([ let mut run_cmd = runner.cargo_command("run", ["--example", "shootout-regex-dna"]);
"run",
"--example",
"shootout-regex-dna",
"--target",
&runner.target_triple,
]);
run_cmd.env("RUSTFLAGS", lint_rust_flags); run_cmd.env("RUSTFLAGS", lint_rust_flags);
let input = let input =
@ -353,41 +346,43 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
}); });
}), }),
TestCase::new("test.regex", &|runner| { TestCase::new("test.regex", &|runner| {
runner.in_dir(["regex"], |runner| { runner.in_dir(prepare::REGEX.source_dir(), |runner| {
runner.run_cargo(["clean"]); runner.run_cargo("clean", []);
// newer aho_corasick versions throw a deprecation warning // newer aho_corasick versions throw a deprecation warning
let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags); let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
if runner.host_triple == runner.target_triple { if runner.host_triple == runner.target_triple {
let mut run_cmd = runner.cargo_command([ let mut run_cmd = runner.cargo_command(
"test", "test",
"--tests", [
"--", "--tests",
"--exclude-should-panic", "--",
"--test-threads", "--exclude-should-panic",
"1", "--test-threads",
"-Zunstable-options", "1",
"-q", "-Zunstable-options",
]); "-q",
],
);
run_cmd.env("RUSTFLAGS", lint_rust_flags); run_cmd.env("RUSTFLAGS", lint_rust_flags);
spawn_and_wait(run_cmd); spawn_and_wait(run_cmd);
} else { } else {
eprintln!("Cross-Compiling: Not running tests"); eprintln!("Cross-Compiling: Not running tests");
let mut build_cmd = let mut build_cmd =
runner.cargo_command(["build", "--tests", "--target", &runner.target_triple]); runner.cargo_command("build", ["--tests", "--target", &runner.target_triple]);
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone()); build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
spawn_and_wait(build_cmd); spawn_and_wait(build_cmd);
} }
}); });
}), }),
TestCase::new("test.portable-simd", &|runner| { TestCase::new("test.portable-simd", &|runner| {
runner.in_dir(["portable-simd"], |runner| { runner.in_dir(prepare::PORTABLE_SIMD.source_dir(), |runner| {
runner.run_cargo(["clean"]); runner.run_cargo("clean", []);
runner.run_cargo(["build", "--all-targets", "--target", &runner.target_triple]); runner.run_cargo("build", ["--all-targets", "--target", &runner.target_triple]);
if runner.host_triple == runner.target_triple { if runner.host_triple == runner.target_triple {
runner.run_cargo(["test", "-q"]); runner.run_cargo("test", ["-q"]);
} }
}); });
}), }),
@ -397,7 +392,7 @@ pub(crate) fn run_tests(
channel: &str, channel: &str,
sysroot_kind: SysrootKind, sysroot_kind: SysrootKind,
target_dir: &Path, target_dir: &Path,
cg_clif_build_dir: &Path, cg_clif_dylib: &Path,
host_triple: &str, host_triple: &str,
target_triple: &str, target_triple: &str,
) { ) {
@ -408,7 +403,7 @@ pub(crate) fn run_tests(
channel, channel,
SysrootKind::None, SysrootKind::None,
&target_dir, &target_dir,
cg_clif_build_dir, cg_clif_dylib,
&host_triple, &host_triple,
&target_triple, &target_triple,
); );
@ -427,7 +422,7 @@ pub(crate) fn run_tests(
channel, channel,
sysroot_kind, sysroot_kind,
&target_dir, &target_dir,
cg_clif_build_dir, cg_clif_dylib,
&host_triple, &host_triple,
&target_triple, &target_triple,
); );
@ -521,16 +516,8 @@ impl TestRunner {
} }
} }
fn in_dir<'a, I, F>(&self, dir: I, callback: F) fn in_dir(&self, new: impl AsRef<Path>, callback: impl FnOnce(&TestRunner)) {
where
I: IntoIterator<Item = &'a str>,
F: FnOnce(&TestRunner),
{
let current = env::current_dir().unwrap(); let current = env::current_dir().unwrap();
let mut new = current.clone();
for d in dir {
new.push(d);
}
env::set_current_dir(new).unwrap(); env::set_current_dir(new).unwrap();
callback(self); callback(self);
@ -595,25 +582,29 @@ impl TestRunner {
spawn_and_wait(cmd); spawn_and_wait(cmd);
} }
fn cargo_command<I, S>(&self, args: I) -> Command fn cargo_command<'a, I>(&self, subcommand: &str, args: I) -> Command
where where
I: IntoIterator<Item = S>, I: IntoIterator<Item = &'a str>,
S: AsRef<OsStr>,
{ {
let mut cargo_clif = self.root_dir.clone(); let mut cargo_clif = self.root_dir.clone();
cargo_clif.push("build"); cargo_clif.push("build");
cargo_clif.push(get_wrapper_file_name("cargo-clif", "bin")); cargo_clif.push(get_wrapper_file_name("cargo-clif", "bin"));
let mut cmd = Command::new(cargo_clif); let mut cmd = cargo_command(
cargo_clif,
subcommand,
if subcommand == "clean" { None } else { Some(&self.target_triple) },
Path::new("."),
);
cmd.args(args); cmd.args(args);
cmd.env("RUSTFLAGS", &self.rust_flags); cmd.env("RUSTFLAGS", &self.rust_flags);
cmd cmd
} }
fn run_cargo<'a, I>(&self, args: I) fn run_cargo<'a, I>(&self, subcommand: &str, args: I)
where where
I: IntoIterator<Item = &'a str>, I: IntoIterator<Item = &'a str>,
{ {
spawn_and_wait(self.cargo_command(args)); spawn_and_wait(self.cargo_command(subcommand, args));
} }
} }

View file

@ -4,6 +4,52 @@ use std::io::Write;
use std::path::Path; use std::path::Path;
use std::process::{self, Command, Stdio}; use std::process::{self, Command, Stdio};
pub(crate) fn cargo_command(
cargo: impl AsRef<Path>,
subcommand: &str,
triple: Option<&str>,
source_dir: &Path,
) -> Command {
let mut cmd = Command::new(cargo.as_ref());
cmd.arg(subcommand)
.arg("--manifest-path")
.arg(source_dir.join("Cargo.toml"))
.arg("--target-dir")
.arg(source_dir.join("target"));
if let Some(triple) = triple {
cmd.arg("--target").arg(triple);
}
cmd
}
pub(crate) fn hyperfine_command(
warmup: u64,
runs: u64,
prepare: Option<Command>,
a: Command,
b: Command,
) -> Command {
let mut bench = Command::new("hyperfine");
if warmup != 0 {
bench.arg("--warmup").arg(warmup.to_string());
}
if runs != 0 {
bench.arg("--runs").arg(runs.to_string());
}
if let Some(prepare) = prepare {
bench.arg("--prepare").arg(format!("{:?}", prepare));
}
bench.arg(format!("{:?}", a)).arg(format!("{:?}", b));
bench
}
#[track_caller] #[track_caller]
pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) { pub(crate) fn try_hard_link(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
let src = src.as_ref(); let src = src.as_ref();

View file

@ -3,4 +3,8 @@ set -e
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version} rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
rm -rf target/ build/ perf.data{,.old} y.bin rm -rf target/ build/ perf.data{,.old} y.bin
rm -rf rand/ regex/ simple-raytracer/ portable-simd/ abi-checker/ rm -rf download/
# Kept for now in case someone updates their checkout of cg_clif before running clean_all.sh
# FIXME remove at some point in the future
rm -rf rand/ regex/ simple-raytracer/ portable-simd/ abi-checker/ abi-cafe/

View file

@ -49,4 +49,4 @@ test.regex-shootout-regex-dna
test.regex test.regex
test.portable-simd test.portable-simd
testsuite.abi-checker testsuite.abi-cafe

View file

@ -5,7 +5,6 @@
// Test that we can handle unsized types with an extern type tail part. // Test that we can handle unsized types with an extern type tail part.
// Regression test for issue #91827. // Regression test for issue #91827.
#![feature(const_ptr_offset_from)]
#![feature(extern_types)] #![feature(extern_types)]
use std::ptr::addr_of; use std::ptr::addr_of;

View file

@ -559,16 +559,22 @@ pub union MaybeUninit<T> {
pub mod intrinsics { pub mod intrinsics {
extern "rust-intrinsic" { extern "rust-intrinsic" {
#[rustc_safe_intrinsic]
pub fn abort() -> !; pub fn abort() -> !;
#[rustc_safe_intrinsic]
pub fn size_of<T>() -> usize; pub fn size_of<T>() -> usize;
pub fn size_of_val<T: ?::Sized>(val: *const T) -> usize; pub fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
#[rustc_safe_intrinsic]
pub fn min_align_of<T>() -> usize; pub fn min_align_of<T>() -> usize;
pub fn min_align_of_val<T: ?::Sized>(val: *const T) -> usize; pub fn min_align_of_val<T: ?::Sized>(val: *const T) -> usize;
pub fn copy<T>(src: *const T, dst: *mut T, count: usize); pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
pub fn transmute<T, U>(e: T) -> U; pub fn transmute<T, U>(e: T) -> U;
pub fn ctlz_nonzero<T>(x: T) -> T; pub fn ctlz_nonzero<T>(x: T) -> T;
#[rustc_safe_intrinsic]
pub fn needs_drop<T: ?::Sized>() -> bool; pub fn needs_drop<T: ?::Sized>() -> bool;
#[rustc_safe_intrinsic]
pub fn bitreverse<T>(x: T) -> T; pub fn bitreverse<T>(x: T) -> T;
#[rustc_safe_intrinsic]
pub fn bswap<T>(x: T) -> T; pub fn bswap<T>(x: T) -> T;
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize); pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
} }

View file

@ -93,6 +93,7 @@ fn start<T: Termination + 'static>(
main: fn() -> T, main: fn() -> T,
argc: isize, argc: isize,
argv: *const *const u8, argv: *const *const u8,
_sigpipe: u8,
) -> isize { ) -> isize {
if argc == 3 { if argc == 3 {
unsafe { puts(*argv as *const i8); } unsafe { puts(*argv as *const i8); }

View file

@ -0,0 +1,29 @@
From 2b15fee2bb5fd14e34c7e17e44d99cb34f4c555d Mon Sep 17 00:00:00 2001
From: Afonso Bordado <afonsobordado@az8.co>
Date: Tue, 27 Sep 2022 07:55:17 +0100
Subject: [PATCH] Disable some test on x86_64-pc-windows-gnu
---
src/report.rs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/report.rs b/src/report.rs
index eeec614..f582867 100644
--- a/src/report.rs
+++ b/src/report.rs
@@ -48,6 +48,12 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn AbiImpl, callee: &dyn AbiImpl
//
// THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES
+ // x86_64-pc-windows-gnu has some broken i128 tests that aren't disabled by default
+ if cfg!(all(target_os = "windows", target_env = "gnu")) && test.test_name == "ui128" {
+ result.run = Link;
+ result.check = Pass(Link);
+ }
+
// END OF VENDOR RESERVED AREA
//
//
--
2.30.1.windows.1

View file

@ -1,36 +0,0 @@
From 1a315ba225577dbbd1f449d9609f16f984f68708 Mon Sep 17 00:00:00 2001
From: Afonso Bordado <afonso360@users.noreply.github.com>
Date: Fri, 12 Aug 2022 22:51:58 +0000
Subject: [PATCH] Disable abi-checker tests
---
src/report.rs | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/report.rs b/src/report.rs
index 7346f5e..8347762 100644
--- a/src/report.rs
+++ b/src/report.rs
@@ -45,6 +45,20 @@ pub fn get_test_rules(test: &TestKey, caller: &dyn AbiImpl, callee: &dyn AbiImpl
//
// THIS AREA RESERVED FOR VENDORS TO APPLY PATCHES
+ // Currently MSVC has some broken ABI issues. Furthermore, they cause
+ // a STATUS_ACCESS_VIOLATION, so we can't even run them. Ensure that they compile and link.
+ if cfg!(windows) && (test.test_name == "bool" || test.test_name == "ui128") {
+ result.run = Link;
+ result.check = Pass(Link);
+ }
+
+ // structs is broken in the current release of cranelift for aarch64.
+ // It has been fixed for cranelift 0.88: https://github.com/bytecodealliance/wasmtime/pull/4634
+ if cfg!(target_arch = "aarch64") && test.test_name == "structs" {
+ result.run = Link;
+ result.check = Pass(Link);
+ }
+
// END OF VENDOR RESERVED AREA
//
//
--
2.34.1

View file

@ -1,80 +1,29 @@
From 97c473937382a5b5858d9cce3c947855d23b2dc5 Mon Sep 17 00:00:00 2001 From b742f03694b920cc14400727d54424e8e1b60928 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com> From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Thu, 18 Nov 2021 19:28:40 +0100 Date: Thu, 18 Nov 2021 19:28:40 +0100
Subject: [PATCH] Disable unsupported tests Subject: [PATCH] Disable unsupported tests
--- ---
crates/core_simd/src/math.rs | 6 ++++++ crates/core_simd/src/elements/int.rs | 8 ++++++++
crates/core_simd/src/vector.rs | 2 ++ crates/core_simd/src/elements/uint.rs | 4 ++++
crates/core_simd/tests/masks.rs | 2 ++ crates/core_simd/src/masks/full_masks.rs | 6 ++++++
crates/core_simd/tests/ops_macros.rs | 4 ++++ crates/core_simd/src/vector.rs | 2 ++
4 files changed, 14 insertions(+) crates/core_simd/tests/masks.rs | 3 ---
5 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs
index 2bae414..2f87499 100644
--- a/crates/core_simd/src/math.rs
+++ b/crates/core_simd/src/math.rs
@@ -5,6 +5,7 @@ macro_rules! impl_uint_arith {
($($ty:ty),+) => {
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
+ /*
/// Lanewise saturating add.
///
/// # Examples
@@ -43,6 +44,7 @@ macro_rules! impl_uint_arith {
pub fn saturating_sub(self, second: Self) -> Self {
unsafe { simd_saturating_sub(self, second) }
}
+ */
})+
}
}
@@ -51,6 +53,7 @@ macro_rules! impl_int_arith {
($($ty:ty),+) => {
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
+ /*
/// Lanewise saturating add.
///
/// # Examples
@@ -89,6 +92,7 @@ macro_rules! impl_int_arith {
pub fn saturating_sub(self, second: Self) -> Self {
unsafe { simd_saturating_sub(self, second) }
}
+ */
/// Lanewise absolute value, implemented in Rust.
/// Every lane becomes its absolute value.
@@ -109,6 +113,7 @@ macro_rules! impl_int_arith {
(self^m) - m
}
+ /*
/// Lanewise saturating absolute value, implemented in Rust.
/// As abs(), except the MIN value becomes MAX instead of itself.
///
@@ -151,6 +156,7 @@ macro_rules! impl_int_arith {
pub fn saturating_neg(self) -> Self {
Self::splat(0).saturating_sub(self)
}
+ */
})+
}
}
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index 7c5ec2b..c8631e8 100644 index e8e8f68..7173c24 100644
--- a/crates/core_simd/src/vector.rs --- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs +++ b/crates/core_simd/src/vector.rs
@@ -75,6 +75,7 @@ where @@ -250,6 +250,7 @@ where
Self(array) unsafe { intrinsics::simd_cast(self) }
} }
+ /* + /*
/// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector. /// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
/// If an index is out-of-bounds, the lane is instead selected from the `or` vector. /// If an index is out-of-bounds, the lane is instead selected from the `or` vector.
/// ///
@@ -297,6 +298,7 @@ where @@ -473,6 +474,7 @@ where
// Cleared ☢️ *mut T Zone // Cleared ☢️ *mut T Zone
} }
} }
@ -82,26 +31,5 @@ index 7c5ec2b..c8631e8 100644
} }
impl<T, const LANES: usize> Copy for Simd<T, LANES> impl<T, const LANES: usize> Copy for Simd<T, LANES>
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
index 6a8ecd3..68fcb49 100644
--- a/crates/core_simd/tests/masks.rs
+++ b/crates/core_simd/tests/masks.rs
@@ -68,6 +68,7 @@ macro_rules! test_mask_api {
assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
}
+ /*
#[cfg(feature = "generic_const_exprs")]
#[test]
fn roundtrip_bitmask_conversion() {
@@ -80,6 +81,7 @@ macro_rules! test_mask_api {
assert_eq!(bitmask, [0b01001001, 0b10000011]);
assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
}
+ */
}
}
}
-- --
2.26.2.7.g19db9cfb68 2.25.1

View file

@ -0,0 +1,47 @@
From eec874c889b8d24e5ad50faded24288150f057b1 Mon Sep 17 00:00:00 2001
From: Afonso Bordado <afonsobordado@az8.co>
Date: Tue, 27 Sep 2022 08:13:58 +0100
Subject: [PATCH] Disable rand tests on mingw
---
rand_distr/src/pareto.rs | 2 ++
rand_distr/tests/value_stability.rs | 4 ++++
2 files changed, 6 insertions(+)
diff --git a/rand_distr/src/pareto.rs b/rand_distr/src/pareto.rs
index 217899e..9cedeb7 100644
--- a/rand_distr/src/pareto.rs
+++ b/rand_distr/src/pareto.rs
@@ -107,6 +107,8 @@ mod tests {
}
#[test]
+ // This is broken on x86_64-pc-windows-gnu presumably due to a broken powf implementation
+ #[cfg_attr(all(target_os = "windows", target_env = "gnu"), ignore)]
fn value_stability() {
fn test_samples<F: Float + core::fmt::Debug, D: Distribution<F>>(
distr: D, zero: F, expected: &[F],
diff --git a/rand_distr/tests/value_stability.rs b/rand_distr/tests/value_stability.rs
index 192ba74..0101ace 100644
--- a/rand_distr/tests/value_stability.rs
+++ b/rand_distr/tests/value_stability.rs
@@ -72,6 +72,8 @@ fn unit_disc_stability() {
}
#[test]
+// This is broken on x86_64-pc-windows-gnu
+#[cfg_attr(all(target_os = "windows", target_env = "gnu"), ignore)]
fn pareto_stability() {
test_samples(213, Pareto::new(1.0, 1.0).unwrap(), &[
1.0423688f32, 2.1235929, 4.132709, 1.4679428,
@@ -143,6 +145,8 @@ fn inverse_gaussian_stability() {
}
#[test]
+// This is broken on x86_64-pc-windows-gnu
+#[cfg_attr(all(target_os = "windows", target_env = "gnu"), ignore)]
fn gamma_stability() {
// Gamma has 3 cases: shape == 1, shape < 1, shape > 1
test_samples(223, Gamma::new(1.0, 5.0).unwrap(), &[
--
2.25.1

View file

@ -1,3 +1,3 @@
[toolchain] [toolchain]
channel = "nightly-2022-08-24" channel = "nightly-2022-10-23"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"] components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View file

@ -10,6 +10,8 @@ git fetch
git checkout -- . git checkout -- .
git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')"
git am ../patches/*-sysroot-*.patch
git apply - <<EOF git apply - <<EOF
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index d95b5b7f17f..00b6f0e3635 100644 index d95b5b7f17f..00b6f0e3635 100644
@ -66,3 +68,7 @@ popd
# FIXME remove once inline asm is fully supported # FIXME remove once inline asm is fully supported
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc" export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
# Allow the testsuite to use llvm tools
host_triple=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ")
export LLVM_BIN_DIR="$(rustc --print sysroot)/lib/rustlib/$host_triple/bin"

View file

@ -29,10 +29,6 @@ rm src/test/incremental/change_crate_dep_kind.rs
rm src/test/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101) rm src/test/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abort instead of exit(101)
# requires compiling with -Cpanic=unwind # requires compiling with -Cpanic=unwind
rm src/test/ui/test-attrs/test-fn-signature-verification-for-explicit-return-type.rs # "Cannot run dynamic test fn out-of-process"
rm src/test/ui/async-await/async-fn-size-moved-locals.rs # -Cpanic=abort shrinks some generator by one byte
rm src/test/ui/async-await/async-fn-size-uninit-locals.rs # same
rm src/test/ui/generator/size-moved-locals.rs # same
rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/ rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/
# vendor intrinsics # vendor intrinsics
@ -67,6 +63,7 @@ rm src/test/ui/target-feature/missing-plusminus.rs # error not implemented
rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
rm -r src/test/run-make/emit-named-files # requires full --emit support rm -r src/test/run-make/emit-named-files # requires full --emit support
rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented
rm src/test/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
# optimization tests # optimization tests
# ================== # ==================
@ -110,12 +107,13 @@ rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unorde
# bugs in the test suite # bugs in the test suite
# ====================== # ======================
rm src/test/ui/backtrace.rs # TODO warning rm src/test/ui/backtrace.rs # TODO warning
rm src/test/ui/empty_global_asm.rs # TODO add needs-asm-support
rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support
rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason # not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
rm -r src/test/run-make/native-link-modifier-bundle rm -r src/test/run-make/native-link-modifier-bundle
rm src/test/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
echo "[TEST] rustc test suite" echo "[TEST] rustc test suite"
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental} RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui,incremental}
popd popd

View file

@ -465,7 +465,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
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); let sig = fx.bcx.import_signature(sig);
(CallTarget::Indirect(sig, method), Some(ptr)) (CallTarget::Indirect(sig, method), Some(ptr.get_addr(fx)))
} }
// Normal call // Normal call
@ -560,7 +560,19 @@ pub(crate) fn codegen_drop<'tcx>(
// we don't actually need to drop anything // we don't actually need to drop anything
} else { } else {
match ty.kind() { match ty.kind() {
ty::Dynamic(..) => { ty::Dynamic(_, _, ty::Dyn) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn Trait)
// which is: exists<T> ( *mut T, Vtable<T: Trait> )
// args[0] args[1]
//
// args = ( Data, Vtable )
// |
// v
// /-------\
// | ... |
// \-------/
//
let (ptr, vtable) = drop_place.to_ptr_maybe_unsized(); let (ptr, vtable) = drop_place.to_ptr_maybe_unsized();
let ptr = ptr.get_addr(fx); let ptr = ptr.get_addr(fx);
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable.unwrap()); let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable.unwrap());
@ -578,6 +590,43 @@ pub(crate) fn codegen_drop<'tcx>(
let sig = fx.bcx.import_signature(sig); let sig = fx.bcx.import_signature(sig);
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]); fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
} }
ty::Dynamic(_, _, ty::DynStar) => {
// IN THIS ARM, WE HAVE:
// ty = *mut (dyn* Trait)
// which is: *mut exists<T: sizeof(T) == sizeof(usize)> (T, Vtable<T: Trait>)
//
// args = [ * ]
// |
// v
// ( Data, Vtable )
// |
// v
// /-------\
// | ... |
// \-------/
//
//
// WE CAN CONVERT THIS INTO THE ABOVE LOGIC BY DOING
//
// data = &(*args[0]).0 // gives a pointer to Data above (really the same pointer)
// vtable = (*args[0]).1 // loads the vtable out
// (data, vtable) // an equivalent Rust `*mut dyn Trait`
//
// SO THEN WE CAN USE THE ABOVE CODE.
let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx);
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable);
let virtual_drop = Instance {
def: ty::InstanceDef::Virtual(drop_instance.def_id(), 0),
substs: drop_instance.substs,
};
let fn_abi =
RevealAllLayoutCx(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 = fx.bcx.import_signature(sig);
fx.bcx.ins().call_indirect(sig, drop_fn, &[data]);
}
_ => { _ => {
assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _))); assert!(!matches!(drop_instance.def, InstanceDef::Virtual(_, _)));

View file

@ -78,7 +78,7 @@ fn codegen_inner(
let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap(); let callee_func_id = module.declare_function(&callee_name, Linkage::Import, &sig).unwrap();
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone()); ctx.func.signature = sig.clone();
{ {
let mut func_ctx = FunctionBuilderContext::new(); let mut func_ctx = FunctionBuilderContext::new();
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);
@ -116,7 +116,7 @@ fn codegen_inner(
let callee_func_id = module.declare_function(callee_name, Linkage::Import, &sig).unwrap(); let callee_func_id = module.declare_function(callee_name, Linkage::Import, &sig).unwrap();
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig); ctx.func.signature = sig;
{ {
let mut func_ctx = FunctionBuilderContext::new(); let mut func_ctx = FunctionBuilderContext::new();
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

View file

@ -159,6 +159,8 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
let err = err.to_string(); let err = err.to_string();
if err == "Unknown file magic" { if err == "Unknown file magic" {
// Not an object file; skip it. // Not an object file; skip it.
} else if object::read::archive::ArchiveFile::parse(&*data).is_ok() {
// Nested archive file; skip it.
} else { } else {
sess.fatal(&format!( sess.fatal(&format!(
"error parsing `{}` during archive creation: {}", "error parsing `{}` during archive creation: {}",

View file

@ -6,6 +6,8 @@ use rustc_middle::ty::adjustment::PointerCast;
use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::layout::FnAbiOf;
use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::print::with_no_trimmed_paths;
use cranelift_codegen::ir::UserFuncName;
use crate::constant::ConstantCx; use crate::constant::ConstantCx;
use crate::debuginfo::FunctionDebugContext; use crate::debuginfo::FunctionDebugContext;
use crate::prelude::*; use crate::prelude::*;
@ -64,7 +66,7 @@ pub(crate) fn codegen_fn<'tcx>(
let mut func_ctx = FunctionBuilderContext::new(); let mut func_ctx = FunctionBuilderContext::new();
let mut func = cached_func; let mut func = cached_func;
func.clear(); func.clear();
func.name = ExternalName::user(0, func_id.as_u32()); func.name = UserFuncName::user(0, func_id.as_u32());
func.signature = sig; func.signature = sig;
func.collect_debug_info(); func.collect_debug_info();
@ -706,9 +708,9 @@ fn codegen_stmt<'tcx>(
let operand = codegen_operand(fx, operand); let operand = codegen_operand(fx, operand);
operand.unsize_value(fx, lval); operand.unsize_value(fx, lval);
} }
Rvalue::Cast(CastKind::DynStar, _, _) => { Rvalue::Cast(CastKind::DynStar, ref operand, _) => {
// FIXME(dyn-star) let operand = codegen_operand(fx, operand);
unimplemented!() operand.coerce_dyn_star(fx, lval);
} }
Rvalue::Discriminant(place) => { Rvalue::Discriminant(place) => {
let place = codegen_place(fx, place); let place = codegen_place(fx, place);
@ -922,7 +924,7 @@ pub(crate) fn codegen_operand<'tcx>(
let cplace = codegen_place(fx, *place); let cplace = codegen_place(fx, *place);
cplace.to_cvalue(fx) cplace.to_cvalue(fx)
} }
Operand::Constant(const_) => crate::constant::codegen_constant(fx, const_), Operand::Constant(const_) => crate::constant::codegen_constant_operand(fx, const_),
} }
} }

View file

@ -10,6 +10,7 @@ pub(super) struct ConcurrencyLimiter {
helper_thread: Option<HelperThread>, helper_thread: Option<HelperThread>,
state: Arc<Mutex<state::ConcurrencyLimiterState>>, state: Arc<Mutex<state::ConcurrencyLimiterState>>,
available_token_condvar: Arc<Condvar>, available_token_condvar: Arc<Condvar>,
finished: bool,
} }
impl ConcurrencyLimiter { impl ConcurrencyLimiter {
@ -32,6 +33,7 @@ impl ConcurrencyLimiter {
helper_thread: Some(helper_thread), helper_thread: Some(helper_thread),
state, state,
available_token_condvar: Arc::new(Condvar::new()), available_token_condvar: Arc::new(Condvar::new()),
finished: false,
} }
} }
@ -56,16 +58,23 @@ impl ConcurrencyLimiter {
let mut state = self.state.lock().unwrap(); let mut state = self.state.lock().unwrap();
state.job_already_done(); state.job_already_done();
} }
}
impl Drop for ConcurrencyLimiter { pub(crate) fn finished(mut self) {
fn drop(&mut self) {
//
self.helper_thread.take(); self.helper_thread.take();
// Assert that all jobs have finished // Assert that all jobs have finished
let state = Mutex::get_mut(Arc::get_mut(&mut self.state).unwrap()).unwrap(); let state = Mutex::get_mut(Arc::get_mut(&mut self.state).unwrap()).unwrap();
state.assert_done(); state.assert_done();
self.finished = true;
}
}
impl Drop for ConcurrencyLimiter {
fn drop(&mut self) {
if !self.finished && !std::thread::panicking() {
panic!("Forgot to call finished() on ConcurrencyLimiter");
}
} }
} }

View file

@ -7,7 +7,6 @@ use rustc_middle::mir::interpret::{
}; };
use rustc_span::DUMMY_SP; use rustc_span::DUMMY_SP;
use cranelift_codegen::ir::GlobalValueData;
use cranelift_module::*; use cranelift_module::*;
use crate::prelude::*; use crate::prelude::*;
@ -81,52 +80,45 @@ pub(crate) fn codegen_tls_ref<'tcx>(
CValue::by_val(tls_ptr, layout) CValue::by_val(tls_ptr, layout)
} }
fn codegen_static_ref<'tcx>( pub(crate) fn eval_mir_constant<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
def_id: DefId, constant: &Constant<'tcx>,
layout: TyAndLayout<'tcx>, ) -> (ConstValue<'tcx>, Ty<'tcx>) {
) -> CPlace<'tcx> { let constant_kind = fx.monomorphize(constant.literal);
let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); let uv = match constant_kind {
let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); ConstantKind::Ty(const_) => match const_.kind() {
if fx.clif_comments.enabled() { ty::ConstKind::Unevaluated(uv) => uv.expand(),
fx.add_comment(local_data_id, format!("{:?}", def_id)); ty::ConstKind::Value(val) => {
} return (fx.tcx.valtree_to_const_val((const_.ty(), val)), const_.ty());
let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); }
assert!(!layout.is_unsized(), "unsized statics aren't supported"); err => span_bug!(
assert!( constant.span,
matches!( "encountered bad ConstKind after monomorphizing: {:?}",
fx.bcx.func.global_values[local_data_id], err
GlobalValueData::Symbol { tls: false, .. } ),
), },
"tls static referenced without Rvalue::ThreadLocalRef" ConstantKind::Unevaluated(mir::UnevaluatedConst { def, .. }, _)
); if fx.tcx.is_static(def.did) =>
CPlace::for_ptr(crate::pointer::Pointer::new(global_ptr), layout) {
span_bug!(constant.span, "MIR constant refers to static");
}
ConstantKind::Unevaluated(uv, _) => uv,
ConstantKind::Val(val, _) => return (val, constant_kind.ty()),
};
(
fx.tcx.const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).unwrap_or_else(|_err| {
span_bug!(constant.span, "erroneous constant not captured by required_consts");
}),
constant_kind.ty(),
)
} }
pub(crate) fn codegen_constant<'tcx>( pub(crate) fn codegen_constant_operand<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
constant: &Constant<'tcx>, constant: &Constant<'tcx>,
) -> CValue<'tcx> { ) -> CValue<'tcx> {
let (const_val, ty) = match fx.monomorphize(constant.literal) { let (const_val, ty) = eval_mir_constant(fx, constant);
ConstantKind::Ty(const_) => unreachable!("{:?}", const_),
ConstantKind::Unevaluated(mir::UnevaluatedConst { def, substs, promoted }, ty)
if fx.tcx.is_static(def.did) =>
{
assert!(substs.is_empty());
assert!(promoted.is_none());
return codegen_static_ref(fx, def.did, fx.layout_of(ty)).to_cvalue(fx);
}
ConstantKind::Unevaluated(unevaluated, ty) => {
match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) {
Ok(const_val) => (const_val, ty),
Err(_) => {
span_bug!(constant.span, "erroneous constant not captured by required_consts");
}
}
}
ConstantKind::Val(val, ty) => (val, ty),
};
codegen_const_value(fx, const_val, ty) codegen_const_value(fx, const_val, ty)
} }
@ -244,7 +236,7 @@ pub(crate) fn codegen_const_value<'tcx>(
} }
} }
pub(crate) fn pointer_for_allocation<'tcx>( fn pointer_for_allocation<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
alloc: ConstAllocation<'tcx>, alloc: ConstAllocation<'tcx>,
) -> crate::pointer::Pointer { ) -> crate::pointer::Pointer {
@ -467,14 +459,13 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
operand: &Operand<'tcx>, operand: &Operand<'tcx>,
) -> Option<ConstValue<'tcx>> { ) -> Option<ConstValue<'tcx>> {
match operand { match operand {
Operand::Constant(const_) => match const_.literal { Operand::Constant(const_) => match fx.monomorphize(const_.literal) {
ConstantKind::Ty(const_) => fx ConstantKind::Ty(const_) => Some(
.monomorphize(const_) const_.eval_for_mir(fx.tcx, ParamEnv::reveal_all()).try_to_value(fx.tcx).unwrap(),
.eval_for_mir(fx.tcx, ParamEnv::reveal_all()) ),
.try_to_value(fx.tcx),
ConstantKind::Val(val, _) => Some(val), ConstantKind::Val(val, _) => Some(val),
ConstantKind::Unevaluated(uv, _) => { ConstantKind::Unevaluated(uv, _) => {
fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).ok() Some(fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).unwrap())
} }
}, },
// FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored

View file

@ -106,7 +106,7 @@ impl OngoingCodegen {
} }
} }
drop(self.concurrency_limiter); self.concurrency_limiter.finished();
( (
CodegenResults { CodegenResults {

View file

@ -67,13 +67,12 @@ fn create_jit_module(
hotswap: bool, hotswap: bool,
) -> (JITModule, CodegenCx) { ) -> (JITModule, CodegenCx) {
let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string()); let crate_info = CrateInfo::new(tcx, "dummy_target_cpu".to_string());
let imported_symbols = load_imported_symbols_for_jit(tcx.sess, crate_info);
let isa = crate::build_isa(tcx.sess, backend_config); let isa = crate::build_isa(tcx.sess, backend_config);
let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names()); let mut jit_builder = JITBuilder::with_isa(isa, cranelift_module::default_libcall_names());
jit_builder.hotswap(hotswap); jit_builder.hotswap(hotswap);
crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); crate::compiler_builtins::register_functions_for_jit(&mut jit_builder);
jit_builder.symbols(imported_symbols); jit_builder.symbol_lookup_fn(dep_symbol_lookup_fn(tcx.sess, crate_info));
jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8); jit_builder.symbol("__clif_jit_fn", clif_jit_fn as *const u8);
let mut jit_module = JITModule::new(jit_builder); let mut jit_module = JITModule::new(jit_builder);
@ -286,10 +285,10 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
}) })
} }
fn load_imported_symbols_for_jit( fn dep_symbol_lookup_fn(
sess: &Session, sess: &Session,
crate_info: CrateInfo, crate_info: CrateInfo,
) -> Vec<(String, *const u8)> { ) -> Box<dyn Fn(&str) -> Option<*const u8>> {
use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::dependency_format::Linkage;
let mut dylib_paths = Vec::new(); let mut dylib_paths = Vec::new();
@ -316,39 +315,23 @@ fn load_imported_symbols_for_jit(
} }
} }
let mut imported_symbols = Vec::new(); let imported_dylibs = Box::leak(
for path in dylib_paths { dylib_paths
use object::{Object, ObjectSymbol}; .into_iter()
let lib = libloading::Library::new(&path).unwrap(); .map(|path| unsafe { libloading::Library::new(&path).unwrap() })
let obj = std::fs::read(path).unwrap(); .collect::<Box<[_]>>(),
let obj = object::File::parse(&*obj).unwrap(); );
imported_symbols.extend(obj.dynamic_symbols().filter_map(|symbol| {
let name = symbol.name().unwrap().to_string();
if name.is_empty() || !symbol.is_global() || symbol.is_undefined() {
return None;
}
if name.starts_with("rust_metadata_") {
// The metadata is part of a section that is not loaded by the dynamic linker in
// case of cg_llvm.
return None;
}
let dlsym_name = if cfg!(target_os = "macos") {
// On macOS `dlsym` expects the name without leading `_`.
assert!(name.starts_with('_'), "{:?}", name);
&name[1..]
} else {
&name
};
let symbol: libloading::Symbol<'_, *const u8> =
unsafe { lib.get(dlsym_name.as_bytes()) }.unwrap();
Some((name, *symbol))
}));
std::mem::forget(lib)
}
sess.abort_if_errors(); sess.abort_if_errors();
imported_symbols Box::new(move |sym_name| {
for dylib in &*imported_dylibs {
if let Ok(sym) = unsafe { dylib.get::<*const u8>(sym_name.as_bytes()) } {
return Some(*sym);
}
}
None
})
} }
fn codegen_shim<'tcx>( fn codegen_shim<'tcx>(

View file

@ -27,7 +27,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
} }
// Used by stdarch // Used by stdarch
if template[0] == InlineAsmTemplatePiece::String("movq %rbx, ".to_string()) if template[0] == InlineAsmTemplatePiece::String("mov ".to_string())
&& matches!( && matches!(
template[1], template[1],
InlineAsmTemplatePiece::Placeholder { InlineAsmTemplatePiece::Placeholder {
@ -36,24 +36,26 @@ pub(crate) fn codegen_inline_asm<'tcx>(
span: _ span: _
} }
) )
&& template[2] == InlineAsmTemplatePiece::String("\n".to_string()) && template[2] == InlineAsmTemplatePiece::String(", rbx".to_string())
&& template[3] == InlineAsmTemplatePiece::String("cpuid".to_string()) && template[3] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[4] == InlineAsmTemplatePiece::String("\n".to_string()) && template[4] == InlineAsmTemplatePiece::String("cpuid".to_string())
&& template[5] == InlineAsmTemplatePiece::String("xchgq %rbx, ".to_string()) && template[5] == InlineAsmTemplatePiece::String("\n".to_string())
&& template[6] == InlineAsmTemplatePiece::String("xchg ".to_string())
&& matches!( && matches!(
template[6], template[7],
InlineAsmTemplatePiece::Placeholder { InlineAsmTemplatePiece::Placeholder {
operand_idx: 0, operand_idx: 0,
modifier: Some('r'), modifier: Some('r'),
span: _ span: _
} }
) )
&& template[8] == InlineAsmTemplatePiece::String(", rbx".to_string())
{ {
assert_eq!(operands.len(), 4); assert_eq!(operands.len(), 4);
let (leaf, eax_place) = match operands[1] { let (leaf, eax_place) = match operands[1] {
InlineAsmOperand::InOut { InlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)), reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
late: true, late: _,
ref in_value, ref in_value,
out_place: Some(out_place), out_place: Some(out_place),
} => ( } => (
@ -68,7 +70,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86( InlineAsmRegOrRegClass::RegClass(InlineAsmRegClass::X86(
X86InlineAsmRegClass::reg, X86InlineAsmRegClass::reg,
)), )),
late: true, late: _,
place: Some(place), place: Some(place),
} => crate::base::codegen_place(fx, place), } => crate::base::codegen_place(fx, place),
_ => unreachable!(), _ => unreachable!(),
@ -76,7 +78,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
let (sub_leaf, ecx_place) = match operands[2] { let (sub_leaf, ecx_place) = match operands[2] {
InlineAsmOperand::InOut { InlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)), reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx)),
late: true, late: _,
ref in_value, ref in_value,
out_place: Some(out_place), out_place: Some(out_place),
} => ( } => (
@ -88,7 +90,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
let edx_place = match operands[3] { let edx_place = match operands[3] {
InlineAsmOperand::Out { InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)), reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx)),
late: true, late: _,
place: Some(place), place: Some(place),
} => crate::base::codegen_place(fx, place), } => crate::base::codegen_place(fx, place),
_ => unreachable!(), _ => unreachable!(),

View file

@ -14,6 +14,10 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
target: Option<BasicBlock>, target: Option<BasicBlock>,
) { ) {
match intrinsic { match intrinsic {
"llvm.x86.sse2.pause" | "llvm.aarch64.isb" => {
// Spin loop hint
}
// Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8` // Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8`
"llvm.x86.sse2.pmovmskb.128" | "llvm.x86.avx2.pmovmskb" | "llvm.x86.sse2.movmsk.pd" => { "llvm.x86.sse2.pmovmskb.128" | "llvm.x86.avx2.pmovmskb" | "llvm.x86.sse2.movmsk.pd" => {
intrinsic_args!(fx, args => (a); intrinsic); intrinsic_args!(fx, args => (a); intrinsic);
@ -25,8 +29,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
let mut res = fx.bcx.ins().iconst(types::I32, 0); let mut res = fx.bcx.ins().iconst(types::I32, 0);
for lane in (0..lane_count).rev() { for lane in (0..lane_count).rev() {
let a_lane = let a_lane = a.value_lane(fx, lane).load_scalar(fx);
a.value_field(fx, mir::Field::new(lane.try_into().unwrap())).load_scalar(fx);
// cast float to int // cast float to int
let a_lane = match lane_ty { let a_lane = match lane_ty {

View file

@ -84,6 +84,30 @@ fn simd_for_each_lane<'tcx>(
} }
} }
fn simd_pair_for_each_lane_typed<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
x: CValue<'tcx>,
y: CValue<'tcx>,
ret: CPlace<'tcx>,
f: &dyn Fn(&mut FunctionCx<'_, '_, 'tcx>, CValue<'tcx>, CValue<'tcx>) -> CValue<'tcx>,
) {
assert_eq!(x.layout(), y.layout());
let layout = x.layout();
let (lane_count, _lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
let (ret_lane_count, _ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
assert_eq!(lane_count, ret_lane_count);
for lane_idx in 0..lane_count {
let x_lane = x.value_lane(fx, lane_idx);
let y_lane = y.value_lane(fx, lane_idx);
let res_lane = f(fx, x_lane, y_lane);
ret.place_lane(fx, lane_idx).write_cvalue(fx, res_lane);
}
}
fn simd_pair_for_each_lane<'tcx>( fn simd_pair_for_each_lane<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
x: CValue<'tcx>, x: CValue<'tcx>,
@ -504,37 +528,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
_ => unreachable!(), _ => unreachable!(),
}; };
let signed = type_sign(lhs.layout().ty); let res = crate::num::codegen_saturating_int_binop(fx, bin_op, lhs, rhs);
let checked_res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
let clif_ty = fx.clif_type(lhs.layout().ty).unwrap();
let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);
let val = match (intrinsic, signed) {
(sym::saturating_add, false) => fx.bcx.ins().select(has_overflow, max, val),
(sym::saturating_sub, false) => fx.bcx.ins().select(has_overflow, min, val),
(sym::saturating_add, true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero =
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = fx.bcx.ins().select(rhs_ge_zero, max, min);
fx.bcx.ins().select(has_overflow, sat_val, val)
}
(sym::saturating_sub, true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero =
fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = fx.bcx.ins().select(rhs_ge_zero, min, max);
fx.bcx.ins().select(has_overflow, sat_val, val)
}
_ => unreachable!(),
};
let res = CValue::by_val(val, lhs.layout());
ret.write_cvalue(fx, res); ret.write_cvalue(fx, res);
} }
sym::rotate_left => { sym::rotate_left => {
@ -819,8 +813,8 @@ fn codegen_regular_intrinsic_call<'tcx>(
sym::ptr_guaranteed_cmp => { sym::ptr_guaranteed_cmp => {
intrinsic_args!(fx, args => (a, b); intrinsic); intrinsic_args!(fx, args => (a, b); intrinsic);
let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b); let val = crate::num::codegen_ptr_binop(fx, BinOp::Eq, a, b).load_scalar(fx);
ret.write_cvalue(fx, val); ret.write_cvalue(fx, CValue::by_val(val, fx.layout_of(fx.tcx.types.u8)));
} }
sym::caller_location => { sym::caller_location => {
@ -1206,7 +1200,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
// FIXME once unwinding is supported, change this to actually catch panics // FIXME once unwinding is supported, change this to actually catch panics
let f_sig = fx.bcx.func.import_signature(Signature { let f_sig = fx.bcx.func.import_signature(Signature {
call_conv: fx.target_config.default_call_conv, call_conv: fx.target_config.default_call_conv,
params: vec![AbiParam::new(fx.bcx.func.dfg.value_type(data))], params: vec![AbiParam::new(pointer_ty(fx.tcx))],
returns: vec![], returns: vec![],
}); });

View file

@ -2,6 +2,7 @@
use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::subst::SubstsRef;
use rustc_span::Symbol; use rustc_span::Symbol;
use rustc_target::abi::Endian;
use super::*; use super::*;
use crate::prelude::*; use crate::prelude::*;
@ -26,7 +27,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
span: Span, span: Span,
) { ) {
match intrinsic { match intrinsic {
sym::simd_cast => { sym::simd_as | sym::simd_cast => {
intrinsic_args!(fx, args => (a); intrinsic); intrinsic_args!(fx, args => (a); intrinsic);
if !a.layout().ty.is_simd() { if !a.layout().ty.is_simd() {
@ -162,6 +163,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
} }
} }
} else { } else {
// FIXME remove this case
intrinsic.as_str()["simd_shuffle".len()..].parse().unwrap() intrinsic.as_str()["simd_shuffle".len()..].parse().unwrap()
}; };
@ -650,8 +652,128 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
} }
} }
// simd_saturating_* sym::simd_select_bitmask => {
// simd_bitmask intrinsic_args!(fx, args => (m, a, b); intrinsic);
if !a.layout().ty.is_simd() {
report_simd_type_validation_error(fx, intrinsic, span, a.layout().ty);
return;
}
assert_eq!(a.layout(), b.layout());
let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
let lane_layout = fx.layout_of(lane_ty);
let m = m.load_scalar(fx);
for lane in 0..lane_count {
let m_lane = fx.bcx.ins().ushr_imm(m, u64::from(lane) as i64);
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);
let m_lane = fx.bcx.ins().icmp_imm(IntCC::Equal, m_lane, 0);
let res_lane =
CValue::by_val(fx.bcx.ins().select(m_lane, b_lane, a_lane), lane_layout);
ret.place_lane(fx, lane).write_cvalue(fx, res_lane);
}
}
sym::simd_bitmask => {
intrinsic_args!(fx, args => (a); intrinsic);
let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
let lane_clif_ty = fx.clif_type(lane_ty).unwrap();
// The `fn simd_bitmask(vector) -> unsigned integer` intrinsic takes a
// vector mask and returns the most significant bit (MSB) of each lane in the form
// of either:
// * an unsigned integer
// * an array of `u8`
// If the vector has less than 8 lanes, a u8 is returned with zeroed trailing bits.
//
// The bit order of the result depends on the byte endianness, LSB-first for little
// endian and MSB-first for big endian.
let expected_int_bits = lane_count.max(8);
let expected_bytes = expected_int_bits / 8 + ((expected_int_bits % 8 > 0) as u64);
match lane_ty.kind() {
ty::Int(_) | ty::Uint(_) => {}
_ => {
fx.tcx.sess.span_fatal(
span,
&format!(
"invalid monomorphization of `simd_bitmask` intrinsic: \
vector argument `{}`'s element type `{}`, expected integer element \
type",
a.layout().ty,
lane_ty
),
);
}
}
let res_type =
Type::int_with_byte_size(u16::try_from(expected_bytes).unwrap()).unwrap();
let mut res = fx.bcx.ins().iconst(res_type, 0);
let lanes = match fx.tcx.sess.target.endian {
Endian::Big => Box::new(0..lane_count) as Box<dyn Iterator<Item = u64>>,
Endian::Little => Box::new((0..lane_count).rev()) as Box<dyn Iterator<Item = u64>>,
};
for lane in lanes {
let a_lane = a.value_lane(fx, lane).load_scalar(fx);
// extract sign bit of an int
let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_clif_ty.bits() - 1));
// shift sign bit into result
let a_lane_sign = clif_intcast(fx, a_lane_sign, res_type, false);
res = fx.bcx.ins().ishl_imm(res, 1);
res = fx.bcx.ins().bor(res, a_lane_sign);
}
match ret.layout().ty.kind() {
ty::Uint(i) if i.bit_width() == Some(expected_int_bits) => {}
ty::Array(elem, len)
if matches!(elem.kind(), ty::Uint(ty::UintTy::U8))
&& len.try_eval_usize(fx.tcx, ty::ParamEnv::reveal_all())
== Some(expected_bytes) => {}
_ => {
fx.tcx.sess.span_fatal(
span,
&format!(
"invalid monomorphization of `simd_bitmask` intrinsic: \
cannot return `{}`, expected `u{}` or `[u8; {}]`",
ret.layout().ty,
expected_int_bits,
expected_bytes
),
);
}
}
let res = CValue::by_val(res, ret.layout());
ret.write_cvalue(fx, res);
}
sym::simd_saturating_add | sym::simd_saturating_sub => {
intrinsic_args!(fx, args => (x, y); intrinsic);
let bin_op = match intrinsic {
sym::simd_saturating_add => BinOp::Add,
sym::simd_saturating_sub => BinOp::Sub,
_ => unreachable!(),
};
// FIXME use vector instructions when possible
simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
crate::num::codegen_saturating_int_binop(fx, bin_op, x_lane, y_lane)
});
}
// simd_arith_offset
// simd_scatter // simd_scatter
// simd_gather // simd_gather
_ => { _ => {

View file

@ -96,8 +96,8 @@ mod prelude {
pub(crate) use cranelift_codegen::ir::function::Function; pub(crate) use cranelift_codegen::ir::function::Function;
pub(crate) use cranelift_codegen::ir::types; pub(crate) use cranelift_codegen::ir::types;
pub(crate) use cranelift_codegen::ir::{ pub(crate) use cranelift_codegen::ir::{
AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc, AbiParam, Block, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc, StackSlot,
StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value, StackSlotData, StackSlotKind, TrapCode, Type, Value,
}; };
pub(crate) use cranelift_codegen::isa::{self, CallConv}; pub(crate) use cranelift_codegen::isa::{self, CallConv};
pub(crate) use cranelift_codegen::Context; pub(crate) use cranelift_codegen::Context;
@ -251,7 +251,6 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
let mut flags_builder = settings::builder(); let mut flags_builder = settings::builder();
flags_builder.enable("is_pic").unwrap(); flags_builder.enable("is_pic").unwrap();
flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" }; let enable_verifier = if backend_config.enable_verifier { "true" } else { "false" };
flags_builder.set("enable_verifier", enable_verifier).unwrap(); flags_builder.set("enable_verifier", enable_verifier).unwrap();
flags_builder.set("regalloc_checker", enable_verifier).unwrap(); flags_builder.set("regalloc_checker", enable_verifier).unwrap();
@ -279,6 +278,15 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
} }
} }
if target_triple.architecture == target_lexicon::Architecture::X86_64 {
// Windows depends on stack probes to grow the committed part of the stack
flags_builder.enable("enable_probestack").unwrap();
flags_builder.set("probestack_strategy", "inline").unwrap();
} else {
// __cranelift_probestack is not provided and inline stack probes are only supported on x86_64
flags_builder.set("enable_probestack", "false").unwrap();
}
let flags = settings::Flags::new(flags_builder); let flags = settings::Flags::new(flags_builder);
let isa_builder = match sess.opts.cg.target_cpu.as_deref() { let isa_builder = match sess.opts.cg.target_cpu.as_deref() {

View file

@ -75,7 +75,7 @@ pub(crate) fn maybe_create_entry_wrapper(
let main_func_id = m.declare_function(main_name, Linkage::Import, &main_sig).unwrap(); let main_func_id = m.declare_function(main_name, Linkage::Import, &main_sig).unwrap();
let mut ctx = Context::new(); let mut ctx = Context::new();
ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig); ctx.func.signature = cmain_sig;
{ {
let mut func_ctx = FunctionBuilderContext::new(); let mut func_ctx = FunctionBuilderContext::new();
let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx);

View file

@ -150,18 +150,12 @@ pub(crate) fn codegen_int_binop<'tcx>(
BinOp::BitXor => b.bxor(lhs, rhs), BinOp::BitXor => b.bxor(lhs, rhs),
BinOp::BitAnd => b.band(lhs, rhs), BinOp::BitAnd => b.band(lhs, rhs),
BinOp::BitOr => b.bor(lhs, rhs), BinOp::BitOr => b.bor(lhs, rhs),
BinOp::Shl => { BinOp::Shl => b.ishl(lhs, rhs),
let lhs_ty = fx.bcx.func.dfg.value_type(lhs);
let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1));
fx.bcx.ins().ishl(lhs, actual_shift)
}
BinOp::Shr => { BinOp::Shr => {
let lhs_ty = fx.bcx.func.dfg.value_type(lhs);
let actual_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1));
if signed { if signed {
fx.bcx.ins().sshr(lhs, actual_shift) b.sshr(lhs, rhs)
} else { } else {
fx.bcx.ins().ushr(lhs, actual_shift) b.ushr(lhs, rhs)
} }
} }
// Compare binops handles by `codegen_binop`. // Compare binops handles by `codegen_binop`.
@ -279,22 +273,15 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
} }
} }
BinOp::Shl => { BinOp::Shl => {
let lhs_ty = fx.bcx.func.dfg.value_type(lhs); let val = fx.bcx.ins().ishl(lhs, rhs);
let masked_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1));
let val = fx.bcx.ins().ishl(lhs, masked_shift);
let ty = fx.bcx.func.dfg.value_type(val); let ty = fx.bcx.func.dfg.value_type(val);
let max_shift = i64::from(ty.bits()) - 1; let max_shift = i64::from(ty.bits()) - 1;
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
(val, has_overflow) (val, has_overflow)
} }
BinOp::Shr => { BinOp::Shr => {
let lhs_ty = fx.bcx.func.dfg.value_type(lhs); let val =
let masked_shift = fx.bcx.ins().band_imm(rhs, i64::from(lhs_ty.bits() - 1)); if !signed { fx.bcx.ins().ushr(lhs, rhs) } else { fx.bcx.ins().sshr(lhs, rhs) };
let val = if !signed {
fx.bcx.ins().ushr(lhs, masked_shift)
} else {
fx.bcx.ins().sshr(lhs, masked_shift)
};
let ty = fx.bcx.func.dfg.value_type(val); let ty = fx.bcx.func.dfg.value_type(val);
let max_shift = i64::from(ty.bits()) - 1; let max_shift = i64::from(ty.bits()) - 1;
let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift); let has_overflow = fx.bcx.ins().icmp_imm(IntCC::UnsignedGreaterThan, rhs, max_shift);
@ -309,6 +296,42 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
CValue::by_val_pair(res, has_overflow, out_layout) CValue::by_val_pair(res, has_overflow, out_layout)
} }
pub(crate) fn codegen_saturating_int_binop<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp,
lhs: CValue<'tcx>,
rhs: CValue<'tcx>,
) -> CValue<'tcx> {
assert_eq!(lhs.layout().ty, rhs.layout().ty);
let signed = type_sign(lhs.layout().ty);
let clif_ty = fx.clif_type(lhs.layout().ty).unwrap();
let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);
let checked_res = crate::num::codegen_checked_int_binop(fx, bin_op, lhs, rhs);
let (val, has_overflow) = checked_res.load_scalar_pair(fx);
let val = match (bin_op, signed) {
(BinOp::Add, false) => fx.bcx.ins().select(has_overflow, max, val),
(BinOp::Sub, false) => fx.bcx.ins().select(has_overflow, min, val),
(BinOp::Add, true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = fx.bcx.ins().select(rhs_ge_zero, max, min);
fx.bcx.ins().select(has_overflow, sat_val, val)
}
(BinOp::Sub, true) => {
let rhs = rhs.load_scalar(fx);
let rhs_ge_zero = fx.bcx.ins().icmp_imm(IntCC::SignedGreaterThanOrEqual, rhs, 0);
let sat_val = fx.bcx.ins().select(rhs_ge_zero, min, max);
fx.bcx.ins().select(has_overflow, sat_val, val)
}
_ => unreachable!(),
};
CValue::by_val(val, lhs.layout())
}
pub(crate) fn codegen_float_binop<'tcx>( pub(crate) fn codegen_float_binop<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
bin_op: BinOp, bin_op: BinOp,

View file

@ -25,7 +25,12 @@ pub(crate) fn unsized_info<'tcx>(
.bcx .bcx
.ins() .ins()
.iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64), .iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => { (
&ty::Dynamic(ref data_a, _, src_dyn_kind),
&ty::Dynamic(ref data_b, _, target_dyn_kind),
) => {
assert_eq!(src_dyn_kind, target_dyn_kind);
let old_info = let old_info =
old_info.expect("unsized_info: missing old info for trait upcasting coercion"); old_info.expect("unsized_info: missing old info for trait upcasting coercion");
if data_a.principal_def_id() == data_b.principal_def_id() { if data_a.principal_def_id() == data_b.principal_def_id() {
@ -101,6 +106,21 @@ fn unsize_ptr<'tcx>(
} }
} }
/// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
pub(crate) fn cast_to_dyn_star<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
src: Value,
src_ty_and_layout: TyAndLayout<'tcx>,
dst_ty: Ty<'tcx>,
old_info: Option<Value>,
) -> (Value, Value) {
assert!(
matches!(dst_ty.kind(), ty::Dynamic(_, _, ty::DynStar)),
"destination type must be a dyn*"
);
(src, unsized_info(fx, src_ty_and_layout.ty, dst_ty, old_info))
}
/// Coerce `src`, which is a reference to a value of type `src_ty`, /// Coerce `src`, which is a reference to a value of type `src_ty`,
/// to a value of type `dst_ty` and store the result in `dst` /// to a value of type `dst_ty` and store the result in `dst`
pub(crate) fn coerce_unsized_into<'tcx>( pub(crate) fn coerce_unsized_into<'tcx>(
@ -147,6 +167,24 @@ pub(crate) fn coerce_unsized_into<'tcx>(
} }
} }
pub(crate) fn coerce_dyn_star<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
src: CValue<'tcx>,
dst: CPlace<'tcx>,
) {
let (data, extra) = if let ty::Dynamic(_, _, ty::DynStar) = src.layout().ty.kind() {
let (data, vtable) = src.load_scalar_pair(fx);
(data, Some(vtable))
} else {
let data = src.load_scalar(fx);
(data, None)
};
let (data, vtable) = cast_to_dyn_star(fx, data, src.layout(), dst.layout().ty, extra);
dst.write_cvalue(fx, CValue::by_val_pair(data, vtable, dst.layout()));
}
// Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs // Adapted from https://github.com/rust-lang/rust/blob/2a663555ddf36f6b041445894a8c175cd1bc718c/src/librustc_codegen_ssa/glue.rs
pub(crate) fn size_and_align_of_dst<'tcx>( pub(crate) fn size_and_align_of_dst<'tcx>(

View file

@ -107,6 +107,50 @@ impl<'tcx> CValue<'tcx> {
} }
} }
// FIXME remove
// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the
// vtable pointer.
pub(crate) fn dyn_star_force_data_on_stack(
self,
fx: &mut FunctionCx<'_, '_, 'tcx>,
) -> (Value, Value) {
assert!(self.1.ty.is_dyn_star());
match self.0 {
CValueInner::ByRef(ptr, None) => {
let (a_scalar, b_scalar) = match self.1.abi {
Abi::ScalarPair(a, b) => (a, b),
_ => unreachable!("dyn_star_force_data_on_stack({:?})", self),
};
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar);
let mut flags = MemFlags::new();
flags.set_notrap();
let vtable = ptr.offset(fx, b_offset).load(fx, clif_ty2, flags);
(ptr.get_addr(fx), vtable)
}
CValueInner::ByValPair(data, vtable) => {
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
// specify stack slot alignment.
size: (u32::try_from(fx.target_config.pointer_type().bytes()).unwrap() + 15)
/ 16
* 16,
});
let data_ptr = Pointer::stack_slot(stack_slot);
let mut flags = MemFlags::new();
flags.set_notrap();
data_ptr.store(fx, data, flags);
(data_ptr.get_addr(fx), vtable)
}
CValueInner::ByRef(_, Some(_)) | CValueInner::ByVal(_) => {
unreachable!("dyn_star_force_data_on_stack({:?})", self)
}
}
}
pub(crate) fn try_to_ptr(self) -> Option<(Pointer, Option<Value>)> { pub(crate) fn try_to_ptr(self) -> Option<(Pointer, Option<Value>)> {
match self.0 { match self.0 {
CValueInner::ByRef(ptr, meta) => Some((ptr, meta)), CValueInner::ByRef(ptr, meta) => Some((ptr, meta)),
@ -236,6 +280,10 @@ impl<'tcx> CValue<'tcx> {
crate::unsize::coerce_unsized_into(fx, self, dest); crate::unsize::coerce_unsized_into(fx, self, dest);
} }
pub(crate) fn coerce_dyn_star(self, fx: &mut FunctionCx<'_, '_, 'tcx>, dest: CPlace<'tcx>) {
crate::unsize::coerce_dyn_star(fx, self, dest);
}
/// If `ty` is signed, `const_val` must already be sign extended. /// If `ty` is signed, `const_val` must already be sign extended.
pub(crate) fn const_val( pub(crate) fn const_val(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,

View file

@ -45,12 +45,26 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>, fx: &mut FunctionCx<'_, '_, 'tcx>,
arg: CValue<'tcx>, arg: CValue<'tcx>,
idx: usize, idx: usize,
) -> (Value, Value) { ) -> (Pointer, Value) {
let (ptr, vtable) = if let Abi::ScalarPair(_, _) = arg.layout().abi { let (ptr, vtable) = 'block: {
arg.load_scalar_pair(fx) if let ty::Ref(_, ty, _) = arg.layout().ty.kind() {
} else { if ty.is_dyn_star() {
let (ptr, vtable) = arg.try_to_ptr().unwrap(); let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);
(ptr.get_addr(fx), vtable.unwrap()) let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
let ptr = dyn_star.place_field(fx, mir::Field::new(0)).to_ptr();
let vtable =
dyn_star.place_field(fx, mir::Field::new(1)).to_cvalue(fx).load_scalar(fx);
break 'block (ptr, vtable);
}
}
if let Abi::ScalarPair(_, _) = arg.layout().abi {
let (ptr, vtable) = arg.load_scalar_pair(fx);
(Pointer::new(ptr), vtable)
} else {
let (ptr, vtable) = arg.try_to_ptr().unwrap();
(ptr, vtable.unwrap())
}
}; };
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes(); let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();