From b63df38a98a1dac5a7d4bc54a28a6204923443a4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 5 Mar 2021 09:32:47 +0000 Subject: [PATCH 01/51] Shrink the size of Rvalue by 16 bytes --- src/base.rs | 4 ++-- src/lib.rs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index 4842628a99da7..db65c38ced1c7 100644 --- a/src/base.rs +++ b/src/base.rs @@ -494,14 +494,14 @@ fn codegen_stmt<'tcx>( let val = crate::constant::codegen_tls_ref(fx, def_id, lval.layout()); lval.write_cvalue(fx, val); } - Rvalue::BinaryOp(bin_op, ref lhs, ref rhs) => { + Rvalue::BinaryOp(bin_op, box (ref lhs, ref rhs)) => { let lhs = codegen_operand(fx, lhs); let rhs = codegen_operand(fx, rhs); let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs); lval.write_cvalue(fx, res); } - Rvalue::CheckedBinaryOp(bin_op, ref lhs, ref rhs) => { + Rvalue::CheckedBinaryOp(bin_op, box (ref lhs, ref rhs)) => { let lhs = codegen_operand(fx, lhs); let rhs = codegen_operand(fx, rhs); diff --git a/src/lib.rs b/src/lib.rs index 1480ab2513378..33158d89d30bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ associated_type_bounds, never_type, try_blocks, + box_patterns, hash_drain_filter )] #![warn(rust_2018_idioms)] From 27886cd6b6a52d5bf3d0a9ea667e04c5e8c59705 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 5 Mar 2021 19:12:59 +0100 Subject: [PATCH 02/51] Merge commit '9a0c32934ebe376128230aa8da3275697b2053e7' into sync_cg_clif-2021-03-05 --- .cirrus.yml | 25 ++ .github/workflows/main.yml | 5 +- .vscode/settings.json | 2 +- Cargo.lock | 128 +++----- Cargo.toml | 5 +- build.sh | 16 +- build_sysroot/Cargo.lock | 20 +- build_sysroot/Cargo.toml | 2 - build_sysroot/alloc_system/Cargo.toml | 13 - build_sysroot/build_sysroot.sh | 2 +- build_sysroot/prepare_sysroot_src.sh | 4 +- clean_all.sh | 2 +- ...ins-Disable-128bit-atomic-operations.patch | 48 +++ example/alloc_example.rs | 2 +- .../lib.rs => example/alloc_system.rs | 136 +-------- ...itrary_self_types_pointers_and_wrappers.rs | 31 +- example/mini_core.rs | 16 + example/mini_core_hello_world.rs | 3 + ...022-core-Disable-not-compiling-tests.patch | 16 - ...027-Disable-128bit-atomic-operations.patch | 103 +++++++ prepare.sh | 2 +- rust-toolchain | 2 +- rustfmt.toml | 4 + scripts/cargo.sh | 2 +- scripts/config.sh | 4 +- scripts/rustup.sh | 2 +- scripts/test_bootstrap.sh | 42 ++- scripts/tests.sh | 9 +- src/abi/comments.rs | 56 ++-- src/abi/mod.rs | 144 +++------ src/abi/pass_mode.rs | 108 ++----- src/abi/returning.rs | 90 ++---- src/allocator.rs | 29 +- src/analyze.rs | 9 +- src/archive.rs | 49 +--- src/atomic_shim.rs | 185 ------------ src/backend.rs | 62 +--- src/base.rs | 271 ++++++----------- src/bin/cg_clif.rs | 8 +- src/bin/cg_clif_build_sysroot.rs | 11 +- src/cast.rs | 34 +-- src/codegen_i128.rs | 85 ++---- src/common.rs | 111 ++----- src/constant.rs | 118 +++----- src/debuginfo/emit.rs | 14 +- src/debuginfo/line_info.rs | 75 ++--- src/debuginfo/mod.rs | 157 ++-------- src/debuginfo/unwind.rs | 27 +- src/discriminant.rs | 45 +-- src/driver/aot.rs | 114 ++------ src/driver/jit.rs | 119 +++----- src/driver/mod.rs | 32 +- src/inline_asm.rs | 57 +--- src/intrinsics/cpuid.rs | 44 +-- src/intrinsics/llvm.rs | 2 +- src/intrinsics/mod.rs | 276 +++++++++--------- src/intrinsics/simd.rs | 2 +- src/lib.rs | 55 ++-- src/main_shim.rs | 29 +- src/metadata.rs | 4 +- src/num.rs | 72 ++--- src/optimize/code_layout.rs | 10 +- src/optimize/mod.rs | 7 +- src/optimize/peephole.rs | 22 +- src/optimize/stack2reg.rs | 49 +--- src/pointer.rs | 123 ++------ src/pretty_clif.rs | 72 ++--- src/toolchain.rs | 15 +- src/trap.rs | 12 +- src/unsize.rs | 75 ++--- src/value_and_place.rs | 187 ++++-------- src/vtable.rs | 23 +- test.sh | 2 +- 73 files changed, 1143 insertions(+), 2594 deletions(-) create mode 100644 .cirrus.yml delete mode 100644 build_sysroot/alloc_system/Cargo.toml create mode 100644 crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch rename build_sysroot/alloc_system/lib.rs => example/alloc_system.rs (62%) create mode 100644 patches/0027-Disable-128bit-atomic-operations.patch create mode 100644 rustfmt.toml delete mode 100644 src/atomic_shim.rs diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 0000000000000..e173df423a765 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,25 @@ +task: + name: freebsd + freebsd_instance: + image: freebsd-12-1-release-amd64 + setup_rust_script: + - pkg install -y curl git bash + - curl https://sh.rustup.rs -sSf --output rustup.sh + - sh rustup.sh --default-toolchain none -y --profile=minimal + cargo_bin_cache: + folder: ~/.cargo/bin + target_cache: + folder: target + prepare_script: + - . $HOME/.cargo/env + - git config --global user.email "user@example.com" + - git config --global user.name "User" + - ./prepare.sh + test_script: + - . $HOME/.cargo/env + - # Enable backtraces for easier debugging + - export RUST_BACKTRACE=1 + - # Reduce amount of benchmark runs as they are slow + - export COMPILE_RUNS=2 + - export RUN_RUNS=2 + - ./test.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 20c58423a0c50..e6d3375fb1bab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,9 +12,6 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - env: - - BACKEND: "" - - BACKEND: --oldbe steps: - uses: actions/checkout@v2 @@ -54,7 +51,7 @@ jobs: export COMPILE_RUNS=2 export RUN_RUNS=2 - ./test.sh $BACKEND + ./test.sh - name: Package prebuilt cg_clif run: tar cvfJ cg_clif.tar.xz build diff --git a/.vscode/settings.json b/.vscode/settings.json index 19ea41563dfd6..a13d5931ffa89 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { // source for rustc_* is not included in the rust-src component; disable the errors about this - "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate"], + "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "macro-error"], "rust-analyzer.assist.importMergeBehavior": "last", "rust-analyzer.cargo.loadOutDirsFromCheck": true, "rust-analyzer.linkedProjects": [ diff --git a/Cargo.lock b/Cargo.lock index 5495cfa5eaa0d..76d9f0d27ce46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "anyhow" version = "1.0.38" @@ -29,18 +31,6 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" -[[package]] -name = "cc" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -49,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "byteorder", "cranelift-bforest", @@ -75,8 +65,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -84,18 +74,18 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" [[package]] name = "cranelift-entity" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" [[package]] name = "cranelift-frontend" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-codegen", "log", @@ -105,8 +95,8 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "anyhow", "cranelift-codegen", @@ -123,8 +113,8 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "anyhow", "cranelift-codegen", @@ -135,18 +125,17 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "cranelift-codegen", - "raw-cpuid", "target-lexicon", ] [[package]] name = "cranelift-object" -version = "0.69.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#986b5768f9e68f1564b43f32b8a4080a6582c8ca" +version = "0.70.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" dependencies = [ "anyhow", "cranelift-codegen", @@ -162,7 +151,7 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -219,9 +208,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.82" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" [[package]] name = "libloading" @@ -229,17 +218,17 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "351a32417a12d5f7e82c368a66781e307834dae04c6ce0cd4456d52989229883" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "winapi", ] [[package]] name = "log" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 0.1.10", + "cfg-if", ] [[package]] @@ -253,9 +242,9 @@ dependencies = [ [[package]] name = "object" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" +checksum = "a9a7ab5d64814df0fe4a4b5ead45ed6c5f181ee3ff04ba344313a6c80446c5d4" dependencies = [ "crc32fast", "indexmap", @@ -272,24 +261,13 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991431c3519a3f36861882da93630ce66b52918dcf1b8e2fd66b397fc96f28df" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" dependencies = [ "proc-macro2", ] -[[package]] -name = "raw-cpuid" -version = "8.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fdf7d9dbd43f3d81d94a49c1c3df73cc2b3827995147e6cf7f89d4ec5483e73" -dependencies = [ - "bitflags", - "cc", - "rustc_version", -] - [[package]] name = "regalloc" version = "0.0.31" @@ -337,30 +315,6 @@ dependencies = [ "target-lexicon", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "smallvec" version = "1.6.1" @@ -369,9 +323,9 @@ checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" [[package]] name = "syn" -version = "1.0.58" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" +checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081" dependencies = [ "proc-macro2", "quote", @@ -380,24 +334,24 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ee5a98e506fb7231a304c3a1bd7c132a55016cf65001e0282480665870dfcb9" +checksum = "422045212ea98508ae3d28025bc5aaa2bd4a9cdaecd442a08da2ee620ee9ea95" [[package]] name = "thiserror" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cc616c6abf8c8928e2fdcc0dbfab37175edd8fb49a4641066ad1364fdab146" +checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be73a2caec27583d0046ef3796c3794f868a5bc813db689eed00c7631275cd1" +checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 3820fce6d1e0d..9861af1f8eae2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,14 +9,14 @@ crate-type = ["dylib"] [dependencies] # These have to be in sync with each other -cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind", "x86", "x64"] } +cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", features = ["unwind", "x64"] } cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main", optional = true } cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } target-lexicon = "0.11.0" gimli = { version = "0.23.0", default-features = false, features = ["write"]} -object = { version = "0.22.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] } +object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] } ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" } indexmap = "1.0.2" @@ -38,7 +38,6 @@ smallvec = "1.6.1" default = ["jit", "inline_asm"] jit = ["cranelift-jit", "libloading"] inline_asm = [] -oldbe = [] [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/build.sh b/build.sh index 598ce35eceaac..090349e54b148 100755 --- a/build.sh +++ b/build.sh @@ -1,11 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash set -e # Settings export CHANNEL="release" build_sysroot="clif" target_dir='build' -oldbe='' while [[ $# != 0 ]]; do case $1 in "--debug") @@ -19,12 +18,9 @@ while [[ $# != 0 ]]; do target_dir=$2 shift ;; - "--oldbe") - oldbe='--features oldbe' - ;; *) echo "Unknown flag '$1'" - echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--oldbe]" + echo "Usage: ./build.sh [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]" exit 1 ;; esac @@ -34,19 +30,19 @@ done # Build cg_clif unset CARGO_TARGET_DIR unamestr=$(uname) -if [[ "$unamestr" == 'Linux' ]]; then +if [[ "$unamestr" == 'Linux' || "$unamestr" == "FreeBSD" ]]; then export RUSTFLAGS='-Clink-arg=-Wl,-rpath=$ORIGIN/../lib '$RUSTFLAGS elif [[ "$unamestr" == 'Darwin' ]]; then export RUSTFLAGS='-Csplit-debuginfo=unpacked -Clink-arg=-Wl,-rpath,@loader_path/../lib -Zosx-rpath-install-name '$RUSTFLAGS dylib_ext='dylib' else - echo "Unsupported os" + echo "Unsupported os $unamestr" exit 1 fi if [[ "$CHANNEL" == "release" ]]; then - cargo build $oldbe --release + cargo build --release else - cargo build $oldbe + cargo build fi source scripts/ext_config.sh diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 0da9999c17285..a7650ab995b0f 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "addr2line" version = "0.14.1" @@ -30,15 +32,6 @@ dependencies = [ "core", ] -[[package]] -name = "alloc_system" -version = "0.0.0" -dependencies = [ - "compiler_builtins", - "core", - "libc", -] - [[package]] name = "autocfg" version = "1.0.1" @@ -47,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] name = "cc" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48" +checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" [[package]] name = "cfg-if" @@ -139,9 +132,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cca32fa0182e8c0989459524dc356b8f2b5c10f1b9eb521b7d182c03cf8c5ff" +checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" dependencies = [ "rustc-std-workspace-core", ] @@ -258,7 +251,6 @@ name = "sysroot" version = "0.0.0" dependencies = [ "alloc", - "alloc_system", "compiler_builtins", "core", "std", diff --git a/build_sysroot/Cargo.toml b/build_sysroot/Cargo.toml index 82516c98af2a2..04748d5dbab59 100644 --- a/build_sysroot/Cargo.toml +++ b/build_sysroot/Cargo.toml @@ -9,8 +9,6 @@ alloc = { path = "./sysroot_src/library/alloc" } std = { path = "./sysroot_src/library/std", features = ["panic_unwind", "backtrace"] } test = { path = "./sysroot_src/library/test" } -alloc_system = { path = "./alloc_system" } - compiler_builtins = { version = "0.1.39", default-features = false, features = ["no-asm"] } [patch.crates-io] diff --git a/build_sysroot/alloc_system/Cargo.toml b/build_sysroot/alloc_system/Cargo.toml deleted file mode 100644 index 9fffca843006f..0000000000000 --- a/build_sysroot/alloc_system/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -authors = ["The Rust Project Developers", "bjorn3 (edited to be usable outside the rust source)"] -name = "alloc_system" -version = "0.0.0" -[lib] -name = "alloc_system" -path = "lib.rs" -test = false -doc = false -[dependencies] -core = { path = "../sysroot_src/library/core" } -libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false } -compiler_builtins = "0.1" diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh index 282ce4a582c4b..636aa5f3f3dc2 100755 --- a/build_sysroot/build_sysroot.sh +++ b/build_sysroot/build_sysroot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Requires the CHANNEL env var to be set to `debug` or `release.` diff --git a/build_sysroot/prepare_sysroot_src.sh b/build_sysroot/prepare_sysroot_src.sh index d3b87e02ba891..c90205db0fbd0 100755 --- a/build_sysroot/prepare_sysroot_src.sh +++ b/build_sysroot/prepare_sysroot_src.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e cd "$(dirname "$0")" @@ -33,7 +33,7 @@ git clone https://github.com/rust-lang/compiler-builtins.git || echo "rust-lang/ pushd compiler-builtins git checkout -- . git checkout 0.1.39 -git apply ../../crate_patches/0001-compiler-builtins-Remove-rotate_left-from-Int.patch +git apply ../../crate_patches/000*-compiler-builtins-*.patch popd echo "Successfully prepared sysroot source for building" diff --git a/clean_all.sh b/clean_all.sh index b47efe72bce03..a7bbeb05cac5a 100755 --- a/clean_all.sh +++ b/clean_all.sh @@ -1,4 +1,4 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e rm -rf target/ build/ build_sysroot/{sysroot_src/,target/,compiler-builtins/} perf.data{,.old} diff --git a/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch b/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch new file mode 100644 index 0000000000000..7daea99f5794d --- /dev/null +++ b/crate_patches/0002-compiler-builtins-Disable-128bit-atomic-operations.patch @@ -0,0 +1,48 @@ +From 1d574bf5e32d51641dcacaf8ef777e95b44f6f2a Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Thu, 18 Feb 2021 18:30:55 +0100 +Subject: [PATCH] Disable 128bit atomic operations + +Cranelift doesn't support them yet +--- + src/mem/mod.rs | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/src/mem/mod.rs b/src/mem/mod.rs +index 107762c..2d1ae10 100644 +--- a/src/mem/mod.rs ++++ b/src/mem/mod.rs +@@ -137,10 +137,6 @@ intrinsics! { + pub extern "C" fn __llvm_memcpy_element_unordered_atomic_8(dest: *mut u64, src: *const u64, bytes: usize) -> () { + memcpy_element_unordered_atomic(dest, src, bytes); + } +- #[cfg(target_has_atomic_load_store = "128")] +- pub extern "C" fn __llvm_memcpy_element_unordered_atomic_16(dest: *mut u128, src: *const u128, bytes: usize) -> () { +- memcpy_element_unordered_atomic(dest, src, bytes); +- } + + #[cfg(target_has_atomic_load_store = "8")] + pub extern "C" fn __llvm_memmove_element_unordered_atomic_1(dest: *mut u8, src: *const u8, bytes: usize) -> () { +@@ -158,10 +154,6 @@ intrinsics! { + pub extern "C" fn __llvm_memmove_element_unordered_atomic_8(dest: *mut u64, src: *const u64, bytes: usize) -> () { + memmove_element_unordered_atomic(dest, src, bytes); + } +- #[cfg(target_has_atomic_load_store = "128")] +- pub extern "C" fn __llvm_memmove_element_unordered_atomic_16(dest: *mut u128, src: *const u128, bytes: usize) -> () { +- memmove_element_unordered_atomic(dest, src, bytes); +- } + + #[cfg(target_has_atomic_load_store = "8")] + pub extern "C" fn __llvm_memset_element_unordered_atomic_1(s: *mut u8, c: u8, bytes: usize) -> () { +@@ -179,8 +171,4 @@ intrinsics! { + pub extern "C" fn __llvm_memset_element_unordered_atomic_8(s: *mut u64, c: u8, bytes: usize) -> () { + memset_element_unordered_atomic(s, c, bytes); + } +- #[cfg(target_has_atomic_load_store = "128")] +- pub extern "C" fn __llvm_memset_element_unordered_atomic_16(s: *mut u128, c: u8, bytes: usize) -> () { +- memset_element_unordered_atomic(s, c, bytes); +- } + } +-- +2.26.2.7.g19db9cfb68 + diff --git a/example/alloc_example.rs b/example/alloc_example.rs index f59600ebb330c..71e93e87b6c41 100644 --- a/example/alloc_example.rs +++ b/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, box_syntax, alloc_system, core_intrinsics, alloc_prelude, alloc_error_handler)] +#![feature(start, box_syntax, core_intrinsics, alloc_prelude, alloc_error_handler)] #![no_std] extern crate alloc; diff --git a/build_sysroot/alloc_system/lib.rs b/example/alloc_system.rs similarity index 62% rename from build_sysroot/alloc_system/lib.rs rename to example/alloc_system.rs index c832d5e5ebb9b..5f66ca67f2d40 100644 --- a/build_sysroot/alloc_system/lib.rs +++ b/example/alloc_system.rs @@ -8,66 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. #![no_std] -#![allow(unused_attributes)] -#![unstable(feature = "alloc_system", - reason = "this library is unlikely to be stabilized in its current \ - form or name", - issue = "32838")] -#![feature(allocator_api)] -#![feature(core_intrinsics)] -#![feature(nll)] -#![feature(staged_api)] -#![feature(rustc_attrs)] -#![feature(alloc_layout_extra)] -#![cfg_attr( - all(target_arch = "wasm32", not(target_os = "emscripten")), - feature(integer_atomics, stdsimd) -)] +#![feature(allocator_api, rustc_private)] #![cfg_attr(any(unix, target_os = "redox"), feature(libc))] + // The minimum alignment guaranteed by the architecture. This value is used to // add fast paths for low alignment values. #[cfg(all(any(target_arch = "x86", target_arch = "arm", target_arch = "mips", target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "asmjs", - target_arch = "wasm32")))] -#[allow(dead_code)] + target_arch = "powerpc64")))] const MIN_ALIGN: usize = 8; #[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "mips64", target_arch = "s390x", target_arch = "sparc64")))] -#[allow(dead_code)] const MIN_ALIGN: usize = 16; -/// The default memory allocator provided by the operating system. -/// -/// This is based on `malloc` on Unix platforms and `HeapAlloc` on Windows, -/// plus related functions. -/// -/// This type can be used in a `static` item -/// with the `#[global_allocator]` attribute -/// to force the global allocator to be the system’s one. -/// (The default is jemalloc for executables, on some platforms.) -/// -/// ```rust -/// use std::alloc::System; -/// -/// #[global_allocator] -/// static A: System = System; -/// -/// fn main() { -/// let a = Box::new(4); // Allocates from the system allocator. -/// println!("{}", a); -/// } -/// ``` -/// -/// It can also be used directly to allocate memory -/// independently of the standard library’s global allocator. -#[stable(feature = "alloc_system_type", since = "1.28.0")] pub struct System; #[cfg(any(windows, unix, target_os = "redox"))] mod realloc_fallback { @@ -96,7 +54,6 @@ mod platform { use MIN_ALIGN; use System; use core::alloc::{GlobalAlloc, Layout}; - #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { @@ -221,7 +178,6 @@ mod platform { }; ptr as *mut u8 } - #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { @@ -254,89 +210,3 @@ mod platform { } } } -// This is an implementation of a global allocator on the wasm32 platform when -// emscripten is not in use. In that situation there's no actual runtime for us -// to lean on for allocation, so instead we provide our own! -// -// The wasm32 instruction set has two instructions for getting the current -// amount of memory and growing the amount of memory. These instructions are the -// foundation on which we're able to build an allocator, so we do so! Note that -// the instructions are also pretty "global" and this is the "global" allocator -// after all! -// -// The current allocator here is the `dlmalloc` crate which we've got included -// in the rust-lang/rust repository as a submodule. The crate is a port of -// dlmalloc.c from C to Rust and is basically just so we can have "pure Rust" -// for now which is currently technically required (can't link with C yet). -// -// The crate itself provides a global allocator which on wasm has no -// synchronization as there are no threads! -#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] -mod platform { - extern crate dlmalloc; - use core::alloc::{GlobalAlloc, Layout}; - use System; - static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; - #[stable(feature = "alloc_system_type", since = "1.28.0")] - unsafe impl GlobalAlloc for System { - #[inline] - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.malloc(layout.size(), layout.align()) - } - #[inline] - unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.calloc(layout.size(), layout.align()) - } - #[inline] - unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - let _lock = lock::lock(); - DLMALLOC.free(ptr, layout.size(), layout.align()) - } - #[inline] - unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { - let _lock = lock::lock(); - DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) - } - } - #[cfg(target_feature = "atomics")] - mod lock { - use core::arch::wasm32; - use core::sync::atomic::{AtomicI32, Ordering::SeqCst}; - static LOCKED: AtomicI32 = AtomicI32::new(0); - pub struct DropLock; - pub fn lock() -> DropLock { - loop { - if LOCKED.swap(1, SeqCst) == 0 { - return DropLock - } - unsafe { - let r = wasm32::atomic::wait_i32( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // expected value - -1, // timeout - ); - debug_assert!(r == 0 || r == 1); - } - } - } - impl Drop for DropLock { - fn drop(&mut self) { - let r = LOCKED.swap(0, SeqCst); - debug_assert_eq!(r, 1); - unsafe { - wasm32::atomic::wake( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // only one thread - ); - } - } - } - } - #[cfg(not(target_feature = "atomics"))] - mod lock { - #[inline] - pub fn lock() {} // no atomics, no threads, that's easy! - } -} diff --git a/example/arbitrary_self_types_pointers_and_wrappers.rs b/example/arbitrary_self_types_pointers_and_wrappers.rs index 0b0039a1370a4..ddeb752f93ed7 100644 --- a/example/arbitrary_self_types_pointers_and_wrappers.rs +++ b/example/arbitrary_self_types_pointers_and_wrappers.rs @@ -1,22 +1,12 @@ // Adapted from rustc run-pass test suite -#![feature(no_core, arbitrary_self_types, box_syntax)] +#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)] #![feature(rustc_attrs)] -#![feature(start, lang_items)] -#![no_core] - -extern crate mini_core; - -use mini_core::*; - -macro_rules! assert_eq { - ($l:expr, $r: expr) => { - if $l != $r { - panic(stringify!($l != $r)); - } - } -} +use std::{ + ops::{Deref, CoerceUnsized, DispatchFromDyn}, + marker::Unsize, +}; struct Ptr(Box); @@ -67,16 +57,13 @@ impl Trait for i32 { } } -#[start] -fn main(_: isize, _: *const *const u8) -> isize { - let pw = Ptr(box Wrapper(5)) as Ptr>; +fn main() { + let pw = Ptr(Box::new(Wrapper(5))) as Ptr>; assert_eq!(pw.ptr_wrapper(), 5); - let wp = Wrapper(Ptr(box 6)) as Wrapper>; + let wp = Wrapper(Ptr(Box::new(6))) as Wrapper>; assert_eq!(wp.wrapper_ptr(), 6); - let wpw = Wrapper(Ptr(box Wrapper(7))) as Wrapper>>; + let wpw = Wrapper(Ptr(Box::new(Wrapper(7)))) as Wrapper>>; assert_eq!(wpw.wrapper_ptr_wrapper(), 7); - - 0 } diff --git a/example/mini_core.rs b/example/mini_core.rs index 002ec7e2e3d7a..7c6d7fc106ded 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -365,6 +365,22 @@ impl PartialEq for Option { } } +#[lang = "shl"] +pub trait Shl { + type Output; + + #[must_use] + fn shl(self, rhs: RHS) -> Self::Output; +} + +impl Shl for u128 { + type Output = u128; + + fn shl(self, rhs: u128) -> u128 { + self << rhs + } +} + #[lang = "neg"] pub trait Neg { type Output; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 4a8375afac3ce..237f4d11d57f1 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -264,6 +264,9 @@ fn main() { assert_eq!(f2 as i8, -128); assert_eq!(f2 as u8, 0); + let amount = 0; + assert_eq!(1u128 << amount, 1); + static ANOTHER_STATIC: &u8 = &A_STATIC; assert_eq!(*ANOTHER_STATIC, 42); diff --git a/patches/0022-core-Disable-not-compiling-tests.patch b/patches/0022-core-Disable-not-compiling-tests.patch index 3eb10069adad6..8cfffe580a1f0 100644 --- a/patches/0022-core-Disable-not-compiling-tests.patch +++ b/patches/0022-core-Disable-not-compiling-tests.patch @@ -119,21 +119,5 @@ index 6609bc3..241b497 100644 #[test] #[should_panic(expected = "index 0 greater than length of slice")] -diff --git a/library/core/tests/num/ops.rs b/library/core/tests/num/ops.rs -index 9979cc8..d5d1d83 100644 ---- a/library/core/tests/num/ops.rs -+++ b/library/core/tests/num/ops.rs -@@ -238,7 +238,7 @@ macro_rules! test_shift_assign { - } - }; - } --test_shift!(test_shl_defined, Shl::shl); --test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign); --test_shift!(test_shr_defined, Shr::shr); --test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign); -+//test_shift!(test_shl_defined, Shl::shl); -+//test_shift_assign!(test_shl_assign_defined, ShlAssign::shl_assign); -+//test_shift!(test_shr_defined, Shr::shr); -+//test_shift_assign!(test_shr_assign_defined, ShrAssign::shr_assign); -- 2.21.0 (Apple Git-122) diff --git a/patches/0027-Disable-128bit-atomic-operations.patch b/patches/0027-Disable-128bit-atomic-operations.patch new file mode 100644 index 0000000000000..32e5930969061 --- /dev/null +++ b/patches/0027-Disable-128bit-atomic-operations.patch @@ -0,0 +1,103 @@ +From 894e07dfec2624ba539129b1c1d63e1d7d812bda Mon Sep 17 00:00:00 2001 +From: bjorn3 +Date: Thu, 18 Feb 2021 18:45:28 +0100 +Subject: [PATCH] Disable 128bit atomic operations + +Cranelift doesn't support them yet +--- + library/core/src/sync/atomic.rs | 38 --------------------------------- + library/core/tests/atomic.rs | 4 ---- + library/std/src/panic.rs | 6 ------ + 3 files changed, 48 deletions(-) + +diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs +index 81c9e1d..65c9503 100644 +--- a/library/core/src/sync/atomic.rs ++++ b/library/core/src/sync/atomic.rs +@@ -2228,44 +2228,6 @@ atomic_int! { + "AtomicU64::new(0)", + u64 AtomicU64 ATOMIC_U64_INIT + } +-#[cfg(target_has_atomic_load_store = "128")] +-atomic_int! { +- cfg(target_has_atomic = "128"), +- cfg(target_has_atomic_equal_alignment = "128"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), +- unstable(feature = "integer_atomics", issue = "32976"), +- "i128", +- "#![feature(integer_atomics)]\n\n", +- atomic_min, atomic_max, +- 16, +- "AtomicI128::new(0)", +- i128 AtomicI128 ATOMIC_I128_INIT +-} +-#[cfg(target_has_atomic_load_store = "128")] +-atomic_int! { +- cfg(target_has_atomic = "128"), +- cfg(target_has_atomic_equal_alignment = "128"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- unstable(feature = "integer_atomics", issue = "32976"), +- rustc_const_stable(feature = "const_integer_atomics", since = "1.34.0"), +- unstable(feature = "integer_atomics", issue = "32976"), +- "u128", +- "#![feature(integer_atomics)]\n\n", +- atomic_umin, atomic_umax, +- 16, +- "AtomicU128::new(0)", +- u128 AtomicU128 ATOMIC_U128_INIT +-} + + macro_rules! atomic_int_ptr_sized { + ( $($target_pointer_width:literal $align:literal)* ) => { $( +diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs +index 2d1e449..cb6da5d 100644 +--- a/library/core/tests/atomic.rs ++++ b/library/core/tests/atomic.rs +@@ -145,10 +145,6 @@ fn atomic_alignment() { + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "64")] + assert_eq!(align_of::(), size_of::()); +- #[cfg(target_has_atomic = "128")] +- assert_eq!(align_of::(), size_of::()); +- #[cfg(target_has_atomic = "128")] +- assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] + assert_eq!(align_of::(), size_of::()); + #[cfg(target_has_atomic = "ptr")] +diff --git a/library/std/src/panic.rs b/library/std/src/panic.rs +index 89a822a..779fd88 100644 +--- a/library/std/src/panic.rs ++++ b/library/std/src/panic.rs +@@ -279,9 +279,6 @@ impl RefUnwindSafe for atomic::AtomicI32 {} + #[cfg(target_has_atomic_load_store = "64")] + #[stable(feature = "integer_atomics_stable", since = "1.34.0")] + impl RefUnwindSafe for atomic::AtomicI64 {} +-#[cfg(target_has_atomic_load_store = "128")] +-#[unstable(feature = "integer_atomics", issue = "32976")] +-impl RefUnwindSafe for atomic::AtomicI128 {} + + #[cfg(target_has_atomic_load_store = "ptr")] + #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] +@@ -298,9 +295,6 @@ impl RefUnwindSafe for atomic::AtomicU32 {} + #[cfg(target_has_atomic_load_store = "64")] + #[stable(feature = "integer_atomics_stable", since = "1.34.0")] + impl RefUnwindSafe for atomic::AtomicU64 {} +-#[cfg(target_has_atomic_load_store = "128")] +-#[unstable(feature = "integer_atomics", issue = "32976")] +-impl RefUnwindSafe for atomic::AtomicU128 {} + + #[cfg(target_has_atomic_load_store = "8")] + #[stable(feature = "unwind_safe_atomic_refs", since = "1.14.0")] +-- +2.26.2.7.g19db9cfb68 + diff --git a/prepare.sh b/prepare.sh index 08e7cb1802999..ee995ffcfa9f7 100755 --- a/prepare.sh +++ b/prepare.sh @@ -1,4 +1,4 @@ -#!/bin/bash --verbose +#!/usr/bin/env bash set -e rustup component add rust-src rustc-dev llvm-tools-preview diff --git a/rust-toolchain b/rust-toolchain index a08f00d19c20f..908ca52135b66 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2021-01-30 +nightly-2021-03-05 diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000000000..2bd8f7d1bc15d --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,4 @@ +# Matches rustfmt.toml of rustc +version = "Two" +use_small_heuristics = "Max" +merge_derives = false diff --git a/scripts/cargo.sh b/scripts/cargo.sh index a3d6d303057b8..669d2d45b71b5 100755 --- a/scripts/cargo.sh +++ b/scripts/cargo.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash dir=$(dirname "$0") source "$dir/config.sh" diff --git a/scripts/config.sh b/scripts/config.sh index 834708aa9a6fb..c2ed2bf256d59 100644 --- a/scripts/config.sh +++ b/scripts/config.sh @@ -3,7 +3,7 @@ set -e unamestr=$(uname) -if [[ "$unamestr" == 'Linux' ]]; then +if [[ "$unamestr" == 'Linux' || "$unamestr" == 'FreeBSD' ]]; then dylib_ext='so' elif [[ "$unamestr" == 'Darwin' ]]; then dylib_ext='dylib' @@ -26,7 +26,7 @@ export RUSTC=$dir"/bin/cg_clif" export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\ '-Zcodegen-backend='$dir'/lib/librustc_codegen_cranelift.'$dylib_ext' --sysroot '$dir -# FIXME remove once the atomic shim is gone +# FIXME fix `#[linkage = "extern_weak"]` without this if [[ "$unamestr" == 'Darwin' ]]; then export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" fi diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 430f5c469b4b2..694945a87c268 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/scripts/test_bootstrap.sh b/scripts/test_bootstrap.sh index db69541b226cf..6473c6ad67d2e 100755 --- a/scripts/test_bootstrap.sh +++ b/scripts/test_bootstrap.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e cd "$(dirname "$0")/../" @@ -14,21 +14,18 @@ git checkout -- . git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" git apply - < config.toml <) { +pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { fx.add_global_comment( "kind loc.idx param pass mode ty".to_string(), ); } pub(super) fn add_arg_comment<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, kind: &str, local: Option, local_field: Option, @@ -42,11 +42,7 @@ pub(super) fn add_arg_comment<'tcx>( [param_a, param_b] => Cow::Owned(format!("= {:?},{:?}", param_a, param_b)), params => Cow::Owned(format!( "= {}", - params - .iter() - .map(ToString::to_string) - .collect::>() - .join(",") + params.iter().map(ToString::to_string).collect::>().join(",") )), }; @@ -62,7 +58,7 @@ pub(super) fn add_arg_comment<'tcx>( )); } -pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, impl Module>) { +pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { fx.add_global_comment(String::new()); fx.add_global_comment( "kind local ty size align (abi,pref)".to_string(), @@ -70,19 +66,13 @@ pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, impl Module> } pub(super) fn add_local_place_comments<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>, local: Local, ) { let TyAndLayout { ty, layout } = place.layout(); - let rustc_target::abi::Layout { - size, - align, - abi: _, - variants: _, - fields: _, - largest_niche: _, - } = layout; + let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } = + layout; let (kind, extra) = match *place.inner() { CPlaceInner::Var(place_local, var) => { @@ -91,10 +81,7 @@ pub(super) fn add_local_place_comments<'tcx>( } CPlaceInner::VarPair(place_local, var1, var2) => { assert_eq!(local, place_local); - ( - "ssa", - Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index())), - ) + ("ssa", Cow::Owned(format!(",var=({}, {})", var1.index(), var2.index()))) } CPlaceInner::VarLane(_local, _var, _lane) => unreachable!(), CPlaceInner::Addr(ptr, meta) => { @@ -104,18 +91,15 @@ pub(super) fn add_local_place_comments<'tcx>( Cow::Borrowed("") }; match ptr.base_and_offset() { - (crate::pointer::PointerBase::Addr(addr), offset) => ( - "reuse", - format!("storage={}{}{}", addr, offset, meta).into(), - ), - (crate::pointer::PointerBase::Stack(stack_slot), offset) => ( - "stack", - format!("storage={}{}{}", stack_slot, offset, meta).into(), - ), - (crate::pointer::PointerBase::Dangling(align), offset) => ( - "zst", - format!("align={},offset={}", align.bytes(), offset).into(), - ), + (crate::pointer::PointerBase::Addr(addr), offset) => { + ("reuse", format!("storage={}{}{}", addr, offset, meta).into()) + } + (crate::pointer::PointerBase::Stack(stack_slot), offset) => { + ("stack", format!("storage={}{}{}", stack_slot, offset, meta).into()) + } + (crate::pointer::PointerBase::Dangling(align), offset) => { + ("zst", format!("align={},offset={}", align.bytes(), offset).into()) + } } } }; @@ -128,11 +112,7 @@ pub(super) fn add_local_place_comments<'tcx>( size.bytes(), align.abi.bytes(), align.pref.bytes(), - if extra.is_empty() { - "" - } else { - " " - }, + if extra.is_empty() { "" } else { " " }, extra, )); } diff --git a/src/abi/mod.rs b/src/abi/mod.rs index b2647e6c8d384..c79889f8ca1da 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -38,25 +38,15 @@ fn clif_sig_from_fn_abi<'tcx>( | Conv::X86VectorCall | Conv::AmdGpuKernel | Conv::AvrInterrupt - | Conv::AvrNonBlockingInterrupt => { - todo!("{:?}", fn_abi.conv) - } + | Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv), }; - let inputs = fn_abi - .args - .iter() - .map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()) - .flatten(); + let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten(); let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx); // Sometimes the first param is an pointer to the place where the return value needs to be stored. let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect(); - Signature { - params, - returns, - call_conv, - } + Signature { params, returns, call_conv } } pub(crate) fn get_function_sig<'tcx>( @@ -65,34 +55,25 @@ pub(crate) fn get_function_sig<'tcx>( inst: Instance<'tcx>, ) -> Signature { assert!(!inst.substs.needs_infer()); - clif_sig_from_fn_abi( - tcx, - triple, - &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[]), - ) + clif_sig_from_fn_abi(tcx, triple, &FnAbi::of_instance(&RevealAllLayoutCx(tcx), inst, &[])) } /// Instance must be monomorphized pub(crate) fn import_function<'tcx>( tcx: TyCtxt<'tcx>, - module: &mut impl Module, + module: &mut dyn Module, inst: Instance<'tcx>, ) -> FuncId { let name = tcx.symbol_name(inst).name.to_string(); let sig = get_function_sig(tcx, module.isa().triple(), inst); - module - .declare_function(&name, Linkage::Import, &sig) - .unwrap() + module.declare_function(&name, Linkage::Import, &sig).unwrap() } -impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { +impl<'tcx> FunctionCx<'_, '_, 'tcx> { /// Instance must be monomorphized pub(crate) fn get_function_ref(&mut self, inst: Instance<'tcx>) -> FuncRef { - let func_id = import_function(self.tcx, &mut self.cx.module, inst); - let func_ref = self - .cx - .module - .declare_func_in_func(func_id, &mut self.bcx.func); + let func_id = import_function(self.tcx, self.cx.module, inst); + let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); #[cfg(debug_assertions)] self.add_comment(func_ref, format!("{:?}", inst)); @@ -107,20 +88,9 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { returns: Vec, args: &[Value], ) -> &[Value] { - let sig = Signature { - params, - returns, - call_conv: CallConv::triple_default(self.triple()), - }; - let func_id = self - .cx - .module - .declare_function(&name, Linkage::Import, &sig) - .unwrap(); - let func_ref = self - .cx - .module - .declare_func_in_func(func_id, &mut self.bcx.func); + let sig = Signature { params, returns, call_conv: CallConv::triple_default(self.triple()) }; + let func_id = self.cx.module.declare_function(&name, Linkage::Import, &sig).unwrap(); + let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); #[cfg(debug_assertions)] { @@ -140,17 +110,12 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { let (input_tys, args): (Vec<_>, Vec<_>) = args .iter() .map(|arg| { - ( - AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), - arg.load_scalar(self), - ) + (AbiParam::new(self.clif_type(arg.layout().ty).unwrap()), arg.load_scalar(self)) }) .unzip(); let return_layout = self.layout_of(return_ty); let return_tys = if let ty::Tuple(tup) = return_ty.kind() { - tup.types() - .map(|ty| AbiParam::new(self.clif_type(ty).unwrap())) - .collect() + tup.types().map(|ty| AbiParam::new(self.clif_type(ty).unwrap())).collect() } else { vec![AbiParam::new(self.clif_type(return_ty).unwrap())] }; @@ -169,7 +134,7 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { /// Make a [`CPlace`] capable of holding value of the specified type. fn make_local_place<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, local: Local, layout: TyAndLayout<'tcx>, is_ssa: bool, @@ -190,10 +155,7 @@ fn make_local_place<'tcx>( place } -pub(crate) fn codegen_fn_prelude<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - start_block: Block, -) { +pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_block: Block) { fx.bcx.append_block_params_for_function_params(start_block); fx.bcx.switch_to_block(start_block); @@ -204,13 +166,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>( #[cfg(debug_assertions)] self::comments::add_args_header_comment(fx); - let mut block_params_iter = fx - .bcx - .func - .dfg - .block_params(start_block) - .to_vec() - .into_iter(); + let mut block_params_iter = fx.bcx.func.dfg.block_params(start_block).to_vec().into_iter(); let ret_place = self::returning::codegen_return_param(fx, &ssa_analyzed, &mut block_params_iter); assert_eq!(fx.local_map.push(ret_place), RETURN_PLACE); @@ -286,10 +242,10 @@ pub(crate) fn codegen_fn_prelude<'tcx>( if let Some((addr, meta)) = val.try_to_ptr() { let local_decl = &fx.mir.local_decls[local]; // v this ! is important - let internally_mutable = !val.layout().ty.is_freeze( - fx.tcx.at(local_decl.source_info.span), - ParamEnv::reveal_all(), - ); + let internally_mutable = !val + .layout() + .ty + .is_freeze(fx.tcx.at(local_decl.source_info.span), ParamEnv::reveal_all()); if local_decl.mutability == mir::Mutability::Not && !internally_mutable { // We wont mutate this argument, so it is fine to borrow the backing storage // of this argument, to prevent a copy. @@ -321,9 +277,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>( ArgKind::Spread(params) => { for (i, param) in params.into_iter().enumerate() { if let Some(param) = param { - place - .place_field(fx, mir::Field::new(i)) - .write_cvalue(fx, param); + place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param); } } } @@ -340,13 +294,11 @@ pub(crate) fn codegen_fn_prelude<'tcx>( assert_eq!(fx.local_map.push(place), local); } - fx.bcx - .ins() - .jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]); + fx.bcx.ins().jump(*fx.block_map.get(START_BLOCK).unwrap(), &[]); } pub(crate) fn codegen_terminator_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span, current_block: Block, func: &Operand<'tcx>, @@ -354,9 +306,8 @@ pub(crate) fn codegen_terminator_call<'tcx>( destination: Option<(Place<'tcx>, BasicBlock)>, ) { let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); - let fn_sig = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); + let fn_sig = + fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); let destination = destination.map(|(place, bb)| (codegen_place(fx, place), bb)); @@ -404,20 +355,11 @@ pub(crate) fn codegen_terminator_call<'tcx>( let fn_abi = if let Some(instance) = instance { FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args) } else { - FnAbi::of_fn_ptr( - &RevealAllLayoutCx(fx.tcx), - fn_ty.fn_sig(fx.tcx), - &extra_args, - ) + FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args) }; let is_cold = instance - .map(|inst| { - fx.tcx - .codegen_fn_attrs(inst.def_id()) - .flags - .contains(CodegenFnAttrFlags::COLD) - }) + .map(|inst| fx.tcx.codegen_fn_attrs(inst.def_id()).flags.contains(CodegenFnAttrFlags::COLD)) .unwrap_or(false); if is_cold { fx.cold_blocks.insert(current_block); @@ -441,9 +383,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } args } else { - args.iter() - .map(|arg| codegen_operand(fx, arg)) - .collect::>() + args.iter().map(|arg| codegen_operand(fx, arg)).collect::>() }; // | indirect call target @@ -451,10 +391,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // v v let (func_ref, first_arg) = match instance { // Trait object call - Some(Instance { - def: InstanceDef::Virtual(_, idx), - .. - }) => { + Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => { #[cfg(debug_assertions)] { let nop_inst = fx.bcx.ins().nop(); @@ -511,10 +448,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( ) .collect::>(); - if instance - .map(|inst| inst.def.requires_caller_location(fx.tcx)) - .unwrap_or(false) - { + if instance.map(|inst| inst.def.requires_caller_location(fx.tcx)).unwrap_or(false) { // Pass the caller location for `#[track_caller]`. let caller_location = fx.get_caller_location(span); call_args.extend( @@ -543,10 +477,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { if fn_sig.abi != Abi::C { - fx.tcx.sess.span_fatal( - span, - &format!("Variadic call for non-C abi {:?}", fn_sig.abi), - ); + fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args @@ -555,9 +486,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let ty = fx.bcx.func.dfg.value_type(arg); if !ty.is_int() { // FIXME set %al to upperbound on float args once floats are supported - fx.tcx - .sess - .span_fatal(span, &format!("Non int ty {:?} for variadic call", ty)); + fx.tcx.sess.span_fatal(span, &format!("Non int ty {:?} for variadic call", ty)); } AbiParam::new(ty) }) @@ -574,7 +503,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( } pub(crate) fn codegen_drop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, span: Span, drop_place: CPlace<'tcx>, ) { @@ -611,10 +540,7 @@ pub(crate) fn codegen_drop<'tcx>( fx, fx.layout_of(fx.tcx.mk_ref( &ty::RegionKind::ReErased, - TypeAndMut { - ty, - mutbl: crate::rustc_hir::Mutability::Mut, - }, + TypeAndMut { ty, mutbl: crate::rustc_hir::Mutability::Mut }, )), ); let arg_value = adjust_arg_for_abi(fx, arg_value, &fn_abi.args[0]); diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 1202c23dbe7b3..d58f952f53c1a 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -71,12 +71,7 @@ fn cast_target_to_abi_params(cast: CastTarget) -> SmallVec<[AbiParam; 2]> { .prefix .iter() .flatten() - .map(|&kind| { - reg_to_abi_param(Reg { - kind, - size: cast.prefix_chunk_size, - }) - }) + .map(|&kind| reg_to_abi_param(Reg { kind, size: cast.prefix_chunk_size })) .chain((0..rest_count).map(|_| reg_to_abi_param(cast.rest.unit))) .collect::>(); @@ -98,12 +93,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { match self.mode { PassMode::Ignore => smallvec![], PassMode::Direct(attrs) => match &self.layout.abi { - Abi::Scalar(scalar) => { - smallvec![apply_arg_attrs_to_abi_param( - AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())), - attrs - )] - } + Abi::Scalar(scalar) => smallvec![apply_arg_attrs_to_abi_param( + AbiParam::new(scalar_to_clif_type(tcx, scalar.clone())), + attrs + )], Abi::Vector { .. } => { let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap(); smallvec![AbiParam::new(vector_ty)] @@ -122,11 +115,7 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { _ => unreachable!("{:?}", self.layout.abi), }, PassMode::Cast(cast) => cast_target_to_abi_params(cast), - PassMode::Indirect { - attrs, - extra_attrs: None, - on_stack, - } => { + PassMode::Indirect { attrs, extra_attrs: None, on_stack } => { if on_stack { let size = u32::try_from(self.layout.size.bytes()).unwrap(); smallvec![apply_arg_attrs_to_abi_param( @@ -134,17 +123,10 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { attrs )] } else { - smallvec![apply_arg_attrs_to_abi_param( - AbiParam::new(pointer_ty(tcx)), - attrs - )] + smallvec![apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs)] } } - PassMode::Indirect { - attrs, - extra_attrs: Some(extra_attrs), - on_stack, - } => { + PassMode::Indirect { attrs, extra_attrs: Some(extra_attrs), on_stack } => { assert!(!on_stack); smallvec![ apply_arg_attrs_to_abi_param(AbiParam::new(pointer_ty(tcx)), attrs), @@ -158,10 +140,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { match self.mode { PassMode::Ignore => (None, vec![]), PassMode::Direct(_) => match &self.layout.abi { - Abi::Scalar(scalar) => ( - None, - vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))], - ), + Abi::Scalar(scalar) => { + (None, vec![AbiParam::new(scalar_to_clif_type(tcx, scalar.clone()))]) + } Abi::Vector { .. } => { let vector_ty = crate::intrinsics::clif_vector_type(tcx, self.layout).unwrap(); (None, vec![AbiParam::new(vector_ty)]) @@ -177,31 +158,19 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> { _ => unreachable!("{:?}", self.layout.abi), }, PassMode::Cast(cast) => (None, cast_target_to_abi_params(cast).into_iter().collect()), - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack, - } => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack } => { assert!(!on_stack); - ( - Some(AbiParam::special( - pointer_ty(tcx), - ArgumentPurpose::StructReturn, - )), - vec![], - ) + (Some(AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructReturn)), vec![]) + } + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), } } } pub(super) fn to_casted_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, cast: CastTarget, ) -> SmallVec<[Value; 2]> { @@ -211,9 +180,7 @@ pub(super) fn to_casted_value<'tcx>( cast_target_to_abi_params(cast) .into_iter() .map(|param| { - let val = ptr - .offset_i64(fx, offset) - .load(fx, param.value_type, MemFlags::new()); + let val = ptr.offset_i64(fx, offset).load(fx, param.value_type, MemFlags::new()); offset += i64::from(param.value_type.bytes()); val }) @@ -221,16 +188,13 @@ pub(super) fn to_casted_value<'tcx>( } pub(super) fn from_casted_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, block_params: &[Value], layout: TyAndLayout<'tcx>, cast: CastTarget, ) -> CValue<'tcx> { let abi_params = cast_target_to_abi_params(cast); - let abi_param_size: u32 = abi_params - .iter() - .map(|param| param.value_type.bytes()) - .sum(); + let abi_param_size: u32 = abi_params.iter().map(|param| param.value_type.bytes()).sum(); let layout_size = u32::try_from(layout.size.bytes()).unwrap(); let stack_slot = fx.bcx.create_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, @@ -260,7 +224,7 @@ pub(super) fn from_casted_value<'tcx>( /// Get a set of values to be passed as function arguments. pub(super) fn adjust_arg_for_abi<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, ) -> SmallVec<[Value; 2]> { @@ -283,7 +247,7 @@ pub(super) fn adjust_arg_for_abi<'tcx>( /// Create a [`CValue`] containing the value of a function parameter adding clif function parameters /// as necessary. pub(super) fn cvalue_for_param<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, #[cfg_attr(not(debug_assertions), allow(unused_variables))] local: Option, #[cfg_attr(not(debug_assertions), allow(unused_variables))] local_field: Option, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, @@ -294,10 +258,7 @@ pub(super) fn cvalue_for_param<'tcx>( .into_iter() .map(|abi_param| { let block_param = block_params_iter.next().unwrap(); - assert_eq!( - fx.bcx.func.dfg.value_type(block_param), - abi_param.value_type - ); + assert_eq!(fx.bcx.func.dfg.value_type(block_param), abi_param.value_type); block_param }) .collect::>(); @@ -321,29 +282,14 @@ pub(super) fn cvalue_for_param<'tcx>( } PassMode::Pair(_, _) => { assert_eq!(block_params.len(), 2, "{:?}", block_params); - Some(CValue::by_val_pair( - block_params[0], - block_params[1], - arg_abi.layout, - )) + Some(CValue::by_val_pair(block_params[0], block_params[1], arg_abi.layout)) } PassMode::Cast(cast) => Some(from_casted_value(fx, &block_params, arg_abi.layout, cast)), - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { assert_eq!(block_params.len(), 1, "{:?}", block_params); - Some(CValue::by_ref( - Pointer::new(block_params[0]), - arg_abi.layout, - )) + Some(CValue::by_ref(Pointer::new(block_params[0]), arg_abi.layout)) } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => { + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { assert_eq!(block_params.len(), 2, "{:?}", block_params); Some(CValue::by_ref_unsized( Pointer::new(block_params[0]), diff --git a/src/abi/returning.rs b/src/abi/returning.rs index a382963bf1ed7..9fa066df69b3c 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -8,14 +8,13 @@ use smallvec::{smallvec, SmallVec}; /// Can the given type be returned into an ssa var or does it need to be returned on the stack. pub(crate) fn can_return_to_ssa_var<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, func: &mir::Operand<'tcx>, args: &[mir::Operand<'tcx>], ) -> bool { let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx)); - let fn_sig = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); + let fn_sig = + fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx)); // Handle special calls like instrinsics and empty drop glue. let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() { @@ -42,11 +41,7 @@ pub(crate) fn can_return_to_ssa_var<'tcx>( let fn_abi = if let Some(instance) = instance { FnAbi::of_instance(&RevealAllLayoutCx(fx.tcx), instance, &extra_args) } else { - FnAbi::of_fn_ptr( - &RevealAllLayoutCx(fx.tcx), - fn_ty.fn_sig(fx.tcx), - &extra_args, - ) + FnAbi::of_fn_ptr(&RevealAllLayoutCx(fx.tcx), fn_ty.fn_sig(fx.tcx), &extra_args) }; match fn_abi.ret.mode { PassMode::Ignore | PassMode::Direct(_) | PassMode::Pair(_, _) => true, @@ -58,15 +53,12 @@ pub(crate) fn can_return_to_ssa_var<'tcx>( /// Return a place where the return value of the current function can be written to. If necessary /// this adds an extra parameter pointing to where the return value needs to be stored. pub(super) fn codegen_return_param<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, ssa_analyzed: &rustc_index::vec::IndexVec, block_params_iter: &mut impl Iterator, ) -> CPlace<'tcx> { let (ret_place, ret_param): (_, SmallVec<[_; 2]>) = match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore => ( - CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout), - smallvec![], - ), + PassMode::Ignore => (CPlace::no_place(fx.fn_abi.as_ref().unwrap().ret.layout), smallvec![]), PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => { let is_ssa = ssa_analyzed[RETURN_PLACE] == crate::analyze::SsaKind::Ssa; ( @@ -79,26 +71,17 @@ pub(super) fn codegen_return_param<'tcx>( smallvec![], ) } - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { let ret_param = block_params_iter.next().unwrap(); assert_eq!(fx.bcx.func.dfg.value_type(ret_param), pointer_ty(fx.tcx)); ( - CPlace::for_ptr( - Pointer::new(ret_param), - fx.fn_abi.as_ref().unwrap().ret.layout, - ), + CPlace::for_ptr(Pointer::new(ret_param), fx.fn_abi.as_ref().unwrap().ret.layout), smallvec![ret_param], ) } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } }; #[cfg(not(debug_assertions))] @@ -120,27 +103,21 @@ pub(super) fn codegen_return_param<'tcx>( /// Invokes the closure with if necessary a value representing the return pointer. When the closure /// returns the call return value(s) if any are written to the correct place. -pub(super) fn codegen_with_call_return_arg<'tcx, M: Module, T>( - fx: &mut FunctionCx<'_, 'tcx, M>, +pub(super) fn codegen_with_call_return_arg<'tcx, T>( + fx: &mut FunctionCx<'_, '_, 'tcx>, ret_arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, ret_place: Option>, - f: impl FnOnce(&mut FunctionCx<'_, 'tcx, M>, Option) -> (Inst, T), + f: impl FnOnce(&mut FunctionCx<'_, '_, 'tcx>, Option) -> (Inst, T), ) -> (Inst, T) { let return_ptr = match ret_arg_abi.mode { PassMode::Ignore => None, - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => match ret_place { + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => match ret_place { Some(ret_place) => Some(ret_place.to_ptr().get_addr(fx)), None => Some(fx.bcx.ins().iconst(fx.pointer_type, 43)), // FIXME allocate temp stack slot }, - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } PassMode::Direct(_) | PassMode::Pair(_, _) | PassMode::Cast(_) => None, }; @@ -177,37 +154,24 @@ pub(super) fn codegen_with_call_return_arg<'tcx, M: Module, T>( ret_place.write_cvalue(fx, result); } } - PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => {} - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => {} + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } } (call_inst, meta) } /// Codegen a return instruction with the right return value(s) if any. -pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, impl Module>) { +pub(crate) fn codegen_return(fx: &mut FunctionCx<'_, '_, '_>) { match fx.fn_abi.as_ref().unwrap().ret.mode { - PassMode::Ignore - | PassMode::Indirect { - attrs: _, - extra_attrs: None, - on_stack: _, - } => { + PassMode::Ignore | PassMode::Indirect { attrs: _, extra_attrs: None, on_stack: _ } => { fx.bcx.ins().return_(&[]); } - PassMode::Indirect { - attrs: _, - extra_attrs: Some(_), - on_stack: _, - } => unreachable!("unsized return value"), + PassMode::Indirect { attrs: _, extra_attrs: Some(_), on_stack: _ } => { + unreachable!("unsized return value") + } PassMode::Direct(_) => { let place = fx.get_local_place(RETURN_PLACE); let ret_val = place.to_cvalue(fx).load_scalar(fx); diff --git a/src/allocator.rs b/src/allocator.rs index 6c5916550ff63..efb64233ef2c3 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -66,13 +66,9 @@ fn codegen_inner( let callee_name = kind.fn_name(method.name); //eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns); - let func_id = module - .declare_function(&caller_name, Linkage::Export, &sig) - .unwrap(); + let func_id = module.declare_function(&caller_name, Linkage::Export, &sig).unwrap(); - 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(); ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig.clone()); @@ -96,11 +92,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function( - func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) + .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } @@ -114,13 +106,10 @@ fn codegen_inner( let callee_name = kind.fn_name(sym::oom); //eprintln!("Codegen allocator shim {} -> {} ({:?} -> {:?})", caller_name, callee_name, sig.params, sig.returns); - let func_id = module - .declare_function("__rust_alloc_error_handler", Linkage::Export, &sig) - .unwrap(); + let func_id = + module.declare_function("__rust_alloc_error_handler", Linkage::Export, &sig).unwrap(); - 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(); ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig); @@ -143,11 +132,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function( - func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) + .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } diff --git a/src/analyze.rs b/src/analyze.rs index 62fbcfe3f7a5d..efead25552f4d 100644 --- a/src/analyze.rs +++ b/src/analyze.rs @@ -11,7 +11,7 @@ pub(crate) enum SsaKind { Ssa, } -pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec { +pub(crate) fn analyze(fx: &FunctionCx<'_, '_, '_>) -> IndexVec { let mut flag_map = fx .mir .local_decls @@ -40,12 +40,7 @@ pub(crate) fn analyze(fx: &FunctionCx<'_, '_, impl Module>) -> IndexVec { + TerminatorKind::Call { destination, func, args, .. } => { if let Some((dest_place, _dest_bb)) = destination { if !crate::abi::can_return_to_ssa_var(fx, func, args) { not_ssa(&mut flag_map, dest_place.local) diff --git a/src/archive.rs b/src/archive.rs index 96579054389ab..7583fc424071e 100644 --- a/src/archive.rs +++ b/src/archive.rs @@ -12,10 +12,7 @@ use object::{Object, ObjectSymbol, SymbolKind}; #[derive(Debug)] enum ArchiveEntry { - FromArchive { - archive_index: usize, - entry_index: usize, - }, + FromArchive { archive_index: usize, entry_index: usize }, File(PathBuf), } @@ -30,7 +27,6 @@ pub(crate) struct ArArchiveBuilder<'a> { // Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at // the end of an archive for linkers to not get confused. entries: Vec<(String, ArchiveEntry)>, - update_symbols: bool, } impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { @@ -46,10 +42,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { let entry = entry.unwrap(); entries.push(( String::from_utf8(entry.header().identifier().to_vec()).unwrap(), - ArchiveEntry::FromArchive { - archive_index: 0, - entry_index: i, - }, + ArchiveEntry::FromArchive { archive_index: 0, entry_index: i }, )); i += 1; } @@ -69,7 +62,6 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { src_archives, entries, - update_symbols: false, } } @@ -95,14 +87,9 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { fn add_native_library(&mut self, name: rustc_span::symbol::Symbol) { let location = find_library(name, &self.lib_search_paths, self.sess); - self.add_archive(location.clone(), |_| false) - .unwrap_or_else(|e| { - panic!( - "failed to add native library {}: {}", - location.to_string_lossy(), - e - ); - }); + self.add_archive(location.clone(), |_| false).unwrap_or_else(|e| { + panic!("failed to add native library {}: {}", location.to_string_lossy(), e); + }); } fn add_rlib( @@ -136,9 +123,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { }) } - fn update_symbols(&mut self) { - self.update_symbols = true; - } + fn update_symbols(&mut self) {} fn build(mut self) { enum BuilderKind { @@ -156,10 +141,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { // FIXME only read the symbol table of the object files to avoid having to keep all // object files in memory at once, or read them twice. let data = match entry { - ArchiveEntry::FromArchive { - archive_index, - entry_index, - } => { + ArchiveEntry::FromArchive { archive_index, entry_index } => { // FIXME read symbols from symtab use std::io::Read; let (ref _src_archive_path, ref mut src_archive) = @@ -225,10 +207,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { err )); }), - entries - .iter() - .map(|(name, _)| name.as_bytes().to_vec()) - .collect(), + entries.iter().map(|(name, _)| name.as_bytes().to_vec()).collect(), ar::GnuSymbolTableFormat::Size32, symbol_table, ) @@ -271,8 +250,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { .expect("Couldn't run ranlib"); if !status.success() { - self.sess - .fatal(&format!("Ranlib exited with code {:?}", status.code())); + self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code())); } } } @@ -292,13 +270,8 @@ impl<'a> ArArchiveBuilder<'a> { let file_name = String::from_utf8(entry.header().identifier().to_vec()) .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err))?; if !skip(&file_name) { - self.entries.push(( - file_name, - ArchiveEntry::FromArchive { - archive_index, - entry_index: i, - }, - )); + self.entries + .push((file_name, ArchiveEntry::FromArchive { archive_index, entry_index: i })); } i += 1; } diff --git a/src/atomic_shim.rs b/src/atomic_shim.rs deleted file mode 100644 index 674e6d907510a..0000000000000 --- a/src/atomic_shim.rs +++ /dev/null @@ -1,185 +0,0 @@ -//! Atomic intrinsics are implemented using a global lock for now, as Cranelift doesn't support -//! atomic operations yet. - -// FIXME implement atomic instructions in Cranelift. - -use crate::prelude::*; - -#[cfg(all(feature = "jit", unix))] -#[no_mangle] -static mut __cg_clif_global_atomic_mutex: libc::pthread_mutex_t = libc::PTHREAD_MUTEX_INITIALIZER; - -pub(crate) fn init_global_lock( - module: &mut impl Module, - bcx: &mut FunctionBuilder<'_>, - use_jit: bool, -) { - if use_jit { - // When using JIT, dylibs won't find the __cg_clif_global_atomic_mutex data object defined here, - // so instead we define it in the cg_clif dylib. - - return; - } - - let mut data_ctx = DataContext::new(); - data_ctx.define_zeroinit(1024); // 1024 bytes should be big enough on all platforms. - data_ctx.set_align(16); - let atomic_mutex = module - .declare_data( - "__cg_clif_global_atomic_mutex", - Linkage::Export, - true, - false, - ) - .unwrap(); - module.define_data(atomic_mutex, &data_ctx).unwrap(); - - let pthread_mutex_init = module - .declare_function( - "pthread_mutex_init", - Linkage::Import, - &cranelift_codegen::ir::Signature { - call_conv: module.target_config().default_call_conv, - params: vec![ - AbiParam::new( - module.target_config().pointer_type(), /* *mut pthread_mutex_t */ - ), - AbiParam::new( - module.target_config().pointer_type(), /* *const pthread_mutex_attr_t */ - ), - ], - returns: vec![AbiParam::new(types::I32 /* c_int */)], - }, - ) - .unwrap(); - - let pthread_mutex_init = module.declare_func_in_func(pthread_mutex_init, bcx.func); - - let atomic_mutex = module.declare_data_in_func(atomic_mutex, bcx.func); - let atomic_mutex = bcx - .ins() - .global_value(module.target_config().pointer_type(), atomic_mutex); - - let nullptr = bcx.ins().iconst(module.target_config().pointer_type(), 0); - - bcx.ins().call(pthread_mutex_init, &[atomic_mutex, nullptr]); -} - -pub(crate) fn init_global_lock_constructor( - module: &mut impl Module, - constructor_name: &str, -) -> FuncId { - let sig = Signature::new(CallConv::SystemV); - let init_func_id = module - .declare_function(constructor_name, Linkage::Export, &sig) - .unwrap(); - - let mut ctx = Context::new(); - ctx.func = Function::with_name_signature(ExternalName::user(0, 0), sig); - { - let mut func_ctx = FunctionBuilderContext::new(); - let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); - - let block = bcx.create_block(); - bcx.switch_to_block(block); - - crate::atomic_shim::init_global_lock(module, &mut bcx, false); - - bcx.ins().return_(&[]); - bcx.seal_all_blocks(); - bcx.finalize(); - } - module - .define_function( - init_func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) - .unwrap(); - - init_func_id -} - -pub(crate) fn lock_global_lock(fx: &mut FunctionCx<'_, '_, impl Module>) { - let atomic_mutex = fx - .cx - .module - .declare_data( - "__cg_clif_global_atomic_mutex", - Linkage::Import, - true, - false, - ) - .unwrap(); - - let pthread_mutex_lock = fx - .cx - .module - .declare_function( - "pthread_mutex_lock", - Linkage::Import, - &cranelift_codegen::ir::Signature { - call_conv: fx.cx.module.target_config().default_call_conv, - params: vec![AbiParam::new( - fx.cx.module.target_config().pointer_type(), /* *mut pthread_mutex_t */ - )], - returns: vec![AbiParam::new(types::I32 /* c_int */)], - }, - ) - .unwrap(); - - let pthread_mutex_lock = fx - .cx - .module - .declare_func_in_func(pthread_mutex_lock, fx.bcx.func); - - let atomic_mutex = fx.cx.module.declare_data_in_func(atomic_mutex, fx.bcx.func); - let atomic_mutex = fx - .bcx - .ins() - .global_value(fx.cx.module.target_config().pointer_type(), atomic_mutex); - - fx.bcx.ins().call(pthread_mutex_lock, &[atomic_mutex]); -} - -pub(crate) fn unlock_global_lock(fx: &mut FunctionCx<'_, '_, impl Module>) { - let atomic_mutex = fx - .cx - .module - .declare_data( - "__cg_clif_global_atomic_mutex", - Linkage::Import, - true, - false, - ) - .unwrap(); - - let pthread_mutex_unlock = fx - .cx - .module - .declare_function( - "pthread_mutex_unlock", - Linkage::Import, - &cranelift_codegen::ir::Signature { - call_conv: fx.cx.module.target_config().default_call_conv, - params: vec![AbiParam::new( - fx.cx.module.target_config().pointer_type(), /* *mut pthread_mutex_t */ - )], - returns: vec![AbiParam::new(types::I32 /* c_int */)], - }, - ) - .unwrap(); - - let pthread_mutex_unlock = fx - .cx - .module - .declare_func_in_func(pthread_mutex_unlock, fx.bcx.func); - - let atomic_mutex = fx.cx.module.declare_data_in_func(atomic_mutex, fx.bcx.func); - let atomic_mutex = fx - .bcx - .ins() - .global_value(fx.cx.module.target_config().pointer_type(), atomic_mutex); - - fx.bcx.ins().call(pthread_mutex_unlock, &[atomic_mutex]); -} diff --git a/src/backend.rs b/src/backend.rs index 0ce34c904bdcc..eb7927fc4adeb 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -8,7 +8,7 @@ use rustc_session::Session; use cranelift_module::FuncId; use object::write::*; -use object::{RelocationEncoding, RelocationKind, SectionKind, SymbolFlags}; +use object::{RelocationEncoding, SectionKind, SymbolFlags}; use cranelift_object::{ObjectBuilder, ObjectModule, ObjectProduct}; @@ -22,9 +22,7 @@ pub(crate) trait WriteMetadata { impl WriteMetadata for object::write::Object { fn add_rustc_section(&mut self, symbol_name: String, data: Vec, _is_like_osx: bool) { - let segment = self - .segment_name(object::write::StandardSegment::Data) - .to_vec(); + let segment = self.segment_name(object::write::StandardSegment::Data).to_vec(); let section_id = self.add_section(segment, b".rustc".to_vec(), object::SectionKind::Data); let offset = self.append_section_data(section_id, &data, 1); // For MachO and probably PE this is necessary to prevent the linker from throwing away the @@ -74,11 +72,7 @@ impl WriteDebugInfo for ObjectProduct { let section_id = self.object.add_section( segment, name, - if id == SectionId::EhFrame { - SectionKind::ReadOnlyData - } else { - SectionKind::Debug - }, + if id == SectionId::EhFrame { SectionKind::ReadOnlyData } else { SectionKind::Debug }, ); self.object .section_mut(section_id) @@ -118,49 +112,6 @@ impl WriteDebugInfo for ObjectProduct { } } -// FIXME remove once atomic instructions are implemented in Cranelift. -pub(crate) trait AddConstructor { - fn add_constructor(&mut self, func_id: FuncId); -} - -impl AddConstructor for ObjectProduct { - fn add_constructor(&mut self, func_id: FuncId) { - let symbol = self.function_symbol(func_id); - let segment = self - .object - .segment_name(object::write::StandardSegment::Data); - let init_array_section = - self.object - .add_section(segment.to_vec(), b".init_array".to_vec(), SectionKind::Data); - let address_size = self - .object - .architecture() - .address_size() - .expect("address_size must be known") - .bytes(); - self.object.append_section_data( - init_array_section, - &std::iter::repeat(0) - .take(address_size.into()) - .collect::>(), - 8, - ); - self.object - .add_relocation( - init_array_section, - object::write::Relocation { - offset: 0, - size: address_size * 8, - kind: RelocationKind::Absolute, - encoding: RelocationEncoding::Generic, - symbol, - addend: 0, - }, - ) - .unwrap(); - } -} - pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object)) -> Vec { let triple = crate::build_isa(sess).triple().clone(); @@ -175,10 +126,9 @@ pub(crate) fn with_object(sess: &Session, name: &str, f: impl FnOnce(&mut Object target_lexicon::Architecture::X86_64 => object::Architecture::X86_64, target_lexicon::Architecture::Arm(_) => object::Architecture::Arm, target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64, - architecture => sess.fatal(&format!( - "target architecture {:?} is unsupported", - architecture, - )), + architecture => { + sess.fatal(&format!("target architecture {:?} is unsupported", architecture,)) + } }; let endian = match triple.endianness().unwrap() { target_lexicon::Endianness::Little => object::Endianness::Little, diff --git a/src/base.rs b/src/base.rs index 4842628a99da7..0a7734d6a0443 100644 --- a/src/base.rs +++ b/src/base.rs @@ -8,7 +8,7 @@ use rustc_target::abi::call::FnAbi; use crate::prelude::*; pub(crate) fn codegen_fn<'tcx>( - cx: &mut crate::CodegenCx<'tcx, impl Module>, + cx: &mut crate::CodegenCx<'_, 'tcx>, instance: Instance<'tcx>, linkage: Linkage, ) { @@ -38,9 +38,8 @@ pub(crate) fn codegen_fn<'tcx>( // Predefine blocks let start_block = bcx.create_block(); - let block_map: IndexVec = (0..mir.basic_blocks().len()) - .map(|_| bcx.create_block()) - .collect(); + let block_map: IndexVec = + (0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect(); // Make FunctionCx let pointer_type = cx.module.target_config().pointer_type(); @@ -68,22 +67,23 @@ pub(crate) fn codegen_fn<'tcx>( inline_asm_index: 0, }; - let arg_uninhabited = fx.mir.args_iter().any(|arg| { - fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)) - .abi - .is_uninhabited() - }); + let arg_uninhabited = fx + .mir + .args_iter() + .any(|arg| fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)).abi.is_uninhabited()); - if arg_uninhabited { - fx.bcx - .append_block_params_for_function_params(fx.block_map[START_BLOCK]); + if !crate::constant::check_constants(&mut fx) { + fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); + fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); + crate::trap::trap_unreachable(&mut fx, "compilation should have been aborted"); + } else if arg_uninhabited { + fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]); fx.bcx.switch_to_block(fx.block_map[START_BLOCK]); crate::trap::trap_unreachable(&mut fx, "function has uninhabited argument"); } else { tcx.sess.time("codegen clif ir", || { - tcx.sess.time("codegen prelude", || { - crate::abi::codegen_fn_prelude(&mut fx, start_block) - }); + tcx.sess + .time("codegen prelude", || crate::abi::codegen_fn_prelude(&mut fx, start_block)); codegen_fn_content(&mut fx); }); } @@ -131,11 +131,7 @@ pub(crate) fn codegen_fn<'tcx>( let module = &mut cx.module; tcx.sess.time("define function", || { module - .define_function( - func_id, - context, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) + .define_function(func_id, context, &mut cranelift_codegen::binemit::NullTrapSink {}) .unwrap() }); @@ -149,14 +145,12 @@ pub(crate) fn codegen_fn<'tcx>( &clif_comments, ); - if let Some(mach_compile_result) = &context.mach_compile_result { - if let Some(disasm) = &mach_compile_result.disasm { - crate::pretty_clif::write_ir_file( - tcx, - &format!("{}.vcode", tcx.symbol_name(instance).name), - |file| file.write_all(disasm.as_bytes()), - ) - } + if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm { + crate::pretty_clif::write_ir_file( + tcx, + &format!("{}.vcode", tcx.symbol_name(instance).name), + |file| file.write_all(disasm.as_bytes()), + ) } // Define debuginfo for function @@ -199,16 +193,13 @@ pub(crate) fn verify_func( Some(Box::new(writer)), err, ); - tcx.sess - .fatal(&format!("cranelift verify error:\n{}", pretty_error)); + tcx.sess.fatal(&format!("cranelift verify error:\n{}", pretty_error)); } } }); } -fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { - crate::constant::check_constants(fx); - +fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() { let block = fx.get_block(bb); fx.bcx.switch_to_block(block); @@ -231,11 +222,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { #[cfg(debug_assertions)] { let mut terminator_head = "\n".to_string(); - bb_data - .terminator() - .kind - .fmt_head(&mut terminator_head) - .unwrap(); + bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); let inst = fx.bcx.func.layout.last_inst(block).unwrap(); fx.add_comment(inst, terminator_head); } @@ -267,13 +254,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { TerminatorKind::Return => { crate::abi::codegen_return(fx); } - TerminatorKind::Assert { - cond, - expected, - msg, - target, - cleanup: _, - } => { + TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => { if !fx.tcx.sess.overflow_checks() { if let mir::AssertKind::OverflowNeg(_) = *msg { let target = fx.get_block(*target); @@ -319,11 +300,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { } } - TerminatorKind::SwitchInt { - discr, - switch_ty, - targets, - } => { + TerminatorKind::SwitchInt { discr, switch_ty, targets } => { let discr = codegen_operand(fx, discr).load_scalar(fx); let use_bool_opt = switch_ty.kind() == fx.tcx.types.bool.kind() @@ -433,11 +410,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { | TerminatorKind::GeneratorDrop => { bug!("shouldn't exist at codegen {:?}", bb_data.terminator()); } - TerminatorKind::Drop { - place, - target, - unwind: _, - } => { + TerminatorKind::Drop { place, target, unwind: _ } => { let drop_place = codegen_place(fx, *place); crate::abi::codegen_drop(fx, bb_data.terminator().source_info.span, drop_place); @@ -452,7 +425,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, impl Module>) { } fn codegen_stmt<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, #[allow(unused_variables)] cur_block: Block, stmt: &Statement<'tcx>, ) { @@ -470,10 +443,7 @@ fn codegen_stmt<'tcx>( } match &stmt.kind { - StatementKind::SetDiscriminant { - place, - variant_index, - } => { + StatementKind::SetDiscriminant { place, variant_index } => { let place = codegen_place(fx, **place); crate::discriminant::codegen_set_discriminant(fx, place, *variant_index); } @@ -594,19 +564,11 @@ fn codegen_stmt<'tcx>( let from_ty = operand.layout().ty; let to_ty = fx.monomorphize(to_ty); - fn is_fat_ptr<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, - ty: Ty<'tcx>, - ) -> bool { + fn is_fat_ptr<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> bool { ty.builtin_deref(true) - .map( - |ty::TypeAndMut { - ty: pointee_ty, - mutbl: _, - }| { - has_ptr_meta(fx.tcx, pointee_ty) - }, - ) + .map(|ty::TypeAndMut { ty: pointee_ty, mutbl: _ }| { + has_ptr_meta(fx.tcx, pointee_ty) + }) .unwrap_or(false) } @@ -626,50 +588,22 @@ fn codegen_stmt<'tcx>( ty::Uint(_) | ty::Int(_) => {} _ => unreachable!("cast adt {} -> {}", from_ty, to_ty), } + let to_clif_ty = fx.clif_type(to_ty).unwrap(); - use rustc_target::abi::{Int, TagEncoding, Variants}; - - match operand.layout().variants { - Variants::Single { index } => { - let discr = operand - .layout() - .ty - .discriminant_for_variant(fx.tcx, index) - .unwrap(); - let discr = if discr.ty.is_signed() { - fx.layout_of(discr.ty).size.sign_extend(discr.val) - } else { - discr.val - }; - let discr = discr.into(); - - let discr = CValue::const_val(fx, fx.layout_of(to_ty), discr); - lval.write_cvalue(fx, discr); - } - Variants::Multiple { - ref tag, - tag_field, - tag_encoding: TagEncoding::Direct, - variants: _, - } => { - let cast_to = fx.clif_type(dest_layout.ty).unwrap(); - - // Read the tag/niche-encoded discriminant from memory. - let encoded_discr = - operand.value_field(fx, mir::Field::new(tag_field)); - let encoded_discr = encoded_discr.load_scalar(fx); - - // Decode the discriminant (specifically if it's niche-encoded). - let signed = match tag.value { - Int(_, signed) => signed, - _ => false, - }; - let val = clif_intcast(fx, encoded_discr, cast_to, signed); - let val = CValue::by_val(val, dest_layout); - lval.write_cvalue(fx, val); - } - Variants::Multiple { .. } => unreachable!(), - } + let discriminant = crate::discriminant::codegen_get_discriminant( + fx, + operand, + fx.layout_of(operand.layout().ty.discriminant_ty(fx.tcx)), + ) + .load_scalar(fx); + + let res = crate::cast::clif_intcast( + fx, + discriminant, + to_clif_ty, + to_ty.is_signed(), + ); + lval.write_cvalue(fx, CValue::by_val(res, dest_layout)); } else { let to_clif_ty = fx.clif_type(to_ty).unwrap(); let from = operand.load_scalar(fx); @@ -730,8 +664,7 @@ fn codegen_stmt<'tcx>( // FIXME use emit_small_memset where possible let addr = lval.to_ptr().get_addr(fx); let val = operand.load_scalar(fx); - fx.bcx - .call_memset(fx.cx.module.target_config(), addr, val, times); + fx.bcx.call_memset(fx.cx.module.target_config(), addr, val, times); } else { let loop_block = fx.bcx.create_block(); let loop_block2 = fx.bcx.create_block(); @@ -766,25 +699,19 @@ fn codegen_stmt<'tcx>( let content_ty = fx.monomorphize(content_ty); let layout = fx.layout_of(content_ty); let llsize = fx.bcx.ins().iconst(usize_type, layout.size.bytes() as i64); - let llalign = fx - .bcx - .ins() - .iconst(usize_type, layout.align.abi.bytes() as i64); + let llalign = fx.bcx.ins().iconst(usize_type, layout.align.abi.bytes() as i64); let box_layout = fx.layout_of(fx.tcx.mk_box(content_ty)); // Allocate space: - let def_id = match fx - .tcx - .lang_items() - .require(rustc_hir::LangItem::ExchangeMalloc) - { - Ok(id) => id, - Err(s) => { - fx.tcx - .sess - .fatal(&format!("allocation of `{}` {}", box_layout.ty, s)); - } - }; + let def_id = + match fx.tcx.lang_items().require(rustc_hir::LangItem::ExchangeMalloc) { + Ok(id) => id, + Err(s) => { + fx.tcx + .sess + .fatal(&format!("allocation of `{}` {}", box_layout.ty, s)); + } + }; let instance = ty::Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let func_ref = fx.get_function_ref(instance); let call = fx.bcx.ins().call(func_ref, &[llsize, llalign]); @@ -792,10 +719,11 @@ fn codegen_stmt<'tcx>( lval.write_cvalue(fx, CValue::by_val(ptr, box_layout)); } Rvalue::NullaryOp(NullOp::SizeOf, ty) => { - assert!(lval - .layout() - .ty - .is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all())); + assert!( + lval.layout() + .ty + .is_sized(fx.tcx.at(stmt.source_info.span), ParamEnv::reveal_all()) + ); let ty_size = fx.layout_of(fx.monomorphize(ty)).size.bytes(); let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), ty_size.into()); @@ -823,11 +751,7 @@ fn codegen_stmt<'tcx>( StatementKind::LlvmInlineAsm(asm) => { use rustc_span::symbol::Symbol; - let LlvmInlineAsm { - asm, - outputs, - inputs, - } = &**asm; + let LlvmInlineAsm { asm, outputs, inputs } = &**asm; let rustc_hir::LlvmInlineAsmInner { asm: asm_code, // Name outputs: output_names, // Vec @@ -843,15 +767,9 @@ fn codegen_stmt<'tcx>( // Black box } "mov %rbx, %rsi\n cpuid\n xchg %rbx, %rsi" => { - assert_eq!( - input_names, - &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")] - ); + assert_eq!(input_names, &[Symbol::intern("{eax}"), Symbol::intern("{ecx}")]); assert_eq!(output_names.len(), 4); - for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]) - .iter() - .enumerate() - { + for (i, c) in (&["={eax}", "={esi}", "={ecx}", "={edx}"]).iter().enumerate() { assert_eq!(&output_names[i].constraint.as_str(), c); assert!(!output_names[i].is_rw); assert!(!output_names[i].is_indirect); @@ -897,12 +815,7 @@ fn codegen_stmt<'tcx>( crate::trap::trap_unimplemented(fx, "_xgetbv arch intrinsic is not supported"); } // ___chkstk, ___chkstk_ms and __alloca are only used on Windows - _ if fx - .tcx - .symbol_name(fx.instance) - .name - .starts_with("___chkstk") => - { + _ if fx.tcx.symbol_name(fx.instance).name.starts_with("___chkstk") => { crate::trap::trap_unimplemented(fx, "Stack probes are not supported"); } _ if fx.tcx.symbol_name(fx.instance).name == "__alloca" => { @@ -922,27 +835,21 @@ fn codegen_stmt<'tcx>( } } -fn codegen_array_len<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - place: CPlace<'tcx>, -) -> Value { +fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value { match *place.layout().ty.kind() { ty::Array(_elem_ty, len) => { - let len = fx - .monomorphize(len) - .eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64; + let len = fx.monomorphize(len).eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64; fx.bcx.ins().iconst(fx.pointer_type, len) } - ty::Slice(_elem_ty) => place - .to_ptr_maybe_unsized() - .1 - .expect("Length metadata for slice place"), + ty::Slice(_elem_ty) => { + place.to_ptr_maybe_unsized().1.expect("Length metadata for slice place") + } _ => bug!("Rvalue::Len({:?})", place), } } pub(crate) fn codegen_place<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, place: Place<'tcx>, ) -> CPlace<'tcx> { let mut cplace = fx.get_local_place(place.local); @@ -959,11 +866,7 @@ pub(crate) fn codegen_place<'tcx>( let index = fx.get_local_place(local).to_cvalue(fx).load_scalar(fx); cplace = cplace.place_index(fx, index); } - PlaceElem::ConstantIndex { - offset, - min_length: _, - from_end, - } => { + PlaceElem::ConstantIndex { offset, min_length: _, from_end } => { let offset: u64 = offset; let index = if !from_end { fx.bcx.ins().iconst(fx.pointer_type, offset as i64) @@ -1014,7 +917,7 @@ pub(crate) fn codegen_place<'tcx>( } pub(crate) fn codegen_operand<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, ) -> CValue<'tcx> { match operand { @@ -1026,34 +929,24 @@ pub(crate) fn codegen_operand<'tcx>( } } -pub(crate) fn codegen_panic<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - msg_str: &str, - span: Span, -) { +pub(crate) fn codegen_panic<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, msg_str: &str, span: Span) { let location = fx.get_caller_location(span).load_scalar(fx); let msg_ptr = fx.anonymous_str("assert", msg_str); - let msg_len = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); + let msg_len = fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(msg_str.len()).unwrap()); let args = [msg_ptr, msg_len, location]; codegen_panic_inner(fx, rustc_hir::LangItem::Panic, &args, span); } pub(crate) fn codegen_panic_inner<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, lang_item: rustc_hir::LangItem, args: &[Value], span: Span, ) { - let def_id = fx - .tcx - .lang_items() - .require(lang_item) - .unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s)); + let def_id = + fx.tcx.lang_items().require(lang_item).unwrap_or_else(|s| fx.tcx.sess.span_fatal(span, &s)); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let symbol_name = fx.tcx.symbol_name(instance).name; diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs index be369b07fddfe..983839d48d2d7 100644 --- a/src/bin/cg_clif.rs +++ b/src/bin/cg_clif.rs @@ -27,13 +27,7 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { config.opts.cg.panic = Some(PanicStrategy::Abort); config.opts.debugging_opts.panic_abort_tests = true; config.opts.maybe_sysroot = Some(config.opts.maybe_sysroot.clone().unwrap_or_else(|| { - std::env::current_exe() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .to_owned() + std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned() })); } } diff --git a/src/bin/cg_clif_build_sysroot.rs b/src/bin/cg_clif_build_sysroot.rs index 83e5dc6e6724d..e7cd5edbbf654 100644 --- a/src/bin/cg_clif_build_sysroot.rs +++ b/src/bin/cg_clif_build_sysroot.rs @@ -46,15 +46,8 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { config.opts.cg.panic = Some(PanicStrategy::Abort); config.opts.debugging_opts.panic_abort_tests = true; - config.opts.maybe_sysroot = Some( - std::env::current_exe() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .to_owned(), - ); + config.opts.maybe_sysroot = + Some(std::env::current_exe().unwrap().parent().unwrap().parent().unwrap().to_owned()); } } diff --git a/src/cast.rs b/src/cast.rs index 57204de1135be..74c5e09f08da0 100644 --- a/src/cast.rs +++ b/src/cast.rs @@ -3,7 +3,7 @@ use crate::prelude::*; pub(crate) fn clif_intcast( - fx: &mut FunctionCx<'_, '_, impl Module>, + fx: &mut FunctionCx<'_, '_, '_>, val: Value, to: Type, signed: bool, @@ -40,18 +40,14 @@ pub(crate) fn clif_intcast( // reduce (types::I128, _) => { let (lsb, _msb) = fx.bcx.ins().isplit(val); - if to == types::I64 { - lsb - } else { - fx.bcx.ins().ireduce(to, lsb) - } + if to == types::I64 { lsb } else { fx.bcx.ins().ireduce(to, lsb) } } (_, _) => fx.bcx.ins().ireduce(to, val), } } pub(crate) fn clif_int_or_float_cast( - fx: &mut FunctionCx<'_, '_, impl Module>, + fx: &mut FunctionCx<'_, '_, '_>, from: Value, from_signed: bool, to_ty: Type, @@ -87,11 +83,7 @@ pub(crate) fn clif_int_or_float_cast( }, ); - let from_rust_ty = if from_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; + let from_rust_ty = if from_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; let to_rust_ty = match to_ty { types::F32 => fx.tcx.types.f32, @@ -100,11 +92,7 @@ pub(crate) fn clif_int_or_float_cast( }; return fx - .easy_call( - &name, - &[CValue::by_val(from, fx.layout_of(from_rust_ty))], - to_rust_ty, - ) + .easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty) .load_scalar(fx); } @@ -138,18 +126,10 @@ pub(crate) fn clif_int_or_float_cast( _ => unreachable!(), }; - let to_rust_ty = if to_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; + let to_rust_ty = if to_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; return fx - .easy_call( - &name, - &[CValue::by_val(from, fx.layout_of(from_rust_ty))], - to_rust_ty, - ) + .easy_call(&name, &[CValue::by_val(from, fx.layout_of(from_rust_ty))], to_rust_ty) .load_scalar(fx); } diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index 866ba90e4ae4b..ae75e6508cb0b 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -5,13 +5,17 @@ use cranelift_codegen::ir::ArgumentPurpose; use crate::prelude::*; pub(crate) fn maybe_codegen<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, checked: bool, lhs: CValue<'tcx>, rhs: CValue<'tcx>, ) -> Option> { - if lhs.layout().ty != fx.tcx.types.u128 && lhs.layout().ty != fx.tcx.types.i128 { + if lhs.layout().ty != fx.tcx.types.u128 + && lhs.layout().ty != fx.tcx.types.i128 + && rhs.layout().ty != fx.tcx.types.u128 + && rhs.layout().ty != fx.tcx.types.i128 + { return None; } @@ -27,11 +31,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub if !checked => None, BinOp::Mul if !checked => { - let val_ty = if is_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; + let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } BinOp::Add | BinOp::Sub | BinOp::Mul => { @@ -43,11 +43,7 @@ pub(crate) fn maybe_codegen<'tcx>( AbiParam::new(types::I128), AbiParam::new(types::I128), ]; - let args = [ - out_place.to_ptr().get_addr(fx), - lhs.load_scalar(fx), - rhs.load_scalar(fx), - ]; + let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; let name = match (bin_op, is_signed) { (BinOp::Add, false) => "__rust_u128_addo", (BinOp::Add, true) => "__rust_i128_addo", @@ -97,70 +93,23 @@ pub(crate) fn maybe_codegen<'tcx>( None }; - // Optimize `val >> 64`, because compiler_builtins uses it to deconstruct an 128bit - // integer into its lsb and msb. - // https://github.com/rust-lang-nursery/compiler-builtins/blob/79a6a1603d5672cbb9187ff41ff4d9b5048ac1cb/src/int/mod.rs#L217 - if resolve_value_imm(fx.bcx.func, rhs_val) == Some(64) { - let (lhs_lsb, lhs_msb) = fx.bcx.ins().isplit(lhs_val); - let all_zeros = fx.bcx.ins().iconst(types::I64, 0); - let val = match (bin_op, is_signed) { - (BinOp::Shr, false) => { - let val = fx.bcx.ins().iconcat(lhs_msb, all_zeros); - Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.u128))) - } - (BinOp::Shr, true) => { - let sign = fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, lhs_msb, 0); - let all_ones = fx.bcx.ins().iconst(types::I64, u64::MAX as i64); - let all_sign_bits = fx.bcx.ins().select(sign, all_zeros, all_ones); - - let val = fx.bcx.ins().iconcat(lhs_msb, all_sign_bits); - Some(CValue::by_val(val, fx.layout_of(fx.tcx.types.i128))) - } - (BinOp::Shl, _) => { - let val_ty = if is_signed { - fx.tcx.types.i128 - } else { - fx.tcx.types.u128 - }; - let val = fx.bcx.ins().iconcat(all_zeros, lhs_lsb); - Some(CValue::by_val(val, fx.layout_of(val_ty))) - } - _ => None, - }; - if let Some(val) = val { - if let Some(is_overflow) = is_overflow { - let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); - let val = val.load_scalar(fx); - return Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty))); + let truncated_rhs = clif_intcast(fx, rhs_val, types::I32, false); + let val = match bin_op { + BinOp::Shl => fx.bcx.ins().ishl(lhs_val, truncated_rhs), + BinOp::Shr => { + if is_signed { + fx.bcx.ins().sshr(lhs_val, truncated_rhs) } else { - return Some(val); + fx.bcx.ins().ushr(lhs_val, truncated_rhs) } } - } - - let truncated_rhs = clif_intcast(fx, rhs_val, types::I32, false); - let truncated_rhs = CValue::by_val(truncated_rhs, fx.layout_of(fx.tcx.types.u32)); - let val = match (bin_op, is_signed) { - (BinOp::Shl, false) => { - fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.u128) - } - (BinOp::Shl, true) => { - fx.easy_call("__ashlti3", &[lhs, truncated_rhs], fx.tcx.types.i128) - } - (BinOp::Shr, false) => { - fx.easy_call("__lshrti3", &[lhs, truncated_rhs], fx.tcx.types.u128) - } - (BinOp::Shr, true) => { - fx.easy_call("__ashrti3", &[lhs, truncated_rhs], fx.tcx.types.i128) - } - (_, _) => unreachable!(), + _ => unreachable!(), }; if let Some(is_overflow) = is_overflow { let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); - let val = val.load_scalar(fx); Some(CValue::by_val_pair(val, is_overflow, fx.layout_of(out_ty))) } else { - Some(val) + Some(CValue::by_val(val, lhs.layout())) } } } diff --git a/src/common.rs b/src/common.rs index fbee84e09f7a6..6a4a6744a5cf7 100644 --- a/src/common.rs +++ b/src/common.rs @@ -3,8 +3,6 @@ use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Integer, Primitive}; use rustc_target::spec::{HasTargetSpec, Target}; -use cranelift_codegen::ir::{InstructionData, Opcode, ValueDef}; - use crate::prelude::*; pub(crate) fn pointer_ty(tcx: TyCtxt<'_>) -> types::Type { @@ -56,11 +54,7 @@ fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option types::F64, }, ty::FnPtr(_) => pointer_ty(tcx), - ty::RawPtr(TypeAndMut { - ty: pointee_ty, - mutbl: _, - }) - | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, pointee_ty) { return None; } else { @@ -99,11 +93,7 @@ fn clif_pair_type_from_ty<'tcx>( } (a, b) } - ty::RawPtr(TypeAndMut { - ty: pointee_ty, - mutbl: _, - }) - | ty::Ref(_, pointee_ty, _) => { + ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => { if has_ptr_meta(tcx, pointee_ty) { (pointer_ty(tcx), pointer_ty(tcx)) } else { @@ -116,15 +106,8 @@ fn clif_pair_type_from_ty<'tcx>( /// Is a pointer to this type a fat ptr? pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { - let ptr_ty = tcx.mk_ptr(TypeAndMut { - ty, - mutbl: rustc_hir::Mutability::Not, - }); - match &tcx - .layout_of(ParamEnv::reveal_all().and(ptr_ty)) - .unwrap() - .abi - { + let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc_hir::Mutability::Not }); + match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi { Abi::Scalar(_) => false, Abi::ScalarPair(_, _) => true, abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi), @@ -132,7 +115,7 @@ pub(crate) fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { } pub(crate) fn codegen_icmp_imm( - fx: &mut FunctionCx<'_, '_, impl Module>, + fx: &mut FunctionCx<'_, '_, '_>, intcc: IntCC, lhs: Value, rhs: i128, @@ -175,51 +158,6 @@ pub(crate) fn codegen_icmp_imm( } } -fn resolve_normal_value_imm(func: &Function, val: Value) -> Option { - if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) { - if let InstructionData::UnaryImm { - opcode: Opcode::Iconst, - imm, - } = func.dfg[inst] - { - Some(imm.into()) - } else { - None - } - } else { - None - } -} - -fn resolve_128bit_value_imm(func: &Function, val: Value) -> Option { - let (lsb, msb) = if let ValueDef::Result(inst, 0 /*param*/) = func.dfg.value_def(val) { - if let InstructionData::Binary { - opcode: Opcode::Iconcat, - args: [lsb, msb], - } = func.dfg[inst] - { - (lsb, msb) - } else { - return None; - } - } else { - return None; - }; - - let lsb = u128::from(resolve_normal_value_imm(func, lsb)? as u64); - let msb = u128::from(resolve_normal_value_imm(func, msb)? as u64); - - Some(msb << 64 | lsb) -} - -pub(crate) fn resolve_value_imm(func: &Function, val: Value) -> Option { - if func.dfg.value_type(val) == types::I128 { - resolve_128bit_value_imm(func, val) - } else { - resolve_normal_value_imm(func, val).map(|imm| u128::from(imm as u64)) - } -} - pub(crate) fn type_min_max_value( bcx: &mut FunctionBuilder<'_>, ty: Type, @@ -288,8 +226,8 @@ pub(crate) fn type_sign(ty: Ty<'_>) -> bool { } } -pub(crate) struct FunctionCx<'clif, 'tcx, M: Module> { - pub(crate) cx: &'clif mut crate::CodegenCx<'tcx, M>, +pub(crate) struct FunctionCx<'m, 'clif, 'tcx> { + pub(crate) cx: &'clif mut crate::CodegenCx<'m, 'tcx>, pub(crate) tcx: TyCtxt<'tcx>, pub(crate) pointer_type: Type, // Cached from module @@ -316,7 +254,7 @@ pub(crate) struct FunctionCx<'clif, 'tcx, M: Module> { pub(crate) inline_asm_index: u32, } -impl<'tcx, M: Module> LayoutOf for FunctionCx<'_, 'tcx, M> { +impl<'tcx> LayoutOf for FunctionCx<'_, '_, 'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; @@ -325,31 +263,31 @@ impl<'tcx, M: Module> LayoutOf for FunctionCx<'_, 'tcx, M> { } } -impl<'tcx, M: Module> layout::HasTyCtxt<'tcx> for FunctionCx<'_, 'tcx, M> { +impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { self.tcx } } -impl<'tcx, M: Module> rustc_target::abi::HasDataLayout for FunctionCx<'_, 'tcx, M> { +impl<'tcx> rustc_target::abi::HasDataLayout for FunctionCx<'_, '_, 'tcx> { fn data_layout(&self) -> &rustc_target::abi::TargetDataLayout { &self.tcx.data_layout } } -impl<'tcx, M: Module> layout::HasParamEnv<'tcx> for FunctionCx<'_, 'tcx, M> { +impl<'tcx> layout::HasParamEnv<'tcx> for FunctionCx<'_, '_, 'tcx> { fn param_env(&self) -> ParamEnv<'tcx> { ParamEnv::reveal_all() } } -impl<'tcx, M: Module> HasTargetSpec for FunctionCx<'_, 'tcx, M> { +impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> { fn target_spec(&self) -> &Target { &self.tcx.sess.target } } -impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { +impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn monomorphize(&self, value: T) -> T where T: TypeFoldable<'tcx> + Copy, @@ -416,12 +354,7 @@ impl<'tcx, M: Module> FunctionCx<'_, 'tcx, M> { let msg_id = self .cx .module - .declare_data( - &format!("__{}_{:08x}", prefix, msg_hash), - Linkage::Local, - false, - false, - ) + .declare_data(&format!("__{}_{:08x}", prefix, msg_hash), Linkage::Local, false, false) .unwrap(); // Ignore DuplicateDefinition error, as the data will be the same @@ -444,15 +377,13 @@ impl<'tcx> LayoutOf for RevealAllLayoutCx<'tcx> { fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> { assert!(!ty.still_further_specializable()); - self.0 - .layout_of(ParamEnv::reveal_all().and(&ty)) - .unwrap_or_else(|e| { - if let layout::LayoutError::SizeOverflow(_) = e { - self.0.sess.fatal(&e.to_string()) - } else { - bug!("failed to get layout for `{}`: {}", ty, e) - } - }) + self.0.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap_or_else(|e| { + if let layout::LayoutError::SizeOverflow(_) = e { + self.0.sess.fatal(&e.to_string()) + } else { + bug!("failed to get layout for `{}`: {}", ty, e) + } + }) } } diff --git a/src/constant.rs b/src/constant.rs index 5702832bcb67d..b0639cf9e15fe 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -28,7 +28,7 @@ enum TodoItem { } impl ConstantCx { - pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut impl Module) { + pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) { //println!("todo {:?}", self.todo); define_all_allocs(tcx, module, &mut self); //println!("done {:?}", self.done); @@ -36,21 +36,20 @@ impl ConstantCx { } } -pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) { +pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { + let mut all_constants_ok = true; for constant in &fx.mir.required_consts { let const_ = fx.monomorphize(constant.literal); match const_.val { ConstKind::Value(_) => {} ConstKind::Unevaluated(def, ref substs, promoted) => { if let Err(err) = - fx.tcx - .const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) + fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { + all_constants_ok = false; match err { ErrorHandled::Reported(ErrorReported) | ErrorHandled::Linted => { - fx.tcx - .sess - .span_err(constant.span, "erroneous constant encountered"); + fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); } ErrorHandled::TooGeneric => { span_bug!( @@ -69,6 +68,7 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) { | ConstKind::Error(_) => unreachable!("{:?}", const_), } } + all_constants_ok } pub(crate) fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) { @@ -76,11 +76,11 @@ pub(crate) fn codegen_static(constants_cx: &mut ConstantCx, def_id: DefId) { } pub(crate) fn codegen_tls_ref<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, def_id: DefId, layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { - let data_id = data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false); + let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] fx.add_comment(local_data_id, format!("tls {:?}", def_id)); @@ -89,11 +89,11 @@ pub(crate) fn codegen_tls_ref<'tcx>( } fn codegen_static_ref<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, def_id: DefId, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - let data_id = data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false); + let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] fx.add_comment(local_data_id, format!("{:?}", def_id)); @@ -110,7 +110,7 @@ fn codegen_static_ref<'tcx>( } pub(crate) fn codegen_constant<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { let const_ = fx.monomorphize(constant.literal); @@ -128,20 +128,10 @@ pub(crate) fn codegen_constant<'tcx>( .to_cvalue(fx); } ConstKind::Unevaluated(def, ref substs, promoted) => { - match fx - .tcx - .const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) - { + match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { Ok(const_val) => const_val, Err(_) => { - fx.tcx - .sess - .span_err(constant.span, "erroneous constant encountered"); - return crate::trap::trap_unreachable_ret_value( - fx, - fx.layout_of(const_.ty), - "erroneous constant encountered", - ); + span_bug!(constant.span, "erroneous constant not captured by required_consts"); } } } @@ -156,7 +146,7 @@ pub(crate) fn codegen_constant<'tcx>( } pub(crate) fn codegen_const_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, const_val: ConstValue<'tcx>, ty: Ty<'tcx>, ) -> CValue<'tcx> { @@ -172,9 +162,7 @@ pub(crate) fn codegen_const_value<'tcx>( if fx.clif_type(layout.ty).is_none() { let (size, align) = (layout.size, layout.align.pref); let mut alloc = Allocation::from_bytes( - std::iter::repeat(0) - .take(size.bytes_usize()) - .collect::>(), + std::iter::repeat(0).take(size.bytes_usize()).collect::>(), align, ); let ptr = Pointer::new(AllocId(!0), Size::ZERO); // The alloc id is never used @@ -190,11 +178,8 @@ pub(crate) fn codegen_const_value<'tcx>( let base_addr = match alloc_kind { Some(GlobalAlloc::Memory(alloc)) => { fx.cx.constants_cx.todo.push(TodoItem::Alloc(ptr.alloc_id)); - let data_id = data_id_for_alloc_id( - &mut fx.cx.module, - ptr.alloc_id, - alloc.mutability, - ); + let data_id = + data_id_for_alloc_id(fx.cx.module, ptr.alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] @@ -203,15 +188,14 @@ pub(crate) fn codegen_const_value<'tcx>( } Some(GlobalAlloc::Function(instance)) => { let func_id = - crate::abi::import_function(fx.tcx, &mut fx.cx.module, instance); + crate::abi::import_function(fx.tcx, fx.cx.module, instance); let local_func_id = fx.cx.module.declare_func_in_func(func_id, &mut fx.bcx.func); fx.bcx.ins().func_addr(fx.pointer_type, local_func_id) } Some(GlobalAlloc::Static(def_id)) => { assert!(fx.tcx.is_static(def_id)); - let data_id = - data_id_for_static(fx.tcx, &mut fx.cx.module, def_id, false); + let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] @@ -221,9 +205,7 @@ pub(crate) fn codegen_const_value<'tcx>( None => bug!("missing allocation {:?}", ptr.alloc_id), }; let val = if ptr.offset.bytes() != 0 { - fx.bcx - .ins() - .iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap()) + fx.bcx.ins().iadd_imm(base_addr, i64::try_from(ptr.offset.bytes()).unwrap()) } else { base_addr }; @@ -240,22 +222,22 @@ pub(crate) fn codegen_const_value<'tcx>( let ptr = pointer_for_allocation(fx, data) .offset_i64(fx, i64::try_from(start).unwrap()) .get_addr(fx); - let len = fx.bcx.ins().iconst( - fx.pointer_type, - i64::try_from(end.checked_sub(start).unwrap()).unwrap(), - ); + let len = fx + .bcx + .ins() + .iconst(fx.pointer_type, i64::try_from(end.checked_sub(start).unwrap()).unwrap()); CValue::by_val_pair(ptr, len, layout) } } } fn pointer_for_allocation<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, alloc: &'tcx Allocation, ) -> crate::pointer::Pointer { let alloc_id = fx.tcx.create_memory_alloc(alloc); fx.cx.constants_cx.todo.push(TodoItem::Alloc(alloc_id)); - let data_id = data_id_for_alloc_id(&mut fx.cx.module, alloc_id, alloc.mutability); + let data_id = data_id_for_alloc_id(fx.cx.module, alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); #[cfg(debug_assertions)] @@ -265,7 +247,7 @@ fn pointer_for_allocation<'tcx>( } fn data_id_for_alloc_id( - module: &mut impl Module, + module: &mut dyn Module, alloc_id: AllocId, mutability: rustc_hir::Mutability, ) -> DataId { @@ -281,7 +263,7 @@ fn data_id_for_alloc_id( fn data_id_for_static( tcx: TyCtxt<'_>, - module: &mut impl Module, + module: &mut dyn Module, def_id: DefId, definition: bool, ) -> DataId { @@ -304,12 +286,7 @@ fn data_id_for_static( } else { !ty.is_freeze(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) }; - let align = tcx - .layout_of(ParamEnv::reveal_all().and(ty)) - .unwrap() - .align - .pref - .bytes(); + let align = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap().align.pref.bytes(); let attrs = tcx.codegen_fn_attrs(def_id); @@ -332,17 +309,11 @@ fn data_id_for_static( // zero. let ref_name = format!("_rust_extern_with_linkage_{}", symbol_name); - let ref_data_id = module - .declare_data(&ref_name, Linkage::Local, false, false) - .unwrap(); + let ref_data_id = module.declare_data(&ref_name, Linkage::Local, false, false).unwrap(); let mut data_ctx = DataContext::new(); data_ctx.set_align(align); let data = module.declare_data_in_data(data_id, &mut data_ctx); - data_ctx.define( - std::iter::repeat(0) - .take(pointer_ty(tcx).bytes() as usize) - .collect(), - ); + data_ctx.define(std::iter::repeat(0).take(pointer_ty(tcx).bytes() as usize).collect()); data_ctx.write_data_addr(0, data, 0); match module.define_data(ref_data_id, &data_ctx) { // Every time the static is referenced there will be another definition of this global, @@ -356,7 +327,7 @@ fn data_id_for_static( } } -fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut ConstantCx) { +fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) { while let Some(todo_item) = cx.todo.pop() { let (data_id, alloc, section_name) = match todo_item { TodoItem::Alloc(alloc_id) => { @@ -371,10 +342,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan TodoItem::Static(def_id) => { //println!("static {:?}", def_id); - let section_name = tcx - .codegen_fn_attrs(def_id) - .link_section - .map(|s| s.as_str()); + let section_name = tcx.codegen_fn_attrs(def_id).link_section.map(|s| s.as_str()); let alloc = tcx.eval_static_initializer(def_id).unwrap(); @@ -396,9 +364,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan data_ctx.set_segment_section("", &*section_name); } - let bytes = alloc - .inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()) - .to_vec(); + let bytes = alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()).to_vec(); data_ctx.define(bytes.into_boxed_slice()); for &(offset, (_tag, reloc)) in alloc.relocations().iter() { @@ -426,10 +392,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan data_id_for_alloc_id(module, reloc, target_alloc.mutability) } GlobalAlloc::Static(def_id) => { - if tcx - .codegen_fn_attrs(def_id) - .flags - .contains(CodegenFnAttrFlags::THREAD_LOCAL) + if tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) { tcx.sess.fatal(&format!( "Allocation {:?} contains reference to TLS value {:?}", @@ -457,14 +420,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut impl Module, cx: &mut Constan } pub(crate) fn mir_operand_get_const_val<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, ) -> Option<&'tcx Const<'tcx>> { match operand { Operand::Copy(_) | Operand::Move(_) => None, - Operand::Constant(const_) => Some( - fx.monomorphize(const_.literal) - .eval(fx.tcx, ParamEnv::reveal_all()), - ), + Operand::Constant(const_) => { + Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all())) + } } } diff --git a/src/debuginfo/emit.rs b/src/debuginfo/emit.rs index 6160f9b78d8b3..6018eefcd42fb 100644 --- a/src/debuginfo/emit.rs +++ b/src/debuginfo/emit.rs @@ -14,10 +14,7 @@ impl DebugContext<'_> { let unit_range_list_id = self.dwarf.unit.ranges.add(self.unit_range_list.clone()); let root = self.dwarf.unit.root(); let root = self.dwarf.unit.get_mut(root); - root.set( - gimli::DW_AT_ranges, - AttributeValue::RangeListRef(unit_range_list_id), - ); + root.set(gimli::DW_AT_ranges, AttributeValue::RangeListRef(unit_range_list_id)); let mut sections = Sections::new(WriterRelocate::new(self.endian)); self.dwarf.write(&mut sections).unwrap(); @@ -66,10 +63,7 @@ pub(super) struct WriterRelocate { impl WriterRelocate { pub(super) fn new(endian: RunTimeEndian) -> Self { - WriterRelocate { - relocs: Vec::new(), - writer: EndianVec::new(endian), - } + WriterRelocate { relocs: Vec::new(), writer: EndianVec::new(endian) } } /// Perform the collected relocations to be usable for JIT usage. @@ -85,9 +79,7 @@ impl WriterRelocate { cranelift_module::FuncId::from_u32(sym.try_into().unwrap()), ); let val = (addr as u64 as i64 + reloc.addend) as u64; - self.writer - .write_udata_at(reloc.offset as usize, val, reloc.size) - .unwrap(); + self.writer.write_udata_at(reloc.offset as usize, val, reloc.size).unwrap(); } } } diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index d226755d85de0..30ed356c7627f 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -53,11 +53,7 @@ pub(crate) fn make_file_info(hash: SourceFileHash) -> Option { if hash.kind == SourceFileHashAlgorithm::Md5 { let mut buf = [0u8; MD5_LEN]; buf.copy_from_slice(hash.hash_bytes()); - Some(FileInfo { - timestamp: 0, - size: 0, - md5: buf, - }) + Some(FileInfo { timestamp: 0, size: 0, md5: buf }) } else { None } @@ -112,24 +108,14 @@ impl<'tcx> DebugContext<'tcx> { let entry = self.dwarf.unit.get_mut(entry_id); - entry.set( - gimli::DW_AT_decl_file, - AttributeValue::FileIndex(Some(file_id)), - ); - entry.set( - gimli::DW_AT_decl_line, - AttributeValue::Udata(loc.line as u64), - ); + entry.set(gimli::DW_AT_decl_file, AttributeValue::FileIndex(Some(file_id))); + entry.set(gimli::DW_AT_decl_line, AttributeValue::Udata(loc.line as u64)); // FIXME: probably omit this - entry.set( - gimli::DW_AT_decl_column, - AttributeValue::Udata(loc.col.to_usize() as u64), - ); + entry.set(gimli::DW_AT_decl_column, AttributeValue::Udata(loc.col.to_usize() as u64)); } pub(super) fn create_debug_lines( &mut self, - isa: &dyn cranelift_codegen::isa::TargetIsa, symbol: usize, entry_id: UnitEntryId, context: &Context, @@ -138,7 +124,6 @@ impl<'tcx> DebugContext<'tcx> { ) -> CodeOffset { let tcx = self.tcx; let line_program = &mut self.dwarf.unit.line_program; - let func = &context.func; let line_strings = &mut self.dwarf.line_strings; let mut last_span = None; @@ -202,43 +187,22 @@ impl<'tcx> DebugContext<'tcx> { let mut func_end = 0; - if let Some(ref mcr) = &context.mach_compile_result { - for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() { - line_program.row().address_offset = u64::from(start); - if !loc.is_default() { - let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap(); - create_row_for_span(line_program, source_info.span); - } else { - create_row_for_span(line_program, function_span); - } - func_end = end; - } - - line_program.end_sequence(u64::from(func_end)); - - func_end = mcr.buffer.total_size(); - } else { - let encinfo = isa.encoding_info(); - let mut blocks = func.layout.blocks().collect::>(); - blocks.sort_by_key(|block| func.offsets[*block]); // Ensure inst offsets always increase - - for block in blocks { - for (offset, inst, size) in func.inst_offsets(block, &encinfo) { - let srcloc = func.srclocs[inst]; - line_program.row().address_offset = u64::from(offset); - if !srcloc.is_default() { - let source_info = - *source_info_set.get_index(srcloc.bits() as usize).unwrap(); - create_row_for_span(line_program, source_info.span); - } else { - create_row_for_span(line_program, function_span); - } - func_end = offset + size; - } + let mcr = context.mach_compile_result.as_ref().unwrap(); + for &MachSrcLoc { start, end, loc } in mcr.buffer.get_srclocs_sorted() { + line_program.row().address_offset = u64::from(start); + if !loc.is_default() { + let source_info = *source_info_set.get_index(loc.bits() as usize).unwrap(); + create_row_for_span(line_program, source_info.span); + } else { + create_row_for_span(line_program, function_span); } - line_program.end_sequence(u64::from(func_end)); + func_end = end; } + line_program.end_sequence(u64::from(func_end)); + + let func_end = mcr.buffer.total_size(); + assert_ne!(func_end, 0); let entry = self.dwarf.unit.get_mut(entry_id); @@ -246,10 +210,7 @@ impl<'tcx> DebugContext<'tcx> { gimli::DW_AT_low_pc, AttributeValue::Address(Address::Symbol { symbol, addend: 0 }), ); - entry.set( - gimli::DW_AT_high_pc, - AttributeValue::Udata(u64::from(func_end)), - ); + entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(func_end))); self.emit_location(entry_id, function_span); diff --git a/src/debuginfo/mod.rs b/src/debuginfo/mod.rs index a6f4ded41b64b..dc8bc8d9cb741 100644 --- a/src/debuginfo/mod.rs +++ b/src/debuginfo/mod.rs @@ -9,7 +9,7 @@ use crate::prelude::*; use rustc_index::vec::IndexVec; use cranelift_codegen::entity::EntityRef; -use cranelift_codegen::ir::{StackSlots, ValueLabel, ValueLoc}; +use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc}; use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::ValueLocRange; @@ -39,7 +39,6 @@ pub(crate) struct DebugContext<'tcx> { dwarf: DwarfUnit, unit_range_list: RangeList, - clif_types: FxHashMap, types: FxHashMap, UnitEntryId>, } @@ -91,20 +90,11 @@ impl<'tcx> DebugContext<'tcx> { let root = dwarf.unit.root(); let root = dwarf.unit.get_mut(root); - root.set( - gimli::DW_AT_producer, - AttributeValue::StringRef(dwarf.strings.add(producer)), - ); - root.set( - gimli::DW_AT_language, - AttributeValue::Language(gimli::DW_LANG_Rust), - ); + root.set(gimli::DW_AT_producer, AttributeValue::StringRef(dwarf.strings.add(producer))); + root.set(gimli::DW_AT_language, AttributeValue::Language(gimli::DW_LANG_Rust)); root.set(gimli::DW_AT_name, AttributeValue::StringRef(name)); root.set(gimli::DW_AT_comp_dir, AttributeValue::StringRef(comp_dir)); - root.set( - gimli::DW_AT_low_pc, - AttributeValue::Address(Address::Constant(0)), - ); + root.set(gimli::DW_AT_low_pc, AttributeValue::Address(Address::Constant(0))); } DebugContext { @@ -115,48 +105,10 @@ impl<'tcx> DebugContext<'tcx> { dwarf, unit_range_list: RangeList(Vec::new()), - clif_types: FxHashMap::default(), types: FxHashMap::default(), } } - fn dwarf_ty_for_clif_ty(&mut self, ty: Type) -> UnitEntryId { - if let Some(type_id) = self.clif_types.get(&ty) { - return *type_id; - } - - let new_entry = |dwarf: &mut DwarfUnit, tag| dwarf.unit.add(dwarf.unit.root(), tag); - - let primitive = |dwarf: &mut DwarfUnit, ate| { - let type_id = new_entry(dwarf, gimli::DW_TAG_base_type); - let type_entry = dwarf.unit.get_mut(type_id); - type_entry.set(gimli::DW_AT_encoding, AttributeValue::Encoding(ate)); - type_id - }; - - let type_id = if ty.is_bool() { - primitive(&mut self.dwarf, gimli::DW_ATE_boolean) - } else if ty.is_int() { - primitive(&mut self.dwarf, gimli::DW_ATE_address) - } else if ty.is_float() { - primitive(&mut self.dwarf, gimli::DW_ATE_float) - } else { - new_entry(&mut self.dwarf, gimli::DW_TAG_structure_type) - }; - - let type_entry = self.dwarf.unit.get_mut(type_id); - type_entry.set( - gimli::DW_AT_name, - AttributeValue::String(format!("{}", ty).replace('i', "u").into_bytes()), - ); - type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(u64::from(ty.bytes())), - ); - - type_id - } - fn dwarf_ty(&mut self, ty: Ty<'tcx>) -> UnitEntryId { if let Some(type_id) = self.types.get(ty) { return *type_id; @@ -181,10 +133,7 @@ impl<'tcx> DebugContext<'tcx> { ty::Int(_) => primitive(&mut self.dwarf, gimli::DW_ATE_signed), ty::Float(_) => primitive(&mut self.dwarf, gimli::DW_ATE_float), ty::Ref(_, pointee_ty, _mutbl) - | ty::RawPtr(ty::TypeAndMut { - ty: pointee_ty, - mutbl: _mutbl, - }) => { + | ty::RawPtr(ty::TypeAndMut { ty: pointee_ty, mutbl: _mutbl }) => { let type_id = new_entry(&mut self.dwarf, gimli::DW_TAG_pointer_type); // Ensure that type is inserted before recursing to avoid duplicates @@ -211,10 +160,7 @@ impl<'tcx> DebugContext<'tcx> { let field_offset = layout.fields.offset(field_idx); let field_layout = layout .field( - &layout::LayoutCx { - tcx: self.tcx, - param_env: ParamEnv::reveal_all(), - }, + &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() }, field_idx, ) .unwrap(); @@ -243,10 +189,7 @@ impl<'tcx> DebugContext<'tcx> { let type_entry = self.dwarf.unit.get_mut(type_id); type_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes())); - type_entry.set( - gimli::DW_AT_byte_size, - AttributeValue::Udata(layout.size.bytes()), - ); + type_entry.set(gimli::DW_AT_byte_size, AttributeValue::Udata(layout.size.bytes())); self.types.insert(ty, type_id); @@ -286,23 +229,15 @@ impl<'tcx> DebugContext<'tcx> { let name_id = self.dwarf.strings.add(name); // Gdb requires DW_AT_name. Otherwise the DW_TAG_subprogram is skipped. entry.set(gimli::DW_AT_name, AttributeValue::StringRef(name_id)); - entry.set( - gimli::DW_AT_linkage_name, - AttributeValue::StringRef(name_id), - ); + entry.set(gimli::DW_AT_linkage_name, AttributeValue::StringRef(name_id)); - let end = - self.create_debug_lines(isa, symbol, entry_id, context, mir.span, source_info_set); + let end = self.create_debug_lines(symbol, entry_id, context, mir.span, source_info_set); self.unit_range_list.0.push(Range::StartLength { begin: Address::Symbol { symbol, addend: 0 }, length: u64::from(end), }); - if isa.get_mach_backend().is_some() { - return; // Not yet implemented for the AArch64 backend. - } - let func_entry = self.dwarf.unit.get_mut(entry_id); // Gdb requires both DW_AT_low_pc and DW_AT_high_pc. Otherwise the DW_TAG_subprogram is skipped. func_entry.set( @@ -312,51 +247,6 @@ impl<'tcx> DebugContext<'tcx> { // Using Udata for DW_AT_high_pc requires at least DWARF4 func_entry.set(gimli::DW_AT_high_pc, AttributeValue::Udata(u64::from(end))); - // FIXME Remove once actual debuginfo for locals works. - for (i, (param, &val)) in context - .func - .signature - .params - .iter() - .zip( - context - .func - .dfg - .block_params(context.func.layout.entry_block().unwrap()), - ) - .enumerate() - { - use cranelift_codegen::ir::ArgumentPurpose; - let base_name = match param.purpose { - ArgumentPurpose::Normal => "arg", - ArgumentPurpose::StructArgument(_) => "struct_arg", - ArgumentPurpose::StructReturn => "sret", - ArgumentPurpose::Link - | ArgumentPurpose::FramePointer - | ArgumentPurpose::CalleeSaved => continue, - ArgumentPurpose::VMContext - | ArgumentPurpose::SignatureId - | ArgumentPurpose::CallerTLS - | ArgumentPurpose::CalleeTLS - | ArgumentPurpose::StackLimit => unreachable!(), - }; - let name = format!("{}{}", base_name, i); - - let dw_ty = self.dwarf_ty_for_clif_ty(param.value_type); - let loc = - translate_loc(isa, context.func.locations[val], &context.func.stack_slots).unwrap(); - - let arg_id = self - .dwarf - .unit - .add(entry_id, gimli::DW_TAG_formal_parameter); - let var_entry = self.dwarf.unit.get_mut(arg_id); - - var_entry.set(gimli::DW_AT_name, AttributeValue::String(name.into_bytes())); - var_entry.set(gimli::DW_AT_type, AttributeValue::UnitRef(dw_ty)); - var_entry.set(gimli::DW_AT_location, AttributeValue::Exprloc(loc)); - } - // FIXME make it more reliable and implement scopes before re-enabling this. if false { let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap(); @@ -376,10 +266,7 @@ impl<'tcx> DebugContext<'tcx> { context, &local_map, &value_labels_ranges, - Place { - local, - projection: ty::List::empty(), - }, + Place { local, projection: ty::List::empty() }, ); let var_entry = self.dwarf.unit.get_mut(var_id); @@ -417,10 +304,7 @@ fn place_location<'tcx>( symbol, addend: i64::from(value_loc_range.start), }, - end: Address::Symbol { - symbol, - addend: i64::from(value_loc_range.end), - }, + end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) }, data: translate_loc( isa, value_loc_range.loc, @@ -463,17 +347,17 @@ fn place_location<'tcx>( // Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137 fn translate_loc( isa: &dyn TargetIsa, - loc: ValueLoc, + loc: LabelValueLoc, stack_slots: &StackSlots, ) -> Option { match loc { - ValueLoc::Reg(reg) => { + LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => { let machine_reg = isa.map_dwarf_register(reg).unwrap(); let mut expr = Expression::new(); expr.op_reg(gimli::Register(machine_reg)); Some(expr) } - ValueLoc::Stack(ss) => { + LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => { if let Some(ss_offset) = stack_slots[ss].offset { let mut expr = Expression::new(); expr.op_breg(X86_64::RBP, i64::from(ss_offset) + 16); @@ -482,6 +366,17 @@ fn translate_loc( None } } - _ => None, + LabelValueLoc::ValueLoc(ValueLoc::Unassigned) => unreachable!(), + LabelValueLoc::Reg(reg) => { + let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap(); + let mut expr = Expression::new(); + expr.op_reg(gimli::Register(machine_reg)); + Some(expr) + } + LabelValueLoc::SPOffset(offset) => { + let mut expr = Expression::new(); + expr.op_breg(X86_64::RSP, offset); + Some(expr) + } } } diff --git a/src/debuginfo/unwind.rs b/src/debuginfo/unwind.rs index 49de927cdba05..357c9fe6ed83a 100644 --- a/src/debuginfo/unwind.rs +++ b/src/debuginfo/unwind.rs @@ -28,11 +28,7 @@ impl<'tcx> UnwindContext<'tcx> { None }; - UnwindContext { - tcx, - frame_table, - cie_id, - } + UnwindContext { tcx, frame_table, cie_id } } pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) { @@ -46,10 +42,8 @@ impl<'tcx> UnwindContext<'tcx> { UnwindInfo::SystemV(unwind_info) => { self.frame_table.add_fde( self.cie_id.unwrap(), - unwind_info.to_fde(Address::Symbol { - symbol: func_id.as_u32() as usize, - addend: 0, - }), + unwind_info + .to_fde(Address::Symbol { symbol: func_id.as_u32() as usize, addend: 0 }), ); } UnwindInfo::WindowsX64(_) => { @@ -60,9 +54,8 @@ impl<'tcx> UnwindContext<'tcx> { } pub(crate) fn emit(self, product: &mut P) { - let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian( - self.tcx, - ))); + let mut eh_frame = + EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx))); self.frame_table.write_eh_frame(&mut eh_frame).unwrap(); if !eh_frame.0.writer.slice().is_empty() { @@ -82,9 +75,8 @@ impl<'tcx> UnwindContext<'tcx> { self, jit_module: &cranelift_jit::JITModule, ) -> Option { - let mut eh_frame = EhFrame::from(super::emit::WriterRelocate::new(super::target_endian( - self.tcx, - ))); + let mut eh_frame = + EhFrame::from(super::emit::WriterRelocate::new(super::target_endian(self.tcx))); self.frame_table.write_eh_frame(&mut eh_frame).unwrap(); if eh_frame.0.writer.slice().is_empty() { @@ -130,10 +122,7 @@ impl<'tcx> UnwindContext<'tcx> { registrations.push(ptr as usize); } - Some(UnwindRegistry { - _frame_table: eh_frame, - registrations, - }) + Some(UnwindRegistry { _frame_table: eh_frame, registrations }) } } diff --git a/src/discriminant.rs b/src/discriminant.rs index ad635016a9136..3326f87f00075 100644 --- a/src/discriminant.rs +++ b/src/discriminant.rs @@ -7,7 +7,7 @@ use rustc_target::abi::{Int, TagEncoding, Variants}; use crate::prelude::*; pub(crate) fn codegen_set_discriminant<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>, variant_index: VariantIdx, ) { @@ -26,11 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( variants: _, } => { let ptr = place.place_field(fx, mir::Field::new(tag_field)); - let to = layout - .ty - .discriminant_for_variant(fx.tcx, variant_index) - .unwrap() - .val; + let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; let to = if ptr.layout().abi.is_signed() { ty::ScalarInt::try_from_int( ptr.layout().size.sign_extend(to) as i128, @@ -46,12 +42,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( Variants::Multiple { tag: _, tag_field, - tag_encoding: - TagEncoding::Niche { - dataful_variant, - ref niche_variants, - niche_start, - }, + tag_encoding: TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start }, variants: _, } => { if variant_index != dataful_variant { @@ -70,7 +61,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( } pub(crate) fn codegen_get_discriminant<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, value: CValue<'tcx>, dest_layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { @@ -101,12 +92,9 @@ pub(crate) fn codegen_get_discriminant<'tcx>( }; return CValue::const_val(fx, dest_layout, discr_val); } - Variants::Multiple { - tag, - tag_field, - tag_encoding, - variants: _, - } => (tag, *tag_field, tag_encoding), + Variants::Multiple { tag, tag_field, tag_encoding, variants: _ } => { + (tag, *tag_field, tag_encoding) + } }; let cast_to = fx.clif_type(dest_layout.ty).unwrap(); @@ -125,11 +113,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( let val = clif_intcast(fx, tag, cast_to, signed); CValue::by_val(val, dest_layout) } - TagEncoding::Niche { - dataful_variant, - ref niche_variants, - niche_start, - } => { + TagEncoding::Niche { dataful_variant, ref niche_variants, niche_start } => { // Rebase from niche values to discriminants, and check // whether the result is in range for the niche variants. @@ -146,9 +130,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( tag } else { // FIXME handle niche_start > i64::MAX - fx.bcx - .ins() - .iadd_imm(tag, -i64::try_from(niche_start).unwrap()) + fx.bcx.ins().iadd_imm(tag, -i64::try_from(niche_start).unwrap()) }; let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32(); let is_niche = { @@ -176,15 +158,10 @@ pub(crate) fn codegen_get_discriminant<'tcx>( } else { clif_intcast(fx, relative_discr, cast_to, false) }; - fx.bcx - .ins() - .iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32())) + fx.bcx.ins().iadd_imm(relative_discr, i64::from(niche_variants.start().as_u32())) }; - let dataful_variant = fx - .bcx - .ins() - .iconst(cast_to, i64::from(dataful_variant.as_u32())); + let dataful_variant = fx.bcx.ins().iconst(cast_to, i64::from(dataful_variant.as_u32())); let discr = fx.bcx.ins().select(is_niche, niche_discr, dataful_variant); CValue::by_val(discr, dest_layout) } diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 39781e2482a6a..b87dcc41928b6 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -12,11 +12,9 @@ use rustc_middle::mir::mono::{CodegenUnit, MonoItem}; use rustc_session::cgu_reuse_tracker::CguReuse; use rustc_session::config::{DebugInfo, OutputType}; -use cranelift_object::{ObjectModule, ObjectProduct}; +use cranelift_object::ObjectModule; -use crate::prelude::*; - -use crate::backend::AddConstructor; +use crate::{prelude::*, BackendConfig}; fn new_module(tcx: TyCtxt<'_>, name: String) -> ObjectModule { let module = crate::backend::make_module(tcx.sess, name); @@ -39,7 +37,6 @@ fn emit_module( module: ObjectModule, debug: Option>, unwind_context: UnwindContext<'_>, - map_product: impl FnOnce(ObjectProduct) -> ObjectProduct, ) -> ModuleCodegenResult { let mut product = module.finish(); @@ -49,15 +46,10 @@ fn emit_module( unwind_context.emit(&mut product); - let product = map_product(product); - - let tmp_file = tcx - .output_filenames(LOCAL_CRATE) - .temp_path(OutputType::Object, Some(&name)); + let tmp_file = tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(&name)); let obj = product.object.write().unwrap(); if let Err(err) = std::fs::write(&tmp_file, obj) { - tcx.sess - .fatal(&format!("error writing object file: {}", err)); + tcx.sess.fatal(&format!("error writing object file: {}", err)); } let work_product = if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() { @@ -71,13 +63,7 @@ fn emit_module( }; ModuleCodegenResult( - CompiledModule { - name, - kind, - object: Some(tmp_file), - dwarf_object: None, - bytecode: None, - }, + CompiledModule { name, kind, object: Some(tmp_file), dwarf_object: None, bytecode: None }, work_product, ) } @@ -117,49 +103,27 @@ fn reuse_workproduct_for_cgu( } } -fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodegenResult { +fn module_codegen( + tcx: TyCtxt<'_>, + (backend_config, cgu_name): (BackendConfig, rustc_span::Symbol), +) -> ModuleCodegenResult { let cgu = tcx.codegen_unit(cgu_name); let mono_items = cgu.items_in_deterministic_order(tcx); let mut module = new_module(tcx, cgu_name.as_str().to_string()); - // Initialize the global atomic mutex using a constructor for proc-macros. - // FIXME implement atomic instructions in Cranelift. - let mut init_atomics_mutex_from_constructor = None; - if tcx - .sess - .crate_types() - .contains(&rustc_session::config::CrateType::ProcMacro) - { - if mono_items.iter().any(|(mono_item, _)| match mono_item { - rustc_middle::mir::mono::MonoItem::Static(def_id) => tcx - .symbol_name(Instance::mono(tcx, *def_id)) - .name - .contains("__rustc_proc_macro_decls_"), - _ => false, - }) { - init_atomics_mutex_from_constructor = - Some(crate::atomic_shim::init_global_lock_constructor( - &mut module, - &format!("{}_init_atomics_mutex", cgu_name.as_str()), - )); - } - } - let mut cx = crate::CodegenCx::new( tcx, - module, + backend_config, + &mut module, tcx.sess.opts.debuginfo != DebugInfo::None, - true, ); super::predefine_mono_items(&mut cx, &mono_items); for (mono_item, (linkage, visibility)) in mono_items { let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); match mono_item { MonoItem::Fn(inst) => { - cx.tcx.sess.time("codegen fn", || { - crate::base::codegen_fn(&mut cx, inst, linkage) - }); + cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); } MonoItem::Static(def_id) => { crate::constant::codegen_static(&mut cx.constants_cx, def_id) @@ -175,9 +139,9 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege } } } - let (mut module, global_asm, debug, mut unwind_context) = + let (global_asm, debug, mut unwind_context) = tcx.sess.time("finalize CodegenCx", || cx.finalize()); - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context, false); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut module, &mut unwind_context); let codegen_result = emit_module( tcx, @@ -186,13 +150,6 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege module, debug, unwind_context, - |mut product| { - if let Some(func_id) = init_atomics_mutex_from_constructor { - product.add_constructor(func_id); - } - - product - }, ); codegen_global_asm(tcx, &cgu.name().as_str(), &global_asm); @@ -202,6 +159,7 @@ fn module_codegen(tcx: TyCtxt<'_>, cgu_name: rustc_span::Symbol) -> ModuleCodege pub(super) fn run_aot( tcx: TyCtxt<'_>, + backend_config: BackendConfig, metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box<(CodegenResults, FxHashMap)> { @@ -225,9 +183,7 @@ pub(super) fn run_aot( cgus.iter() .map(|cgu| { let cgu_reuse = determine_cgu_reuse(tcx, cgu); - tcx.sess - .cgu_reuse_tracker - .set_actual_reuse(&cgu.name().as_str(), cgu_reuse); + tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse); match cgu_reuse { _ if std::env::var("CG_CLIF_INCR_CACHE_DISABLED").is_ok() => {} @@ -242,7 +198,7 @@ pub(super) fn run_aot( let (ModuleCodegenResult(module, work_product), _) = tcx.dep_graph.with_task( dep_node, tcx, - cgu.name(), + (backend_config, cgu.name()), module_codegen, rustc_middle::dep_graph::hash_result, ); @@ -271,7 +227,6 @@ pub(super) fn run_aot( allocator_module, None, allocator_unwind_context, - |product| product, ); if let Some((id, product)) = work_product { work_products.insert(id, product); @@ -301,8 +256,7 @@ pub(super) fn run_aot( }); if let Err(err) = std::fs::write(&tmp_file, obj) { - tcx.sess - .fatal(&format!("error writing metadata object file: {}", err)); + tcx.sess.fatal(&format!("error writing metadata object file: {}", err)); } (metadata_cgu_name, tmp_file) @@ -356,8 +310,7 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) { "asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift", ); } else { - tcx.sess - .fatal("asm! and global_asm! are not yet supported on macOS and Windows"); + tcx.sess.fatal("asm! and global_asm! are not yet supported on macOS and Windows"); } } @@ -367,19 +320,12 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) { // Remove all LLVM style comments let global_asm = global_asm .lines() - .map(|line| { - if let Some(index) = line.find("//") { - &line[0..index] - } else { - line - } - }) + .map(|line| if let Some(index) = line.find("//") { &line[0..index] } else { line }) .collect::>() .join("\n"); - let output_object_file = tcx - .output_filenames(LOCAL_CRATE) - .temp_path(OutputType::Object, Some(cgu_name)); + let output_object_file = + tcx.output_filenames(LOCAL_CRATE).temp_path(OutputType::Object, Some(cgu_name)); // Assemble `global_asm` let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm"); @@ -389,16 +335,10 @@ fn codegen_global_asm(tcx: TyCtxt<'_>, cgu_name: &str, global_asm: &str) { .stdin(Stdio::piped()) .spawn() .expect("Failed to spawn `as`."); - child - .stdin - .take() - .unwrap() - .write_all(global_asm.as_bytes()) - .unwrap(); + child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap(); let status = child.wait().expect("Failed to wait for `as`."); if !status.success() { - tcx.sess - .fatal(&format!("Failed to assemble `{}`", global_asm)); + tcx.sess.fatal(&format!("Failed to assemble `{}`", global_asm)); } // Link the global asm and main object file together @@ -442,11 +382,7 @@ fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) -> CguR } let work_product_id = &cgu.work_product_id(); - if tcx - .dep_graph - .previous_work_product(work_product_id) - .is_none() - { + if tcx.dep_graph.previous_work_product(work_product_id).is_none() { // We don't have anything cached for this CGU. This can happen // if the CGU did not exist in the previous session. return CguReuse::No; diff --git a/src/driver/jit.rs b/src/driver/jit.rs index f784d8d27cc74..245df03ffb84d 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -10,43 +10,24 @@ use rustc_middle::mir::mono::MonoItem; use cranelift_jit::{JITBuilder, JITModule}; -use crate::prelude::*; +use crate::{prelude::*, BackendConfig}; use crate::{CodegenCx, CodegenMode}; thread_local! { + pub static BACKEND_CONFIG: RefCell> = RefCell::new(None); pub static CURRENT_MODULE: RefCell> = RefCell::new(None); } -pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { +pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { if !tcx.sess.opts.output_types.should_codegen() { tcx.sess.fatal("JIT mode doesn't work with `cargo check`."); } - #[cfg(unix)] - unsafe { - // When not using our custom driver rustc will open us without the RTLD_GLOBAL flag, so - // __cg_clif_global_atomic_mutex will not be exported. We fix this by opening ourself again - // as global. - // FIXME remove once atomic_shim is gone - - let mut dl_info: libc::Dl_info = std::mem::zeroed(); - assert_ne!( - libc::dladdr(run_jit as *const libc::c_void, &mut dl_info), - 0 - ); - assert_ne!( - libc::dlopen(dl_info.dli_fname, libc::RTLD_NOW | libc::RTLD_GLOBAL), - std::ptr::null_mut(), - ); - } - let imported_symbols = load_imported_symbols_for_jit(tcx); - let mut jit_builder = JITBuilder::with_isa( - crate::build_isa(tcx.sess), - cranelift_module::default_libcall_names(), - ); - jit_builder.hotswap(matches!(codegen_mode, CodegenMode::JitLazy)); + let mut jit_builder = + JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names()); + jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy)); jit_builder.symbols(imported_symbols); let mut jit_module = JITModule::new(jit_builder); assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); @@ -56,14 +37,10 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { AbiParam::new(jit_module.target_config().pointer_type()), AbiParam::new(jit_module.target_config().pointer_type()), ], - returns: vec![AbiParam::new( - jit_module.target_config().pointer_type(), /*isize*/ - )], + returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)], call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), }; - let main_func_id = jit_module - .declare_function("main", Linkage::Import, &sig) - .unwrap(); + let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap(); let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); let mono_items = cgus @@ -74,19 +51,19 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { .into_iter() .collect::>(); - let mut cx = crate::CodegenCx::new(tcx, jit_module, false, false); + let mut cx = crate::CodegenCx::new(tcx, backend_config, &mut jit_module, false); super::time(tcx, "codegen mono items", || { super::predefine_mono_items(&mut cx, &mono_items); for (mono_item, (linkage, visibility)) in mono_items { let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); match mono_item { - MonoItem::Fn(inst) => match codegen_mode { + MonoItem::Fn(inst) => match backend_config.codegen_mode { CodegenMode::Aot => unreachable!(), CodegenMode::Jit => { - cx.tcx.sess.time("codegen fn", || { - crate::base::codegen_fn(&mut cx, inst, linkage) - }); + cx.tcx + .sess + .time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); } CodegenMode::JitLazy => codegen_shim(&mut cx, inst), }, @@ -101,7 +78,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { } }); - let (mut jit_module, global_asm, _debug, mut unwind_context) = + let (global_asm, _debug, mut unwind_context) = tcx.sess.time("finalize CodegenCx", || cx.finalize()); jit_module.finalize_definitions(); @@ -109,7 +86,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { tcx.sess.fatal("Inline asm is not supported in JIT mode"); } - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context, true); + crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context); crate::allocator::codegen(tcx, &mut jit_module, &mut unwind_context); tcx.sess.abort_if_errors(); @@ -120,7 +97,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); - println!("Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed"); + println!( + "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" + ); let f: extern "C" fn(c_int, *const *const c_char) -> c_int = unsafe { ::std::mem::transmute(finalized_main) }; @@ -136,6 +115,9 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, codegen_mode: CodegenMode) -> ! { // useful as some dynamic linkers use it as a marker to jump over. argv.push(std::ptr::null()); + BACKEND_CONFIG.with(|tls_backend_config| { + assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none()) + }); CURRENT_MODULE .with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none())); @@ -153,21 +135,19 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 CURRENT_MODULE.with(|jit_module| { let mut jit_module = jit_module.borrow_mut(); let jit_module = jit_module.as_mut().unwrap(); - let mut cx = crate::CodegenCx::new(tcx, jit_module, false, false); + let backend_config = + BACKEND_CONFIG.with(|backend_config| backend_config.borrow().clone().unwrap()); let name = tcx.symbol_name(instance).name.to_string(); - let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), instance); - let func_id = cx - .module - .declare_function(&name, Linkage::Export, &sig) - .unwrap(); - cx.module.prepare_for_function_redefine(func_id).unwrap(); - - tcx.sess.time("codegen fn", || { - crate::base::codegen_fn(&mut cx, instance, Linkage::Export) - }); - - let (jit_module, global_asm, _debug_context, unwind_context) = cx.finalize(); + let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance); + let func_id = jit_module.declare_function(&name, Linkage::Export, &sig).unwrap(); + jit_module.prepare_for_function_redefine(func_id).unwrap(); + + let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false); + tcx.sess + .time("codegen fn", || crate::base::codegen_fn(&mut cx, instance, Linkage::Export)); + + let (global_asm, _debug_context, unwind_context) = cx.finalize(); assert!(global_asm.is_empty()); jit_module.finalize_definitions(); std::mem::forget(unsafe { unwind_context.register_jit(&jit_module) }); @@ -194,9 +174,8 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { Linkage::NotLinked | Linkage::IncludedFromDylib => {} Linkage::Static => { let name = tcx.crate_name(cnum); - let mut err = tcx - .sess - .struct_err(&format!("Can't load static lib {}", name.as_str())); + let mut err = + tcx.sess.struct_err(&format!("Can't load static lib {}", name.as_str())); err.note("rustc_codegen_cranelift can only load dylibs in JIT mode."); err.emit(); } @@ -217,6 +196,11 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { 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); @@ -236,17 +220,14 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { imported_symbols } -pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx, impl Module>, inst: Instance<'tcx>) { +pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { let tcx = cx.tcx; let pointer_type = cx.module.target_config().pointer_type(); let name = tcx.symbol_name(inst).name.to_string(); let sig = crate::abi::get_function_sig(tcx, cx.module.isa().triple(), inst); - let func_id = cx - .module - .declare_function(&name, Linkage::Export, &sig) - .unwrap(); + let func_id = cx.module.declare_function(&name, Linkage::Export, &sig).unwrap(); let instance_ptr = Box::into_raw(Box::new(inst)); @@ -267,28 +248,18 @@ pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'tcx, impl Module>, inst: In let mut builder_ctx = FunctionBuilderContext::new(); let mut trampoline_builder = FunctionBuilder::new(&mut trampoline, &mut builder_ctx); - let jit_fn = cx - .module - .declare_func_in_func(jit_fn, trampoline_builder.func); + let jit_fn = cx.module.declare_func_in_func(jit_fn, trampoline_builder.func); let sig_ref = trampoline_builder.func.import_signature(sig); let entry_block = trampoline_builder.create_block(); trampoline_builder.append_block_params_for_function_params(entry_block); - let fn_args = trampoline_builder - .func - .dfg - .block_params(entry_block) - .to_vec(); + let fn_args = trampoline_builder.func.dfg.block_params(entry_block).to_vec(); trampoline_builder.switch_to_block(entry_block); - let instance_ptr = trampoline_builder - .ins() - .iconst(pointer_type, instance_ptr as u64 as i64); + let instance_ptr = trampoline_builder.ins().iconst(pointer_type, instance_ptr as u64 as i64); let jitted_fn = trampoline_builder.ins().call(jit_fn, &[instance_ptr]); let jitted_fn = trampoline_builder.func.dfg.inst_results(jitted_fn)[0]; - let call_inst = trampoline_builder - .ins() - .call_indirect(sig_ref, jitted_fn, &fn_args); + let call_inst = trampoline_builder.ins().call_indirect(sig_ref, jitted_fn, &fn_args); let ret_vals = trampoline_builder.func.dfg.inst_results(call_inst).to_vec(); trampoline_builder.ins().return_(&ret_vals); diff --git a/src/driver/mod.rs b/src/driver/mod.rs index 2497f9dfdfbcf..b994f28ffef5b 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -17,33 +17,30 @@ pub(crate) fn codegen_crate( tcx: TyCtxt<'_>, metadata: EncodedMetadata, need_metadata_module: bool, - config: crate::BackendConfig, + backend_config: crate::BackendConfig, ) -> Box { tcx.sess.abort_if_errors(); - match config.codegen_mode { - CodegenMode::Aot => aot::run_aot(tcx, metadata, need_metadata_module), + match backend_config.codegen_mode { + CodegenMode::Aot => aot::run_aot(tcx, backend_config, metadata, need_metadata_module), CodegenMode::Jit | CodegenMode::JitLazy => { - let is_executable = tcx - .sess - .crate_types() - .contains(&rustc_session::config::CrateType::Executable); + let is_executable = + tcx.sess.crate_types().contains(&rustc_session::config::CrateType::Executable); if !is_executable { tcx.sess.fatal("can't jit non-executable crate"); } #[cfg(feature = "jit")] - let _: ! = jit::run_jit(tcx, config.codegen_mode); + let _: ! = jit::run_jit(tcx, backend_config); #[cfg(not(feature = "jit"))] - tcx.sess - .fatal("jit support was disabled when compiling rustc_codegen_cranelift"); + tcx.sess.fatal("jit support was disabled when compiling rustc_codegen_cranelift"); } } } fn predefine_mono_items<'tcx>( - cx: &mut crate::CodegenCx<'tcx, impl Module>, + cx: &mut crate::CodegenCx<'_, 'tcx>, mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))], ) { cx.tcx.sess.time("predefine functions", || { @@ -63,21 +60,12 @@ fn predefine_mono_items<'tcx>( } fn time(tcx: TyCtxt<'_>, name: &'static str, f: impl FnOnce() -> R) -> R { - if std::env::var("CG_CLIF_DISPLAY_CG_TIME") - .as_ref() - .map(|val| &**val) - == Ok("1") - { + if std::env::var("CG_CLIF_DISPLAY_CG_TIME").as_ref().map(|val| &**val) == Ok("1") { println!("[{:<30}: {}] start", tcx.crate_name(LOCAL_CRATE), name); let before = std::time::Instant::now(); let res = tcx.sess.time(name, f); let after = std::time::Instant::now(); - println!( - "[{:<30}: {}] end time: {:?}", - tcx.crate_name(LOCAL_CRATE), - name, - after - before - ); + println!("[{:<30}: {}] end time: {:?}", tcx.crate_name(LOCAL_CRATE), name, after - before); res } else { tcx.sess.time(name, f) diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 04aac780125d9..5b3df2bd38280 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::InlineAsmOperand; use rustc_target::asm::*; pub(crate) fn codegen_inline_asm<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, _span: Span, template: &[InlineAsmTemplatePiece], operands: &[InlineAsmOperand<'tcx>], @@ -53,11 +53,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( crate::base::codegen_operand(fx, value).load_scalar(fx), )); } - InlineAsmOperand::Out { - reg, - late: _, - place, - } => { + InlineAsmOperand::Out { reg, late: _, place } => { let reg = expect_reg(reg); clobbered_regs.push((reg, new_slot(reg.reg_class()))); if let Some(place) = place { @@ -68,12 +64,7 @@ pub(crate) fn codegen_inline_asm<'tcx>( )); } } - InlineAsmOperand::InOut { - reg, - late: _, - ref in_value, - out_place, - } => { + InlineAsmOperand::InOut { reg, late: _, ref in_value, out_place } => { let reg = expect_reg(reg); clobbered_regs.push((reg, new_slot(reg.reg_class()))); inputs.push(( @@ -97,11 +88,8 @@ pub(crate) fn codegen_inline_asm<'tcx>( let inline_asm_index = fx.inline_asm_index; fx.inline_asm_index += 1; - let asm_name = format!( - "{}__inline_asm_{}", - fx.tcx.symbol_name(fx.instance).name, - inline_asm_index - ); + let asm_name = + format!("{}__inline_asm_{}", fx.tcx.symbol_name(fx.instance).name, inline_asm_index); let generated_asm = generate_asm_wrapper( &asm_name, @@ -129,12 +117,7 @@ fn generate_asm_wrapper( let mut generated_asm = String::new(); writeln!(generated_asm, ".globl {}", asm_name).unwrap(); writeln!(generated_asm, ".type {},@function", asm_name).unwrap(); - writeln!( - generated_asm, - ".section .text.{},\"ax\",@progbits", - asm_name - ) - .unwrap(); + writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap(); writeln!(generated_asm, "{}:", asm_name).unwrap(); generated_asm.push_str(".intel_syntax noprefix\n"); @@ -164,11 +147,7 @@ fn generate_asm_wrapper( InlineAsmTemplatePiece::String(s) => { generated_asm.push_str(s); } - InlineAsmTemplatePiece::Placeholder { - operand_idx: _, - modifier: _, - span: _, - } => todo!(), + InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span: _ } => todo!(), } } generated_asm.push('\n'); @@ -203,7 +182,7 @@ fn generate_asm_wrapper( } fn call_inline_asm<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, asm_name: &str, slot_size: Size, inputs: Vec<(InlineAsmReg, Size, Value)>, @@ -230,17 +209,12 @@ fn call_inline_asm<'tcx>( }, ) .unwrap(); - let inline_asm_func = fx - .cx - .module - .declare_func_in_func(inline_asm_func, &mut fx.bcx.func); + let inline_asm_func = fx.cx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func); #[cfg(debug_assertions)] fx.add_comment(inline_asm_func, asm_name); for (_reg, offset, value) in inputs { - fx.bcx - .ins() - .stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap()); + fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap()); } let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0); @@ -248,10 +222,7 @@ fn call_inline_asm<'tcx>( for (_reg, offset, place) in outputs { let ty = fx.clif_type(place.layout().ty).unwrap(); - let value = fx - .bcx - .ins() - .stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap()); + let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap()); place.write_cvalue(fx, CValue::by_val(value, place.layout())); } } @@ -267,8 +238,7 @@ fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsm match arch { InlineAsmArch::X86_64 => { write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap(); - reg.emit(generated_asm, InlineAsmArch::X86_64, None) - .unwrap(); + reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap(); generated_asm.push('\n'); } _ => unimplemented!("save_register for {:?}", arch), @@ -284,8 +254,7 @@ fn restore_register( match arch { InlineAsmArch::X86_64 => { generated_asm.push_str(" mov "); - reg.emit(generated_asm, InlineAsmArch::X86_64, None) - .unwrap(); + reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap(); writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap(); } _ => unimplemented!("restore_register for {:?}", arch), diff --git a/src/intrinsics/cpuid.rs b/src/intrinsics/cpuid.rs index c1a1cdbe4eb7d..b27b0eddfbad6 100644 --- a/src/intrinsics/cpuid.rs +++ b/src/intrinsics/cpuid.rs @@ -6,7 +6,7 @@ use crate::prelude::*; /// /// This emulates an intel cpu with sse and sse2 support, but which doesn't support anything else. pub(crate) fn codegen_cpuid_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, leaf: Value, _subleaf: Value, ) -> (Value, Value, Value, Value) { @@ -31,54 +31,28 @@ pub(crate) fn codegen_cpuid_call<'tcx>( fx.bcx.switch_to_block(leaf_0); let max_basic_leaf = fx.bcx.ins().iconst(types::I32, 1); - let vend0 = fx - .bcx - .ins() - .iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu"))); - let vend2 = fx - .bcx - .ins() - .iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI"))); - let vend1 = fx - .bcx - .ins() - .iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel"))); - fx.bcx - .ins() - .jump(dest, &[max_basic_leaf, vend0, vend1, vend2]); + let vend0 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"Genu"))); + let vend2 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ineI"))); + let vend1 = fx.bcx.ins().iconst(types::I32, i64::from(u32::from_le_bytes(*b"ntel"))); + fx.bcx.ins().jump(dest, &[max_basic_leaf, vend0, vend1, vend2]); fx.bcx.switch_to_block(leaf_1); let cpu_signature = fx.bcx.ins().iconst(types::I32, 0); let additional_information = fx.bcx.ins().iconst(types::I32, 0); let ecx_features = fx.bcx.ins().iconst(types::I32, 0); - let edx_features = fx - .bcx - .ins() - .iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */); - fx.bcx.ins().jump( - dest, - &[ - cpu_signature, - additional_information, - ecx_features, - edx_features, - ], - ); + let edx_features = fx.bcx.ins().iconst(types::I32, 1 << 25 /* sse */ | 1 << 26 /* sse2 */); + fx.bcx.ins().jump(dest, &[cpu_signature, additional_information, ecx_features, edx_features]); fx.bcx.switch_to_block(leaf_8000_0000); let extended_max_basic_leaf = fx.bcx.ins().iconst(types::I32, 0); let zero = fx.bcx.ins().iconst(types::I32, 0); - fx.bcx - .ins() - .jump(dest, &[extended_max_basic_leaf, zero, zero, zero]); + fx.bcx.ins().jump(dest, &[extended_max_basic_leaf, zero, zero, zero]); fx.bcx.switch_to_block(leaf_8000_0001); let zero = fx.bcx.ins().iconst(types::I32, 0); let proc_info_ecx = fx.bcx.ins().iconst(types::I32, 0); let proc_info_edx = fx.bcx.ins().iconst(types::I32, 0); - fx.bcx - .ins() - .jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]); + fx.bcx.ins().jump(dest, &[zero, zero, proc_info_ecx, proc_info_edx]); fx.bcx.switch_to_block(unsupported_leaf); crate::trap::trap_unreachable( diff --git a/src/intrinsics/llvm.rs b/src/intrinsics/llvm.rs index d58e4d4995842..0692da397eb94 100644 --- a/src/intrinsics/llvm.rs +++ b/src/intrinsics/llvm.rs @@ -6,7 +6,7 @@ use crate::prelude::*; use rustc_middle::ty::subst::SubstsRef; pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, intrinsic: &str, substs: SubstsRef<'tcx>, args: &[mir::Operand<'tcx>], diff --git a/src/intrinsics/mod.rs b/src/intrinsics/mod.rs index 8946ac43bc65a..39e047a98f9eb 100644 --- a/src/intrinsics/mod.rs +++ b/src/intrinsics/mod.rs @@ -9,6 +9,7 @@ pub(crate) use cpuid::codegen_cpuid_call; pub(crate) use llvm::codegen_llvm_intrinsic_call; use crate::prelude::*; +use cranelift_codegen::ir::AtomicRmwOp; use rustc_middle::ty::print::with_no_trimmed_paths; macro intrinsic_pat { @@ -112,38 +113,6 @@ macro call_intrinsic_match { } } -macro atomic_binop_return_old($fx:expr, $op:ident<$T:ident>($ptr:ident, $src:ident) -> $ret:ident) { - crate::atomic_shim::lock_global_lock($fx); - - let clif_ty = $fx.clif_type($T).unwrap(); - let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0); - let new = $fx.bcx.ins().$op(old, $src); - $fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0); - $ret.write_cvalue($fx, CValue::by_val(old, $fx.layout_of($T))); - - crate::atomic_shim::unlock_global_lock($fx); -} - -macro atomic_minmax($fx:expr, $cc:expr, <$T:ident> ($ptr:ident, $src:ident) -> $ret:ident) { - crate::atomic_shim::lock_global_lock($fx); - - // Read old - let clif_ty = $fx.clif_type($T).unwrap(); - let old = $fx.bcx.ins().load(clif_ty, MemFlags::new(), $ptr, 0); - - // Compare - let is_eq = $fx.bcx.ins().icmp(IntCC::SignedGreaterThan, old, $src); - let new = $fx.bcx.ins().select(is_eq, old, $src); - - // Write new - $fx.bcx.ins().store(MemFlags::new(), new, $ptr, 0); - - let ret_val = CValue::by_val(old, $ret.layout()); - $ret.write_cvalue($fx, ret_val); - - crate::atomic_shim::unlock_global_lock($fx); -} - macro validate_atomic_type($fx:ident, $intrinsic:ident, $span:ident, $ty:expr) { match $ty.kind() { ty::Uint(_) | ty::Int(_) | ty::RawPtr(..) => {} @@ -184,12 +153,12 @@ pub(crate) fn clif_vector_type<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx } } -fn simd_for_each_lane<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_for_each_lane<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, val: CValue<'tcx>, ret: CPlace<'tcx>, f: impl Fn( - &mut FunctionCx<'_, 'tcx, M>, + &mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, TyAndLayout<'tcx>, Value, @@ -213,13 +182,13 @@ fn simd_for_each_lane<'tcx, M: Module>( } } -fn simd_pair_for_each_lane<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_pair_for_each_lane<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, x: CValue<'tcx>, y: CValue<'tcx>, ret: CPlace<'tcx>, f: impl Fn( - &mut FunctionCx<'_, 'tcx, M>, + &mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, TyAndLayout<'tcx>, Value, @@ -246,11 +215,11 @@ fn simd_pair_for_each_lane<'tcx, M: Module>( } } -fn simd_reduce<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_reduce<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, val: CValue<'tcx>, ret: CPlace<'tcx>, - f: impl Fn(&mut FunctionCx<'_, 'tcx, M>, TyAndLayout<'tcx>, Value, Value) -> Value, + f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, TyAndLayout<'tcx>, Value, Value) -> Value, ) { let (lane_count, lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx); let lane_layout = fx.layout_of(lane_ty); @@ -258,20 +227,19 @@ fn simd_reduce<'tcx, M: Module>( let mut res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx); for lane_idx in 1..lane_count { - let lane = val - .value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())) - .load_scalar(fx); + let lane = + val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx); res_val = f(fx, lane_layout, res_val, lane); } let res = CValue::by_val(res_val, lane_layout); ret.write_cvalue(fx, res); } -fn simd_reduce_bool<'tcx, M: Module>( - fx: &mut FunctionCx<'_, 'tcx, M>, +fn simd_reduce_bool<'tcx>( + fx: &mut FunctionCx<'_, '_, 'tcx>, val: CValue<'tcx>, ret: CPlace<'tcx>, - f: impl Fn(&mut FunctionCx<'_, 'tcx, M>, Value, Value) -> Value, + f: impl Fn(&mut FunctionCx<'_, '_, 'tcx>, Value, Value) -> Value, ) { let (lane_count, _lane_ty) = val.layout().ty.simd_size_and_type(fx.tcx); assert!(ret.layout().ty.is_bool()); @@ -279,9 +247,8 @@ fn simd_reduce_bool<'tcx, M: Module>( let res_val = val.value_field(fx, mir::Field::new(0)).load_scalar(fx); let mut res_val = fx.bcx.ins().band_imm(res_val, 1); // mask to boolean for lane_idx in 1..lane_count { - let lane = val - .value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())) - .load_scalar(fx); + let lane = + val.value_field(fx, mir::Field::new(lane_idx.try_into().unwrap())).load_scalar(fx); let lane = fx.bcx.ins().band_imm(lane, 1); // mask to boolean res_val = f(fx, res_val, lane); } @@ -290,7 +257,7 @@ fn simd_reduce_bool<'tcx, M: Module>( } fn bool_to_zero_or_max_uint<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, val: Value, ) -> CValue<'tcx> { @@ -424,7 +391,7 @@ macro simd_flt_binop($fx:expr, $op:ident($x:ident, $y:ident) -> $ret:ident) { } pub(crate) fn codegen_intrinsic_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, instance: Instance<'tcx>, args: &[mir::Operand<'tcx>], destination: Option<(CPlace<'tcx>, BasicBlock)>, @@ -912,136 +879,175 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( }; _ if intrinsic.starts_with("atomic_fence"), () { - crate::atomic_shim::lock_global_lock(fx); - crate::atomic_shim::unlock_global_lock(fx); + fx.bcx.ins().fence(); }; _ if intrinsic.starts_with("atomic_singlethreadfence"), () { - crate::atomic_shim::lock_global_lock(fx); - crate::atomic_shim::unlock_global_lock(fx); + // FIXME use a compiler fence once Cranelift supports it + fx.bcx.ins().fence(); }; - _ if intrinsic.starts_with("atomic_load"), (c ptr) { - crate::atomic_shim::lock_global_lock(fx); + _ if intrinsic.starts_with("atomic_load"), (v ptr) { + validate_atomic_type!(fx, intrinsic, span, T); + let ty = fx.clif_type(T).unwrap(); - let inner_layout = - fx.layout_of(ptr.layout().ty.builtin_deref(true).unwrap().ty); - validate_atomic_type!(fx, intrinsic, span, inner_layout.ty); - let val = CValue::by_ref(Pointer::new(ptr.load_scalar(fx)), inner_layout); - ret.write_cvalue(fx, val); + let val = fx.bcx.ins().atomic_load(ty, MemFlags::trusted(), ptr); - crate::atomic_shim::unlock_global_lock(fx); + let val = CValue::by_val(val, fx.layout_of(T)); + ret.write_cvalue(fx, val); }; _ if intrinsic.starts_with("atomic_store"), (v ptr, c val) { validate_atomic_type!(fx, intrinsic, span, val.layout().ty); - crate::atomic_shim::lock_global_lock(fx); - - let dest = CPlace::for_ptr(Pointer::new(ptr), val.layout()); - dest.write_cvalue(fx, val); + let val = val.load_scalar(fx); - crate::atomic_shim::unlock_global_lock(fx); + fx.bcx.ins().atomic_store(MemFlags::trusted(), val, ptr); }; - _ if intrinsic.starts_with("atomic_xchg"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, T); - - crate::atomic_shim::lock_global_lock(fx); + _ if intrinsic.starts_with("atomic_xchg"), (v ptr, c new) { + let layout = new.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); - // Read old - let clif_ty = fx.clif_type(T).unwrap(); - let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0); - ret.write_cvalue(fx, CValue::by_val(old, fx.layout_of(T))); + let new = new.load_scalar(fx); - // Write new - let dest = CPlace::for_ptr(Pointer::new(ptr), src.layout()); - dest.write_cvalue(fx, src); + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xchg, ptr, new); - crate::atomic_shim::unlock_global_lock(fx); + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_cxchg"), (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_* - validate_atomic_type!(fx, intrinsic, span, T); + _ if intrinsic.starts_with("atomic_cxchg"), (v ptr, c test_old, c new) { // both atomic_cxchg_* and atomic_cxchgweak_* + let layout = new.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); let test_old = test_old.load_scalar(fx); let new = new.load_scalar(fx); - crate::atomic_shim::lock_global_lock(fx); - - // Read old - let clif_ty = fx.clif_type(T).unwrap(); - let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0); - - // Compare + let old = fx.bcx.ins().atomic_cas(MemFlags::trusted(), ptr, test_old, new); let is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old); - let new = fx.bcx.ins().select(is_eq, new, old); // Keep old if not equal to test_old - - // Write new - fx.bcx.ins().store(MemFlags::new(), new, ptr, 0); let ret_val = CValue::by_val_pair(old, fx.bcx.ins().bint(types::I8, is_eq), ret.layout()); - ret.write_cvalue(fx, ret_val); - - crate::atomic_shim::unlock_global_lock(fx); + ret.write_cvalue(fx, ret_val) }; - _ if intrinsic.starts_with("atomic_xadd"), (v ptr, c amount) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_xadd"), (v ptr, c amount) { + let layout = amount.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let amount = amount.load_scalar(fx); - atomic_binop_return_old! (fx, iadd(ptr, amount) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Add, ptr, amount); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_xsub"), (v ptr, c amount) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_xsub"), (v ptr, c amount) { + let layout = amount.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let amount = amount.load_scalar(fx); - atomic_binop_return_old! (fx, isub(ptr, amount) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Sub, ptr, amount); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_and"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_and"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_binop_return_old! (fx, band(ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::And, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_nand"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, T); + _ if intrinsic.starts_with("atomic_or"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); let src = src.load_scalar(fx); - crate::atomic_shim::lock_global_lock(fx); - - let clif_ty = fx.clif_type(T).unwrap(); - let old = fx.bcx.ins().load(clif_ty, MemFlags::new(), ptr, 0); - let and = fx.bcx.ins().band(old, src); - let new = fx.bcx.ins().bnot(and); - fx.bcx.ins().store(MemFlags::new(), new, ptr, 0); - ret.write_cvalue(fx, CValue::by_val(old, fx.layout_of(T))); + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Or, ptr, src); - crate::atomic_shim::unlock_global_lock(fx); + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_or"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_xor"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_binop_return_old! (fx, bor(ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Xor, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_xor"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + + // FIXME https://github.com/bytecodealliance/wasmtime/issues/2647 + _ if intrinsic.starts_with("atomic_nand"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_binop_return_old! (fx, bxor(ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Nand, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; + _ if intrinsic.starts_with("atomic_max"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); - _ if intrinsic.starts_with("atomic_max"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::SignedGreaterThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Smax, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_umax"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_umax"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::UnsignedGreaterThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Umax, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_min"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_min"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::SignedLessThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Smin, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; - _ if intrinsic.starts_with("atomic_umin"), (v ptr, c src) { - validate_atomic_type!(fx, intrinsic, span, ret.layout().ty); + _ if intrinsic.starts_with("atomic_umin"), (v ptr, c src) { + let layout = src.layout(); + validate_atomic_type!(fx, intrinsic, span, layout.ty); + let ty = fx.clif_type(layout.ty).unwrap(); + let src = src.load_scalar(fx); - atomic_minmax!(fx, IntCC::UnsignedLessThan, (ptr, src) -> ret); + + let old = fx.bcx.ins().atomic_rmw(ty, MemFlags::trusted(), AtomicRmwOp::Umin, ptr, src); + + let old = CValue::by_val(old, layout); + ret.write_cvalue(fx, old); }; minnumf32, (v a, v b) { diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index e0eb5c59590ff..1f8eeb1e71491 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -4,7 +4,7 @@ use super::*; use crate::prelude::*; pub(super) fn codegen_simd_intrinsic_call<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, instance: Instance<'tcx>, args: &[mir::Operand<'tcx>], ret: CPlace<'tcx>, diff --git a/src/lib.rs b/src/lib.rs index 1480ab2513378..e1927ad3a6920 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,8 +11,6 @@ #![warn(unused_lifetimes)] #![warn(unreachable_pub)] -#[cfg(feature = "jit")] -extern crate libc; extern crate snap; #[macro_use] extern crate rustc_middle; @@ -53,7 +51,6 @@ mod abi; mod allocator; mod analyze; mod archive; -mod atomic_shim; mod backend; mod base; mod cast; @@ -129,9 +126,9 @@ impl String> Drop for PrintOnPanic { } } -struct CodegenCx<'tcx, M: Module> { +struct CodegenCx<'m, 'tcx: 'm> { tcx: TyCtxt<'tcx>, - module: M, + module: &'m mut dyn Module, global_asm: String, constants_cx: ConstantCx, cached_context: Context, @@ -140,14 +137,20 @@ struct CodegenCx<'tcx, M: Module> { unwind_context: UnwindContext<'tcx>, } -impl<'tcx, M: Module> CodegenCx<'tcx, M> { - fn new(tcx: TyCtxt<'tcx>, module: M, debug_info: bool, pic_eh_frame: bool) -> Self { - let unwind_context = UnwindContext::new(tcx, module.isa(), pic_eh_frame); - let debug_context = if debug_info { - Some(DebugContext::new(tcx, module.isa())) - } else { - None - }; +impl<'m, 'tcx> CodegenCx<'m, 'tcx> { + fn new( + tcx: TyCtxt<'tcx>, + backend_config: BackendConfig, + module: &'m mut dyn Module, + debug_info: bool, + ) -> Self { + let unwind_context = UnwindContext::new( + tcx, + module.isa(), + matches!(backend_config.codegen_mode, CodegenMode::Aot), + ); + let debug_context = + if debug_info { Some(DebugContext::new(tcx, module.isa())) } else { None }; CodegenCx { tcx, module, @@ -160,14 +163,9 @@ impl<'tcx, M: Module> CodegenCx<'tcx, M> { } } - fn finalize(mut self) -> (M, String, Option>, UnwindContext<'tcx>) { - self.constants_cx.finalize(self.tcx, &mut self.module); - ( - self.module, - self.global_asm, - self.debug_context, - self.unwind_context, - ) + fn finalize(self) -> (String, Option>, UnwindContext<'tcx>) { + self.constants_cx.finalize(self.tcx, self.module); + (self.global_asm, self.debug_context, self.unwind_context) } } @@ -302,14 +300,7 @@ fn build_isa(sess: &Session) -> Box { flags_builder.enable("is_pic").unwrap(); flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided flags_builder - .set( - "enable_verifier", - if cfg!(debug_assertions) { - "true" - } else { - "false" - }, - ) + .set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" }) .unwrap(); let tls_model = match target_triple.binary_format { @@ -338,11 +329,7 @@ fn build_isa(sess: &Session) -> Box { let flags = settings::Flags::new(flags_builder); - let variant = if cfg!(feature = "oldbe") { - cranelift_codegen::isa::BackendVariant::Legacy - } else { - cranelift_codegen::isa::BackendVariant::MachInst - }; + let variant = cranelift_codegen::isa::BackendVariant::MachInst; let mut isa_builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap(); // Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt` // is interpreted as `bsr`. diff --git a/src/main_shim.rs b/src/main_shim.rs index b193cea877dad..62e551b186ff7 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -9,7 +9,6 @@ pub(crate) fn maybe_create_entry_wrapper( tcx: TyCtxt<'_>, module: &mut impl Module, unwind_context: &mut UnwindContext<'_>, - use_jit: bool, ) { let (main_def_id, use_start_lang_item) = match tcx.entry_fn(LOCAL_CRATE) { Some((def_id, entry_ty)) => ( @@ -27,14 +26,7 @@ pub(crate) fn maybe_create_entry_wrapper( return; } - create_entry_fn( - tcx, - module, - unwind_context, - main_def_id, - use_start_lang_item, - use_jit, - ); + create_entry_fn(tcx, module, unwind_context, main_def_id, use_start_lang_item); fn create_entry_fn( tcx: TyCtxt<'_>, @@ -42,7 +34,6 @@ pub(crate) fn maybe_create_entry_wrapper( unwind_context: &mut UnwindContext<'_>, rust_main_def_id: DefId, use_start_lang_item: bool, - use_jit: bool, ) { let main_ret_ty = tcx.fn_sig(rust_main_def_id).output(); // Given that `main()` has no arguments, @@ -57,23 +48,17 @@ pub(crate) fn maybe_create_entry_wrapper( AbiParam::new(m.target_config().pointer_type()), AbiParam::new(m.target_config().pointer_type()), ], - returns: vec![AbiParam::new( - m.target_config().pointer_type(), /*isize*/ - )], + returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)], call_conv: CallConv::triple_default(m.isa().triple()), }; - let cmain_func_id = m - .declare_function("main", Linkage::Export, &cmain_sig) - .unwrap(); + let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap(); let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx); let main_name = tcx.symbol_name(instance).name.to_string(); let main_sig = get_function_sig(tcx, m.isa().triple(), instance); - 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(); ctx.func = Function::with_name_signature(ExternalName::user(0, 0), cmain_sig); @@ -86,8 +71,6 @@ pub(crate) fn maybe_create_entry_wrapper( let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type()); let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type()); - crate::atomic_shim::init_global_lock(m, &mut bcx, use_jit); - let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func); let call_inst = if use_start_lang_item { @@ -103,9 +86,7 @@ pub(crate) fn maybe_create_entry_wrapper( .polymorphize(tcx); let start_func_id = import_function(tcx, m, start_instance); - let main_val = bcx - .ins() - .func_addr(m.target_config().pointer_type(), main_func_ref); + let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref); let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func); bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv]) diff --git a/src/metadata.rs b/src/metadata.rs index 2e3b9fb8364e4..190c4f45ccafd 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -94,9 +94,7 @@ pub(crate) fn write_metadata( assert!(kind == MetadataKind::Compressed); let mut compressed = tcx.metadata_encoding_version(); - FrameEncoder::new(&mut compressed) - .write_all(&metadata.raw_data) - .unwrap(); + FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap(); product.add_rustc_section( rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx), diff --git a/src/num.rs b/src/num.rs index d1d2b3b872a4b..da49e1c6c91db 100644 --- a/src/num.rs +++ b/src/num.rs @@ -41,7 +41,7 @@ pub(crate) fn bin_op_to_intcc(bin_op: BinOp, signed: bool) -> Option { } fn codegen_compare_bin_op<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, signed: bool, lhs: Value, @@ -54,7 +54,7 @@ fn codegen_compare_bin_op<'tcx>( } pub(crate) fn codegen_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -93,17 +93,12 @@ pub(crate) fn codegen_binop<'tcx>( ty::Uint(_) | ty::Int(_) => crate::num::codegen_int_binop(fx, bin_op, in_lhs, in_rhs), ty::Float(_) => crate::num::codegen_float_binop(fx, bin_op, in_lhs, in_rhs), ty::RawPtr(..) | ty::FnPtr(..) => crate::num::codegen_ptr_binop(fx, bin_op, in_lhs, in_rhs), - _ => unreachable!( - "{:?}({:?}, {:?})", - bin_op, - in_lhs.layout().ty, - in_rhs.layout().ty - ), + _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty), } } pub(crate) fn codegen_bool_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -124,7 +119,7 @@ pub(crate) fn codegen_bool_binop<'tcx>( } pub(crate) fn codegen_int_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -185,19 +180,14 @@ pub(crate) fn codegen_int_binop<'tcx>( } } // Compare binops handles by `codegen_binop`. - _ => unreachable!( - "{:?}({:?}, {:?})", - bin_op, - in_lhs.layout().ty, - in_rhs.layout().ty - ), + _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs.layout().ty, in_rhs.layout().ty), }; CValue::by_val(val, in_lhs.layout()) } pub(crate) fn codegen_checked_int_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -268,9 +258,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( let rhs = fx.bcx.ins().sextend(ty.double_width().unwrap(), rhs); let val = fx.bcx.ins().imul(lhs, rhs); let has_underflow = - fx.bcx - .ins() - .icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1))); + fx.bcx.ins().icmp_imm(IntCC::SignedLessThan, val, -(1 << (ty.bits() - 1))); let has_overflow = fx.bcx.ins().icmp_imm( IntCC::SignedGreaterThan, val, @@ -309,10 +297,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( let val = fx.bcx.ins().ishl(lhs, actual_shift); let ty = fx.bcx.func.dfg.value_type(val); 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) } BinOp::Shr => { @@ -326,38 +311,20 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( }; let ty = fx.bcx.func.dfg.value_type(val); 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) } - _ => bug!( - "binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", - bin_op, - in_lhs, - in_rhs - ), + _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; let has_overflow = fx.bcx.ins().bint(types::I8, has_overflow); - // FIXME directly write to result place instead - let out_place = CPlace::new_stack_slot( - fx, - fx.layout_of( - fx.tcx - .mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()), - ), - ); - let out_layout = out_place.layout(); - out_place.write_cvalue(fx, CValue::by_val_pair(res, has_overflow, out_layout)); - - out_place.to_cvalue(fx) + let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter())); + CValue::by_val_pair(res, has_overflow, out_layout) } pub(crate) fn codegen_float_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -402,7 +369,7 @@ pub(crate) fn codegen_float_binop<'tcx>( } pub(crate) fn codegen_ptr_binop<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, bin_op: BinOp, in_lhs: CValue<'tcx>, in_rhs: CValue<'tcx>, @@ -452,9 +419,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>( let ptr_eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_ptr, rhs_ptr); let ptr_cmp = - fx.bcx - .ins() - .icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr); + fx.bcx.ins().icmp(bin_op_to_intcc(bin_op, false).unwrap(), lhs_ptr, rhs_ptr); let extra_cmp = fx.bcx.ins().icmp( bin_op_to_intcc(bin_op, false).unwrap(), lhs_extra, @@ -466,9 +431,6 @@ pub(crate) fn codegen_ptr_binop<'tcx>( _ => panic!("bin_op {:?} on ptr", bin_op), }; - CValue::by_val( - fx.bcx.ins().bint(types::I8, res), - fx.layout_of(fx.tcx.types.bool), - ) + CValue::by_val(fx.bcx.ins().bint(types::I8, res), fx.layout_of(fx.tcx.types.bool)) } } diff --git a/src/optimize/code_layout.rs b/src/optimize/code_layout.rs index f02732014d1e3..ca9ff15ec10ff 100644 --- a/src/optimize/code_layout.rs +++ b/src/optimize/code_layout.rs @@ -15,10 +15,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet>(); for &inst in &insts { ctx.func.layout.remove_inst(inst); @@ -28,10 +25,7 @@ pub(super) fn optimize_function(ctx: &mut Context, cold_blocks: &EntitySet( if tcx.sess.opts.optimize == rustc_session::config::OptLevel::No { return; // FIXME classify optimizations over opt levels } - self::stack2reg::optimize_function(ctx, clif_comments); + + // FIXME(#1142) stack2reg miscompiles lewton + if false { + self::stack2reg::optimize_function(ctx, clif_comments); + } + crate::pretty_clif::write_clif_file(tcx, "stack2reg", None, instance, &ctx, &*clif_comments); crate::base::verify_func(tcx, &*clif_comments, &ctx.func); } diff --git a/src/optimize/peephole.rs b/src/optimize/peephole.rs index a575ed8dc35f8..b95e2d72877d9 100644 --- a/src/optimize/peephole.rs +++ b/src/optimize/peephole.rs @@ -10,10 +10,7 @@ use cranelift_frontend::FunctionBuilder; pub(crate) fn maybe_unwrap_bint(bcx: &mut FunctionBuilder<'_>, arg: Value) -> Value { if let ValueDef::Result(arg_inst, 0) = bcx.func.dfg.value_def(arg) { match bcx.func.dfg[arg_inst] { - InstructionData::Unary { - opcode: Opcode::Bint, - arg, - } => arg, + InstructionData::Unary { opcode: Opcode::Bint, arg } => arg, _ => arg, } } else { @@ -54,12 +51,7 @@ pub(crate) fn make_branchable_value(bcx: &mut FunctionBuilder<'_>, arg: Value) - match bcx.func.dfg[arg_inst] { // This is the lowering of Rvalue::Not - InstructionData::Load { - opcode: Opcode::Load, - arg: ptr, - flags, - offset, - } => { + InstructionData::Load { opcode: Opcode::Load, arg: ptr, flags, offset } => { // Using `load.i8 + uextend.i32` would legalize to `uload8 + ireduce.i8 + // uextend.i32`. Just `uload8` is much faster. match bcx.func.dfg.ctrl_typevar(arg_inst) { @@ -95,20 +87,14 @@ pub(crate) fn maybe_known_branch_taken( }; match bcx.func.dfg[arg_inst] { - InstructionData::UnaryBool { - opcode: Opcode::Bconst, - imm, - } => { + InstructionData::UnaryBool { opcode: Opcode::Bconst, imm } => { if test_zero { Some(!imm) } else { Some(imm) } } - InstructionData::UnaryImm { - opcode: Opcode::Iconst, - imm, - } => { + InstructionData::UnaryImm { opcode: Opcode::Iconst, imm } => { if test_zero { Some(imm.bits() == 0) } else { diff --git a/src/optimize/stack2reg.rs b/src/optimize/stack2reg.rs index 3c939d5a58639..d111f37f5e455 100644 --- a/src/optimize/stack2reg.rs +++ b/src/optimize/stack2reg.rs @@ -175,16 +175,14 @@ impl<'a> OptimizeContext<'a> { } } - OptimizeContext { - ctx, - stack_slot_usage_map, - } + OptimizeContext { ctx, stack_slot_usage_map } } } pub(super) fn optimize_function( ctx: &mut Context, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] clif_comments: &mut crate::pretty_clif::CommentWriter, + #[cfg_attr(not(debug_assertions), allow(unused_variables))] + clif_comments: &mut crate::pretty_clif::CommentWriter, ) { combine_stack_addr_with_load_store(&mut ctx.func); @@ -296,12 +294,7 @@ fn combine_stack_addr_with_load_store(func: &mut Function) { while let Some(_block) = cursor.next_block() { while let Some(inst) = cursor.next_inst() { match cursor.func.dfg[inst] { - InstructionData::Load { - opcode: Opcode::Load, - arg: addr, - flags: _, - offset, - } => { + InstructionData::Load { opcode: Opcode::Load, arg: addr, flags: _, offset } => { if cursor.func.dfg.ctrl_typevar(inst) == types::I128 || cursor.func.dfg.ctrl_typevar(inst).is_vector() { @@ -391,20 +384,14 @@ fn remove_unused_stack_addr_and_stack_load(opt_ctx: &mut OptimizeContext<'_>) { stack_slot_users .stack_addr .drain_filter(|inst| { - stack_addr_load_insts_users - .get(inst) - .map(|users| users.is_empty()) - .unwrap_or(true) + stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true) }) .for_each(|inst| StackSlotUsage::remove_unused_stack_addr(&mut func, inst)); stack_slot_users .stack_load .drain_filter(|inst| { - stack_addr_load_insts_users - .get(inst) - .map(|users| users.is_empty()) - .unwrap_or(true) + stack_addr_load_insts_users.get(inst).map(|users| users.is_empty()).unwrap_or(true) }) .for_each(|inst| StackSlotUsage::remove_unused_load(&mut func, inst)); } @@ -415,11 +402,8 @@ fn try_get_stack_slot_and_offset_for_addr( addr: Value, ) -> Option<(StackSlot, Offset32)> { if let ValueDef::Result(addr_inst, 0) = func.dfg.value_def(addr) { - if let InstructionData::StackLoad { - opcode: Opcode::StackAddr, - stack_slot, - offset, - } = func.dfg[addr_inst] + if let InstructionData::StackLoad { opcode: Opcode::StackAddr, stack_slot, offset } = + func.dfg[addr_inst] { return Some((stack_slot, offset)); } @@ -437,16 +421,8 @@ enum SpatialOverlap { fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap { fn inst_info(func: &Function, inst: Inst) -> (StackSlot, Offset32, u32) { match func.dfg[inst] { - InstructionData::StackLoad { - opcode: Opcode::StackAddr, - stack_slot, - offset, - } - | InstructionData::StackLoad { - opcode: Opcode::StackLoad, - stack_slot, - offset, - } + InstructionData::StackLoad { opcode: Opcode::StackAddr, stack_slot, offset } + | InstructionData::StackLoad { opcode: Opcode::StackLoad, stack_slot, offset } | InstructionData::StackStore { opcode: Opcode::StackStore, stack_slot, @@ -471,10 +447,7 @@ fn spatial_overlap(func: &Function, src: Inst, dest: Inst) -> SpatialOverlap { } let src_end: i64 = src_offset.try_add_i64(i64::from(src_size)).unwrap().into(); - let dest_end: i64 = dest_offset - .try_add_i64(i64::from(dest_size)) - .unwrap() - .into(); + let dest_end: i64 = dest_offset.try_add_i64(i64::from(dest_size)).unwrap().into(); if src_end <= dest_offset.into() || dest_end <= src_offset.into() { return SpatialOverlap::No; } diff --git a/src/pointer.rs b/src/pointer.rs index b2036d7bcd452..88a78f3214d87 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -23,35 +23,20 @@ pub(crate) enum PointerBase { impl Pointer { pub(crate) fn new(addr: Value) -> Self { - Pointer { - base: PointerBase::Addr(addr), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } } pub(crate) fn stack_slot(stack_slot: StackSlot) -> Self { - Pointer { - base: PointerBase::Stack(stack_slot), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Stack(stack_slot), offset: Offset32::new(0) } } - pub(crate) fn const_addr<'a, 'tcx>( - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - addr: i64, - ) -> Self { + pub(crate) fn const_addr(fx: &mut FunctionCx<'_, '_, '_>, addr: i64) -> Self { let addr = fx.bcx.ins().iconst(fx.pointer_type, addr); - Pointer { - base: PointerBase::Addr(addr), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } } pub(crate) fn dangling(align: Align) -> Self { - Pointer { - base: PointerBase::Dangling(align), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) } } #[cfg(debug_assertions)] @@ -59,46 +44,28 @@ impl Pointer { (self.base, self.offset) } - pub(crate) fn get_addr<'a, 'tcx>(self, fx: &mut FunctionCx<'a, 'tcx, impl Module>) -> Value { + pub(crate) fn get_addr(self, fx: &mut FunctionCx<'_, '_, '_>) -> Value { match self.base { PointerBase::Addr(base_addr) => { let offset: i64 = self.offset.into(); - if offset == 0 { - base_addr - } else { - fx.bcx.ins().iadd_imm(base_addr, offset) - } + if offset == 0 { base_addr } else { fx.bcx.ins().iadd_imm(base_addr, offset) } } PointerBase::Stack(stack_slot) => { - fx.bcx - .ins() - .stack_addr(fx.pointer_type, stack_slot, self.offset) + fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, self.offset) + } + PointerBase::Dangling(align) => { + fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()) } - PointerBase::Dangling(align) => fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()), } } - pub(crate) fn offset<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - extra_offset: Offset32, - ) -> Self { + pub(crate) fn offset(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: Offset32) -> Self { self.offset_i64(fx, extra_offset.into()) } - pub(crate) fn offset_i64<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - extra_offset: i64, - ) -> Self { + pub(crate) fn offset_i64(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: i64) -> Self { if let Some(new_offset) = self.offset.try_add_i64(extra_offset) { - Pointer { - base: self.base, - offset: new_offset, - } + Pointer { base: self.base, offset: new_offset } } else { let base_offset: i64 = self.offset.into(); if let Some(new_offset) = base_offset.checked_add(extra_offset) { @@ -107,16 +74,12 @@ impl Pointer { PointerBase::Stack(stack_slot) => { fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0) } - PointerBase::Dangling(align) => fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()), + PointerBase::Dangling(align) => { + fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()) + } }; let addr = fx.bcx.ins().iadd_imm(base_addr, new_offset); - Pointer { - base: PointerBase::Addr(addr), - offset: Offset32::new(0), - } + Pointer { base: PointerBase::Addr(addr), offset: Offset32::new(0) } } else { panic!( "self.offset ({}) + extra_offset ({}) not representable in i64", @@ -126,31 +89,22 @@ impl Pointer { } } - pub(crate) fn offset_value<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - extra_offset: Value, - ) -> Self { + pub(crate) fn offset_value(self, fx: &mut FunctionCx<'_, '_, '_>, extra_offset: Value) -> Self { match self.base { PointerBase::Addr(addr) => Pointer { base: PointerBase::Addr(fx.bcx.ins().iadd(addr, extra_offset)), offset: self.offset, }, PointerBase::Stack(stack_slot) => { - let base_addr = fx - .bcx - .ins() - .stack_addr(fx.pointer_type, stack_slot, self.offset); + let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, self.offset); Pointer { base: PointerBase::Addr(fx.bcx.ins().iadd(base_addr, extra_offset)), offset: Offset32::new(0), } } PointerBase::Dangling(align) => { - let addr = fx - .bcx - .ins() - .iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()); + let addr = + fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(align.bytes()).unwrap()); Pointer { base: PointerBase::Addr(fx.bcx.ins().iadd(addr, extra_offset)), offset: self.offset, @@ -159,46 +113,21 @@ impl Pointer { } } - pub(crate) fn load<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - ty: Type, - flags: MemFlags, - ) -> Value { + pub(crate) fn load(self, fx: &mut FunctionCx<'_, '_, '_>, ty: Type, flags: MemFlags) -> Value { match self.base { PointerBase::Addr(base_addr) => fx.bcx.ins().load(ty, flags, base_addr, self.offset), - PointerBase::Stack(stack_slot) => { - if ty == types::I128 || ty.is_vector() { - // WORKAROUND for stack_load.i128 and stack_load.iXxY not being implemented - let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0); - fx.bcx.ins().load(ty, flags, base_addr, self.offset) - } else { - fx.bcx.ins().stack_load(ty, stack_slot, self.offset) - } - } + PointerBase::Stack(stack_slot) => fx.bcx.ins().stack_load(ty, stack_slot, self.offset), PointerBase::Dangling(_align) => unreachable!(), } } - pub(crate) fn store<'a, 'tcx>( - self, - fx: &mut FunctionCx<'a, 'tcx, impl Module>, - value: Value, - flags: MemFlags, - ) { + pub(crate) fn store(self, fx: &mut FunctionCx<'_, '_, '_>, value: Value, flags: MemFlags) { match self.base { PointerBase::Addr(base_addr) => { fx.bcx.ins().store(flags, value, base_addr, self.offset); } PointerBase::Stack(stack_slot) => { - let val_ty = fx.bcx.func.dfg.value_type(value); - if val_ty == types::I128 || val_ty.is_vector() { - // WORKAROUND for stack_store.i128 and stack_store.iXxY not being implemented - let base_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0); - fx.bcx.ins().store(flags, value, base_addr, self.offset); - } else { - fx.bcx.ins().stack_store(value, stack_slot, self.offset); - } + fx.bcx.ins().stack_store(value, stack_slot, self.offset); } PointerBase::Dangling(_align) => unreachable!(), } diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index f4a15ab12d511..9c91b92e515b1 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -79,20 +79,14 @@ impl CommentWriter { vec![ format!("symbol {}", tcx.symbol_name(instance).name), format!("instance {:?}", instance), - format!( - "abi {:?}", - FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[]) - ), + format!("abi {:?}", FnAbi::of_instance(&RevealAllLayoutCx(tcx), instance, &[])), String::new(), ] } else { vec![] }; - CommentWriter { - global_comments, - entity_comments: FxHashMap::default(), - } + CommentWriter { global_comments, entity_comments: FxHashMap::default() } } } @@ -186,7 +180,7 @@ impl FuncWriter for &'_ CommentWriter { } #[cfg(debug_assertions)] -impl FunctionCx<'_, '_, M> { +impl FunctionCx<'_, '_, '_> { pub(crate) fn add_global_comment>(&mut self, comment: S) { self.clif_comments.add_global_comment(comment); } @@ -201,12 +195,7 @@ impl FunctionCx<'_, '_, M> { } pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { - cfg!(debug_assertions) - || tcx - .sess - .opts - .output_types - .contains_key(&OutputType::LlvmAssembly) + tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } pub(crate) fn write_ir_file<'tcx>( @@ -245,40 +234,33 @@ pub(crate) fn write_clif_file<'tcx>( context: &cranelift_codegen::Context, mut clif_comments: &CommentWriter, ) { - write_ir_file( - tcx, - &format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix), - |file| { - let value_ranges = isa.map(|isa| { - context - .build_value_labels_ranges(isa) - .expect("value location ranges") - }); + write_ir_file(tcx, &format!("{}.{}.clif", tcx.symbol_name(instance).name, postfix), |file| { + let value_ranges = + isa.map(|isa| context.build_value_labels_ranges(isa).expect("value location ranges")); - let mut clif = String::new(); - cranelift_codegen::write::decorate_function( - &mut clif_comments, - &mut clif, - &context.func, - &DisplayFunctionAnnotations { - isa: Some(&*crate::build_isa(tcx.sess)), - value_ranges: value_ranges.as_ref(), - }, - ) - .unwrap(); + let mut clif = String::new(); + cranelift_codegen::write::decorate_function( + &mut clif_comments, + &mut clif, + &context.func, + &DisplayFunctionAnnotations { + isa: Some(&*crate::build_isa(tcx.sess)), + value_ranges: value_ranges.as_ref(), + }, + ) + .unwrap(); - writeln!(file, "test compile")?; - writeln!(file, "set is_pic")?; - writeln!(file, "set enable_simd")?; - writeln!(file, "target {} haswell", crate::target_triple(tcx.sess))?; - writeln!(file)?; - file.write_all(clif.as_bytes())?; - Ok(()) - }, - ); + writeln!(file, "test compile")?; + writeln!(file, "set is_pic")?; + writeln!(file, "set enable_simd")?; + writeln!(file, "target {} haswell", crate::target_triple(tcx.sess))?; + writeln!(file)?; + file.write_all(clif.as_bytes())?; + Ok(()) + }); } -impl fmt::Debug for FunctionCx<'_, '_, M> { +impl fmt::Debug for FunctionCx<'_, '_, '_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "{:?}", self.instance.substs)?; writeln!(f, "{:?}", self.local_map)?; diff --git a/src/toolchain.rs b/src/toolchain.rs index 735c59d70c120..484a9b699a0aa 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -71,12 +71,9 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { flavor, )), (Some(linker), None) => { - let stem = linker - .file_stem() - .and_then(|stem| stem.to_str()) - .unwrap_or_else(|| { - sess.fatal("couldn't extract file stem from specified linker") - }); + let stem = linker.file_stem().and_then(|stem| stem.to_str()).unwrap_or_else(|| { + sess.fatal("couldn't extract file stem from specified linker") + }); let flavor = if stem == "emcc" { LinkerFlavor::Em @@ -105,11 +102,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { // linker and linker flavor specified via command line have precedence over what the target // specification specifies - if let Some(ret) = infer_from( - sess, - sess.opts.cg.linker.clone(), - sess.opts.cg.linker_flavor, - ) { + if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), sess.opts.cg.linker_flavor) { return ret; } diff --git a/src/trap.rs b/src/trap.rs index 67495c7414840..bb63d72addf98 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -2,7 +2,7 @@ use crate::prelude::*; -fn codegen_print(fx: &mut FunctionCx<'_, '_, impl Module>, msg: &str) { +fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) { let puts = fx .cx .module @@ -29,7 +29,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, impl Module>, msg: &str) { } /// Trap code: user1 -pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsRef) { +pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef) { codegen_print(fx, msg.as_ref()); fx.bcx.ins().trap(TrapCode::User(1)); } @@ -38,7 +38,7 @@ pub(crate) fn trap_abort(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsR /// so you can **not** add instructions to it afterwards. /// /// Trap code: user65535 -pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsRef) { +pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef) { codegen_print(fx, msg.as_ref()); fx.bcx.ins().trap(TrapCode::UnreachableCodeReached); } @@ -47,7 +47,7 @@ pub(crate) fn trap_unreachable(fx: &mut FunctionCx<'_, '_, impl Module>, msg: im /// /// Trap code: user65535 pub(crate) fn trap_unreachable_ret_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, dest_layout: TyAndLayout<'tcx>, msg: impl AsRef, ) -> CValue<'tcx> { @@ -62,7 +62,7 @@ pub(crate) fn trap_unreachable_ret_value<'tcx>( /// to it afterwards. /// /// Trap code: user65535 -pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, impl Module>, msg: impl AsRef) { +pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, '_>, msg: impl AsRef) { codegen_print(fx, msg.as_ref()); let true_ = fx.bcx.ins().iconst(types::I32, 1); fx.bcx.ins().trapnz(true_, TrapCode::User(!0)); @@ -72,7 +72,7 @@ pub(crate) fn trap_unimplemented(fx: &mut FunctionCx<'_, '_, impl Module>, msg: /// /// Trap code: user65535 pub(crate) fn trap_unimplemented_ret_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, dest_layout: TyAndLayout<'tcx>, msg: impl AsRef, ) -> CValue<'tcx> { diff --git a/src/unsize.rs b/src/unsize.rs index c77ff5d56ba62..042583cd5720f 100644 --- a/src/unsize.rs +++ b/src/unsize.rs @@ -13,19 +13,18 @@ use crate::prelude::*; /// in an upcast, where the new vtable for an object will be derived /// from the old one. pub(crate) fn unsized_info<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, source: Ty<'tcx>, target: Ty<'tcx>, old_info: Option, ) -> Value { let (source, target) = - fx.tcx - .struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all()); + fx.tcx.struct_lockstep_tails_erasing_lifetimes(source, target, ParamEnv::reveal_all()); match (&source.kind(), &target.kind()) { - (&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst( - fx.pointer_type, - len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64, - ), + (&ty::Array(_, len), &ty::Slice(_)) => fx + .bcx + .ins() + .iconst(fx.pointer_type, len.eval_usize(fx.tcx, ParamEnv::reveal_all()) as i64), (&ty::Dynamic(..), &ty::Dynamic(..)) => { // For now, upcasts are limited to changes in marker // traits, and hence never actually require an actual @@ -35,17 +34,13 @@ pub(crate) fn unsized_info<'tcx>( (_, &ty::Dynamic(ref data, ..)) => { crate::vtable::get_vtable(fx, fx.layout_of(source), data.principal()) } - _ => bug!( - "unsized_info: invalid unsizing {:?} -> {:?}", - source, - target - ), + _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target), } } /// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer. fn unsize_thin_ptr<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, src: Value, src_layout: TyAndLayout<'tcx>, dst_layout: TyAndLayout<'tcx>, @@ -89,24 +84,22 @@ fn unsize_thin_ptr<'tcx>( /// 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` pub(crate) fn coerce_unsized_into<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, src: CValue<'tcx>, dst: CPlace<'tcx>, ) { let src_ty = src.layout().ty; let dst_ty = dst.layout().ty; let mut coerce_ptr = || { - let (base, info) = if fx - .layout_of(src.layout().ty.builtin_deref(true).unwrap().ty) - .is_unsized() - { - // fat-ptr to fat-ptr unsize preserves the vtable - // i.e., &'a fmt::Debug+Send => &'a fmt::Debug - src.load_scalar_pair(fx) - } else { - let base = src.load_scalar(fx); - unsize_thin_ptr(fx, base, src.layout(), dst.layout()) - }; + let (base, info) = + if fx.layout_of(src.layout().ty.builtin_deref(true).unwrap().ty).is_unsized() { + // fat-ptr to fat-ptr unsize preserves the vtable + // i.e., &'a fmt::Debug+Send => &'a fmt::Debug + src.load_scalar_pair(fx) + } else { + let base = src.load_scalar(fx); + unsize_thin_ptr(fx, base, src.layout(), dst.layout()) + }; dst.write_cvalue(fx, CValue::by_val_pair(base, info, dst.layout())); }; match (&src_ty.kind(), &dst_ty.kind()) { @@ -131,39 +124,26 @@ pub(crate) fn coerce_unsized_into<'tcx>( } } } - _ => bug!( - "coerce_unsized_into: invalid coercion {:?} -> {:?}", - src_ty, - dst_ty - ), + _ => bug!("coerce_unsized_into: invalid coercion {:?} -> {:?}", src_ty, dst_ty), } } // 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>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, info: Value, ) -> (Value, Value) { if !layout.is_unsized() { - let size = fx - .bcx - .ins() - .iconst(fx.pointer_type, layout.size.bytes() as i64); - let align = fx - .bcx - .ins() - .iconst(fx.pointer_type, layout.align.abi.bytes() as i64); + let size = fx.bcx.ins().iconst(fx.pointer_type, layout.size.bytes() as i64); + let align = fx.bcx.ins().iconst(fx.pointer_type, layout.align.abi.bytes() as i64); return (size, align); } match layout.ty.kind() { ty::Dynamic(..) => { // load size/align from vtable - ( - crate::vtable::size_of_obj(fx, info), - crate::vtable::min_align_of_obj(fx, info), - ) + (crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info)) } ty::Slice(_) | ty::Str => { let unit = layout.field(fx, 0); @@ -171,9 +151,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>( // times the unit size. ( fx.bcx.ins().imul_imm(info, unit.size.bytes() as i64), - fx.bcx - .ins() - .iconst(fx.pointer_type, unit.align.abi.bytes() as i64), + fx.bcx.ins().iconst(fx.pointer_type, unit.align.abi.bytes() as i64), ) } _ => { @@ -211,10 +189,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>( // Choose max of two known alignments (combined value must // be aligned according to more restrictive of the two). - let cmp = fx - .bcx - .ins() - .icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align); + let cmp = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, sized_align, unsized_align); let align = fx.bcx.ins().select(cmp, sized_align, unsized_align); // Issue #27023: must add any necessary padding to `size` diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 765604e0f984e..cffaf79ded10b 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -6,7 +6,7 @@ use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::immediates::Offset32; fn codegen_field<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, base: Pointer, extra: Option, layout: TyAndLayout<'tcx>, @@ -15,11 +15,8 @@ fn codegen_field<'tcx>( let field_offset = layout.fields.offset(field.index()); let field_layout = layout.field(&*fx, field.index()); - let simple = |fx: &mut FunctionCx<'_, '_, _>| { - ( - base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()), - field_layout, - ) + let simple = |fx: &mut FunctionCx<'_, '_, '_>| { + (base.offset_i64(fx, i64::try_from(field_offset.bytes()).unwrap()), field_layout) }; if let Some(extra) = extra { @@ -58,10 +55,7 @@ fn scalar_pair_calculate_b_offset( a_scalar: &Scalar, b_scalar: &Scalar, ) -> Offset32 { - let b_offset = a_scalar - .value - .size(&tcx) - .align_to(b_scalar.value.align(&tcx).abi); + let b_offset = a_scalar.value.size(&tcx).align_to(b_scalar.value.align(&tcx).abi); Offset32::new(b_offset.bytes().try_into().unwrap()) } @@ -106,10 +100,7 @@ impl<'tcx> CValue<'tcx> { } // FIXME remove - pub(crate) fn force_stack( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - ) -> (Pointer, Option) { + pub(crate) fn force_stack(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> (Pointer, Option) { let layout = self.1; match self.0 { CValueInner::ByRef(ptr, meta) => (ptr, meta), @@ -129,7 +120,7 @@ impl<'tcx> CValue<'tcx> { } /// Load a value with layout.abi of scalar - pub(crate) fn load_scalar(self, fx: &mut FunctionCx<'_, 'tcx, impl Module>) -> Value { + pub(crate) fn load_scalar(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> Value { let layout = self.1; match self.0 { CValueInner::ByRef(ptr, None) => { @@ -153,10 +144,7 @@ impl<'tcx> CValue<'tcx> { } /// Load a value pair with layout.abi of scalar pair - pub(crate) fn load_scalar_pair( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - ) -> (Value, Value) { + pub(crate) fn load_scalar_pair(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> (Value, Value) { let layout = self.1; match self.0 { CValueInner::ByRef(ptr, None) => { @@ -183,7 +171,7 @@ impl<'tcx> CValue<'tcx> { pub(crate) fn value_field( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, field: mir::Field, ) -> CValue<'tcx> { let layout = self.1; @@ -219,21 +207,17 @@ impl<'tcx> CValue<'tcx> { } } - pub(crate) fn unsize_value( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - dest: CPlace<'tcx>, - ) { + pub(crate) fn unsize_value(self, fx: &mut FunctionCx<'_, '_, 'tcx>, dest: CPlace<'tcx>) { crate::unsize::coerce_unsized_into(fx, self, dest); } /// If `ty` is signed, `const_val` must already be sign extended. pub(crate) fn const_val( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, const_val: ty::ScalarInt, ) -> CValue<'tcx> { - assert_eq!(const_val.size(), layout.size); + assert_eq!(const_val.size(), layout.size, "{:#?}: {:?}", const_val, layout); use cranelift_codegen::ir::immediates::{Ieee32, Ieee64}; let clif_ty = fx.clif_type(layout.ty).unwrap(); @@ -250,18 +234,11 @@ impl<'tcx> CValue<'tcx> { ty::Uint(UintTy::U128) | ty::Int(IntTy::I128) => { let const_val = const_val.to_bits(layout.size).unwrap(); let lsb = fx.bcx.ins().iconst(types::I64, const_val as u64 as i64); - let msb = fx - .bcx - .ins() - .iconst(types::I64, (const_val >> 64) as u64 as i64); + let msb = fx.bcx.ins().iconst(types::I64, (const_val >> 64) as u64 as i64); fx.bcx.ins().iconcat(lsb, msb) } - ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..) - | ty::RawPtr(..) => { - fx - .bcx - .ins() - .iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64) + ty::Bool | ty::Char | ty::Uint(_) | ty::Int(_) | ty::Ref(..) | ty::RawPtr(..) => { + fx.bcx.ins().iconst(clif_ty, const_val.to_bits(layout.size).unwrap() as i64) } ty::Float(FloatTy::F32) => { fx.bcx.ins().f32const(Ieee32::with_bits(u32::try_from(const_val).unwrap())) @@ -279,14 +256,8 @@ impl<'tcx> CValue<'tcx> { } pub(crate) fn cast_pointer_to(self, layout: TyAndLayout<'tcx>) -> Self { - assert!(matches!( - self.layout().ty.kind(), - ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) - )); - assert!(matches!( - layout.ty.kind(), - ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..) - )); + assert!(matches!(self.layout().ty.kind(), ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..))); + assert!(matches!(layout.ty.kind(), ty::Ref(..) | ty::RawPtr(..) | ty::FnPtr(..))); assert_eq!(self.layout().abi, layout.abi); CValue(self.0, layout) } @@ -317,14 +288,11 @@ impl<'tcx> CPlace<'tcx> { } pub(crate) fn no_place(layout: TyAndLayout<'tcx>) -> CPlace<'tcx> { - CPlace { - inner: CPlaceInner::Addr(Pointer::dangling(layout.align.pref), None), - layout, - } + CPlace { inner: CPlaceInner::Addr(Pointer::dangling(layout.align.pref), None), layout } } pub(crate) fn new_stack_slot( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { assert!(!layout.is_unsized()); @@ -339,28 +307,22 @@ impl<'tcx> CPlace<'tcx> { size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16, offset: None, }); - CPlace { - inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), - layout, - } + CPlace { inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), layout } } pub(crate) fn new_var( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { let var = Variable::with_u32(fx.next_ssa_var); fx.next_ssa_var += 1; fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap()); - CPlace { - inner: CPlaceInner::Var(local, var), - layout, - } + CPlace { inner: CPlaceInner::Var(local, var), layout } } pub(crate) fn new_var_pair( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, local: Local, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { @@ -372,17 +334,11 @@ impl<'tcx> CPlace<'tcx> { let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap(); fx.bcx.declare_var(var1, ty1); fx.bcx.declare_var(var2, ty2); - CPlace { - inner: CPlaceInner::VarPair(local, var1, var2), - layout, - } + CPlace { inner: CPlaceInner::VarPair(local, var1, var2), layout } } pub(crate) fn for_ptr(ptr: Pointer, layout: TyAndLayout<'tcx>) -> CPlace<'tcx> { - CPlace { - inner: CPlaceInner::Addr(ptr, None), - layout, - } + CPlace { inner: CPlaceInner::Addr(ptr, None), layout } } pub(crate) fn for_ptr_with_extra( @@ -390,34 +346,27 @@ impl<'tcx> CPlace<'tcx> { extra: Value, layout: TyAndLayout<'tcx>, ) -> CPlace<'tcx> { - CPlace { - inner: CPlaceInner::Addr(ptr, Some(extra)), - layout, - } + CPlace { inner: CPlaceInner::Addr(ptr, Some(extra)), layout } } - pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, 'tcx, impl Module>) -> CValue<'tcx> { + pub(crate) fn to_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CValue<'tcx> { let layout = self.layout(); match self.inner { CPlaceInner::Var(_local, var) => { let val = fx.bcx.use_var(var); - fx.bcx - .set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); CValue::by_val(val, layout) } CPlaceInner::VarPair(_local, var1, var2) => { let val1 = fx.bcx.use_var(var1); - fx.bcx - .set_val_label(val1, cranelift_codegen::ir::ValueLabel::new(var1.index())); + //fx.bcx.set_val_label(val1, cranelift_codegen::ir::ValueLabel::new(var1.index())); let val2 = fx.bcx.use_var(var2); - fx.bcx - .set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index())); + //fx.bcx.set_val_label(val2, cranelift_codegen::ir::ValueLabel::new(var2.index())); CValue::by_val_pair(val1, val2, layout) } CPlaceInner::VarLane(_local, var, lane) => { let val = fx.bcx.use_var(var); - fx.bcx - .set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(val, cranelift_codegen::ir::ValueLabel::new(var.index())); let val = fx.bcx.ins().extractlane(val, lane); CValue::by_val(val, layout) } @@ -447,11 +396,7 @@ impl<'tcx> CPlace<'tcx> { } } - pub(crate) fn write_cvalue( - self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, - from: CValue<'tcx>, - ) { + pub(crate) fn write_cvalue(self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>) { assert_assignable(fx, from.layout().ty, self.layout().ty); self.write_cvalue_maybe_transmute(fx, from, "write_cvalue"); @@ -459,7 +404,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn write_cvalue_transmute( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>, ) { self.write_cvalue_maybe_transmute(fx, from, "write_cvalue_transmute"); @@ -467,12 +412,12 @@ impl<'tcx> CPlace<'tcx> { fn write_cvalue_maybe_transmute( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>, #[cfg_attr(not(debug_assertions), allow(unused_variables))] method: &'static str, ) { fn transmute_value<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, var: Variable, data: Value, dst_ty: Type, @@ -511,8 +456,7 @@ impl<'tcx> CPlace<'tcx> { } _ => unreachable!("write_cvalue_transmute: {:?} -> {:?}", src_ty, dst_ty), }; - fx.bcx - .set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(data, cranelift_codegen::ir::ValueLabel::new(var.index())); fx.bcx.def_var(var, data); } @@ -558,15 +502,13 @@ impl<'tcx> CPlace<'tcx> { // First get the old vector let vector = fx.bcx.use_var(var); - fx.bcx - .set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); // Next insert the written lane into the vector let vector = fx.bcx.ins().insertlane(vector, data, lane); // Finally write the new vector - fx.bcx - .set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); + //fx.bcx.set_val_label(vector, cranelift_codegen::ir::ValueLabel::new(var.index())); fx.bcx.def_var(var, vector); return; @@ -604,10 +546,7 @@ impl<'tcx> CPlace<'tcx> { to_ptr.store(fx, val, flags); } CValueInner::ByValPair(_, _) => { - bug!( - "Non ScalarPair abi {:?} for ByValPair CValue", - dst_layout.abi - ); + bug!("Non ScalarPair abi {:?} for ByValPair CValue", dst_layout.abi); } CValueInner::ByRef(from_ptr, None) => { let from_addr = from_ptr.get_addr(fx); @@ -632,7 +571,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_field( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, field: mir::Field, ) -> CPlace<'tcx> { let layout = self.layout(); @@ -650,18 +589,8 @@ impl<'tcx> CPlace<'tcx> { let layout = layout.field(&*fx, field.index()); match field.as_u32() { - 0 => { - return CPlace { - inner: CPlaceInner::Var(local, var1), - layout, - } - } - 1 => { - return CPlace { - inner: CPlaceInner::Var(local, var2), - layout, - } - } + 0 => return CPlace { inner: CPlaceInner::Var(local, var1), layout }, + 1 => return CPlace { inner: CPlaceInner::Var(local, var2), layout }, _ => unreachable!("field should be 0 or 1"), } } @@ -680,7 +609,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_index( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, index: Value, ) -> CPlace<'tcx> { let (elem_layout, ptr) = match self.layout().ty.kind() { @@ -689,30 +618,24 @@ impl<'tcx> CPlace<'tcx> { _ => bug!("place_index({:?})", self.layout().ty), }; - let offset = fx - .bcx - .ins() - .imul_imm(index, elem_layout.size.bytes() as i64); + let offset = fx.bcx.ins().imul_imm(index, elem_layout.size.bytes() as i64); CPlace::for_ptr(ptr.offset_value(fx, offset), elem_layout) } - pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, 'tcx, impl Module>) -> CPlace<'tcx> { + pub(crate) fn place_deref(self, fx: &mut FunctionCx<'_, '_, 'tcx>) -> CPlace<'tcx> { let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty); if has_ptr_meta(fx.tcx, inner_layout.ty) { let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx); CPlace::for_ptr_with_extra(Pointer::new(addr), extra, inner_layout) } else { - CPlace::for_ptr( - Pointer::new(self.to_cvalue(fx).load_scalar(fx)), - inner_layout, - ) + CPlace::for_ptr(Pointer::new(self.to_cvalue(fx).load_scalar(fx)), inner_layout) } } pub(crate) fn place_ref( self, - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { if has_ptr_meta(fx.tcx, self.layout().ty) { @@ -729,21 +652,18 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn downcast_variant( self, - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, variant: VariantIdx, ) -> Self { assert!(!self.layout().is_unsized()); let layout = self.layout().for_variant(fx, variant); - CPlace { - inner: self.inner, - layout, - } + CPlace { inner: self.inner, layout } } } #[track_caller] pub(crate) fn assert_assignable<'tcx>( - fx: &FunctionCx<'_, 'tcx, impl Module>, + fx: &FunctionCx<'_, '_, 'tcx>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>, ) { @@ -776,12 +696,9 @@ pub(crate) fn assert_assignable<'tcx>( } (&ty::Dynamic(from_traits, _), &ty::Dynamic(to_traits, _)) => { for (from, to) in from_traits.iter().zip(to_traits) { - let from = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); - let to = fx - .tcx - .normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to); + let from = + fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), from); + let to = fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), to); assert_eq!( from, to, "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n\n{:#?}", diff --git a/src/vtable.rs b/src/vtable.rs index 8f15586a9dc06..4d2551a061b99 100644 --- a/src/vtable.rs +++ b/src/vtable.rs @@ -15,7 +15,7 @@ fn vtable_memflags() -> MemFlags { flags } -pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Value) -> Value { +pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; fx.bcx.ins().load( pointer_ty(fx.tcx), @@ -25,7 +25,7 @@ pub(crate) fn drop_fn_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: V ) } -pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Value) -> Value { +pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; fx.bcx.ins().load( pointer_ty(fx.tcx), @@ -35,7 +35,7 @@ pub(crate) fn size_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Valu ) } -pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: Value) -> Value { +pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, '_>, vtable: Value) -> Value { let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize; fx.bcx.ins().load( pointer_ty(fx.tcx), @@ -46,7 +46,7 @@ pub(crate) fn min_align_of_obj(fx: &mut FunctionCx<'_, '_, impl Module>, vtable: } pub(crate) fn get_ptr_and_method_ref<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, arg: CValue<'tcx>, idx: usize, ) -> (Value, Value) { @@ -68,7 +68,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( } pub(crate) fn get_vtable<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, trait_ref: Option>, ) -> Value { @@ -85,7 +85,7 @@ pub(crate) fn get_vtable<'tcx>( } fn build_vtable<'tcx>( - fx: &mut FunctionCx<'_, 'tcx, impl Module>, + fx: &mut FunctionCx<'_, '_, 'tcx>, layout: TyAndLayout<'tcx>, trait_ref: Option>, ) -> DataId { @@ -94,7 +94,7 @@ fn build_vtable<'tcx>( let drop_in_place_fn = import_function( tcx, - &mut fx.cx.module, + fx.cx.module, Instance::resolve_drop_in_place(tcx, layout.ty).polymorphize(fx.tcx), ); @@ -111,7 +111,7 @@ fn build_vtable<'tcx>( opt_mth.map(|(def_id, substs)| { import_function( tcx, - &mut fx.cx.module, + fx.cx.module, Instance::resolve_for_vtable(tcx, ParamEnv::reveal_all(), def_id, substs) .unwrap() .polymorphize(fx.tcx), @@ -165,11 +165,8 @@ fn build_vtable<'tcx>( } fn write_usize(tcx: TyCtxt<'_>, buf: &mut [u8], idx: usize, num: u64) { - let pointer_size = tcx - .layout_of(ParamEnv::reveal_all().and(tcx.types.usize)) - .unwrap() - .size - .bytes() as usize; + let pointer_size = + tcx.layout_of(ParamEnv::reveal_all().and(tcx.types.usize)).unwrap().size.bytes() as usize; let target = &mut buf[idx * pointer_size..(idx + 1) * pointer_size]; match tcx.data_layout.endian { diff --git a/test.sh b/test.sh index 5ab10e0e905c7..e222adc7b8058 100755 --- a/test.sh +++ b/test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e ./build.sh --sysroot none "$@" From c825bc8e61c9a30adebacbe87d048324a5e1063a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 5 Mar 2021 21:32:37 +0100 Subject: [PATCH 03/51] Update Cranelift This adds support for the WindowsFastcall calling convention --- Cargo.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 76d9f0d27ce46..1ed186032ff20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "byteorder", "cranelift-bforest", @@ -65,8 +65,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -74,18 +74,18 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" [[package]] name = "cranelift-entity" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" [[package]] name = "cranelift-frontend" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-codegen", "log", @@ -95,8 +95,8 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "anyhow", "cranelift-codegen", @@ -113,8 +113,8 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "anyhow", "cranelift-codegen", @@ -125,8 +125,8 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "cranelift-codegen", "target-lexicon", @@ -134,8 +134,8 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.70.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#cdb60ec5a9df087262ae8960a31067e88cd80058" +version = "0.71.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" dependencies = [ "anyhow", "cranelift-codegen", From 1122f42e2872a4bb65adeb990fb73cc555f5c3cf Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 25 May 2020 21:43:22 +0200 Subject: [PATCH 04/51] Support cross-compiling to Windows using MinGW --- example/mini_core.rs | 1 + example/mini_core_hello_world.rs | 4 +- example/std_example.rs | 3 +- prepare.sh | 1 + src/codegen_i128.rs | 89 +++++++++++++++++++++++++------- src/inline_asm.rs | 4 ++ src/lib.rs | 2 + 7 files changed, 82 insertions(+), 22 deletions(-) diff --git a/example/mini_core.rs b/example/mini_core.rs index 7c6d7fc106ded..c4834c8040871 100644 --- a/example/mini_core.rs +++ b/example/mini_core.rs @@ -621,6 +621,7 @@ struct PanicLocation { } #[no_mangle] +#[cfg(not(windows))] pub fn get_tls() -> u8 { #[thread_local] static A: u8 = 42; diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 237f4d11d57f1..08ceaeb65443f 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -239,7 +239,7 @@ fn main() { assert_eq!(((|()| 42u8) as fn(()) -> u8)(()), 42); - #[cfg(not(jit))] + #[cfg(not(any(jit, windows)))] { extern { #[linkage = "extern_weak"] @@ -292,7 +292,7 @@ fn main() { from_decimal_string(); - #[cfg(not(jit))] + #[cfg(not(any(jit, windows)))] test_tls(); #[cfg(all(not(jit), target_os = "linux"))] diff --git a/example/std_example.rs b/example/std_example.rs index 015bbdfed4648..221b512e3bd4c 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -16,7 +16,8 @@ fn main() { let mut stderr = stderr.lock(); // FIXME support lazy jit when multi threading - #[cfg(not(lazy_jit))] + // FIXME support TLS on windows + #[cfg(not(any(lazy_jit, windows)))] std::thread::spawn(move || { println!("Hello from another thread!"); }); diff --git a/prepare.sh b/prepare.sh index ee995ffcfa9f7..d391399bee070 100755 --- a/prepare.sh +++ b/prepare.sh @@ -2,6 +2,7 @@ set -e rustup component add rust-src rustc-dev llvm-tools-preview +rustup target add x86_64-pc-windows-gnu ./build_sysroot/prepare_sysroot_src.sh cargo install hyperfine || echo "Skipping hyperfine install" diff --git a/src/codegen_i128.rs b/src/codegen_i128.rs index ae75e6508cb0b..ffe1922ab9056 100644 --- a/src/codegen_i128.rs +++ b/src/codegen_i128.rs @@ -32,18 +32,56 @@ pub(crate) fn maybe_codegen<'tcx>( BinOp::Add | BinOp::Sub if !checked => None, BinOp::Mul if !checked => { let val_ty = if is_signed { fx.tcx.types.i128 } else { fx.tcx.types.u128 }; - Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) + if fx.tcx.sess.target.is_like_windows { + let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); + let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); + let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); + assert!(lhs_extra.is_none()); + assert!(rhs_extra.is_none()); + let args = + [ret_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)]; + fx.lib_call( + "__multi3", + vec![ + AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + vec![], + &args, + ); + Some(ret_place.to_cvalue(fx)) + } else { + Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) + } } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); let out_ty = fx.tcx.mk_tup([lhs.layout().ty, fx.tcx.types.bool].iter()); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); - let param_types = vec![ - AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), - AbiParam::new(types::I128), - AbiParam::new(types::I128), - ]; - let args = [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)]; + let (param_types, args) = if fx.tcx.sess.target.is_like_windows { + let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); + let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); + assert!(lhs_extra.is_none()); + assert!(rhs_extra.is_none()); + ( + vec![ + AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), + AbiParam::new(pointer_ty(fx.tcx)), + AbiParam::new(pointer_ty(fx.tcx)), + ], + [out_place.to_ptr().get_addr(fx), lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)], + ) + } else { + ( + vec![ + AbiParam::special(pointer_ty(fx.tcx), ArgumentPurpose::StructReturn), + AbiParam::new(types::I128), + AbiParam::new(types::I128), + ], + [out_place.to_ptr().get_addr(fx), lhs.load_scalar(fx), rhs.load_scalar(fx)], + ) + }; let name = match (bin_op, is_signed) { (BinOp::Add, false) => "__rust_u128_addo", (BinOp::Add, true) => "__rust_i128_addo", @@ -57,20 +95,33 @@ pub(crate) fn maybe_codegen<'tcx>( Some(out_place.to_cvalue(fx)) } BinOp::Offset => unreachable!("offset should only be used on pointers, not 128bit ints"), - BinOp::Div => { + BinOp::Div | BinOp::Rem => { assert!(!checked); - if is_signed { - Some(fx.easy_call("__divti3", &[lhs, rhs], fx.tcx.types.i128)) - } else { - Some(fx.easy_call("__udivti3", &[lhs, rhs], fx.tcx.types.u128)) - } - } - BinOp::Rem => { - assert!(!checked); - if is_signed { - Some(fx.easy_call("__modti3", &[lhs, rhs], fx.tcx.types.i128)) + let name = match (bin_op, is_signed) { + (BinOp::Div, false) => "__udivti3", + (BinOp::Div, true) => "__divti3", + (BinOp::Rem, false) => "__umodti3", + (BinOp::Rem, true) => "__modti3", + _ => unreachable!(), + }; + if fx.tcx.sess.target.is_like_windows { + let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); + let (rhs_ptr, rhs_extra) = rhs.force_stack(fx); + assert!(lhs_extra.is_none()); + assert!(rhs_extra.is_none()); + let args = [lhs_ptr.get_addr(fx), rhs_ptr.get_addr(fx)]; + let ret = fx.lib_call( + name, + vec![AbiParam::new(pointer_ty(fx.tcx)), AbiParam::new(pointer_ty(fx.tcx))], + vec![AbiParam::new(types::I64X2)], + &args, + )[0]; + // FIXME use bitcast instead of store to get from i64x2 to i128 + let ret_place = CPlace::new_stack_slot(fx, lhs.layout()); + ret_place.to_ptr().store(fx, ret, MemFlags::trusted()); + Some(ret_place.to_cvalue(fx)) } else { - Some(fx.easy_call("__umodti3", &[lhs, rhs], fx.tcx.types.u128)) + Some(fx.easy_call(name, &[lhs, rhs], lhs.layout().ty)) } } BinOp::Lt | BinOp::Le | BinOp::Eq | BinOp::Ge | BinOp::Gt | BinOp::Ne => { diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 5b3df2bd38280..33234f820aa8f 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -20,6 +20,10 @@ pub(crate) fn codegen_inline_asm<'tcx>( if template.is_empty() { // Black box return; + } else if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) { + let true_ = fx.bcx.ins().iconst(types::I32, 1); + fx.bcx.ins().trapnz(true_, TrapCode::User(1)); + return; } let mut slot_size = Size::from_bytes(0); diff --git a/src/lib.rs b/src/lib.rs index e1927ad3a6920..5db2499709a62 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -313,6 +313,8 @@ fn build_isa(sess: &Session) -> Box { flags_builder.set("enable_simd", "true").unwrap(); + flags_builder.set("enable_llvm_abi_extensions", "true").unwrap(); + use rustc_session::config::OptLevel; match sess.opts.optimize { OptLevel::No => { From d23b12fa62b30a30eba42a33fb2d1ff3932815db Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Feb 2021 14:35:27 +0100 Subject: [PATCH 05/51] Build all tests when cross-compiling --- build.sh | 7 +++++++ scripts/tests.sh | 45 ++++++++++++++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/build.sh b/build.sh index 090349e54b148..76bc1884334af 100755 --- a/build.sh +++ b/build.sh @@ -55,6 +55,7 @@ ln target/$CHANNEL/*rustc_codegen_cranelift* "$target_dir"/lib ln rust-toolchain scripts/config.sh scripts/cargo.sh "$target_dir" mkdir -p "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/" +mkdir -p "$target_dir/lib/rustlib/$HOST_TRIPLE/lib/" if [[ "$TARGET_TRIPLE" == "x86_64-pc-windows-gnu" ]]; then cp $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib/*.o "$target_dir/lib/rustlib/$TARGET_TRIPLE/lib/" fi @@ -64,12 +65,18 @@ case "$build_sysroot" in ;; "llvm") cp -r $(rustc --print sysroot)/lib/rustlib/$TARGET_TRIPLE/lib "$target_dir/lib/rustlib/$TARGET_TRIPLE/" + if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then + cp -r $(rustc --print sysroot)/lib/rustlib/$HOST_TRIPLE/lib "$target_dir/lib/rustlib/$HOST_TRIPLE/" + fi ;; "clif") echo "[BUILD] sysroot" dir=$(pwd) cd "$target_dir" time "$dir/build_sysroot/build_sysroot.sh" + if [[ "$HOST_TRIPLE" != "$TARGET_TRIPLE" ]]; then + time TARGET_TRIPLE="$HOST_TRIPLE" "$dir/build_sysroot/build_sysroot.sh" + fi cp lib/rustlib/*/lib/libstd-* lib/ ;; *) diff --git a/scripts/tests.sh b/scripts/tests.sh index f9a9fb091fb4a..3afcea8f06bd6 100755 --- a/scripts/tests.sh +++ b/scripts/tests.sh @@ -71,14 +71,20 @@ function base_sysroot_tests() { echo "[AOT] mod_bench" $MY_RUSTC example/mod_bench.rs --crate-type bin --target "$TARGET_TRIPLE" $RUN_WRAPPER ./target/out/mod_bench +} +function extended_sysroot_tests() { pushd rand - rm -r ./target || true - ../build/cargo.sh test --workspace + cargo clean + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + echo "[TEST] rust-random/rand" + ../build/cargo.sh test --workspace + else + echo "[AOT] rust-random/rand" + ../build/cargo.sh build --workspace --target $TARGET_TRIPLE --tests + fi popd -} -function extended_sysroot_tests() { pushd simple-raytracer if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then echo "[BENCH COMPILE] ebobby/simple-raytracer" @@ -92,27 +98,40 @@ function extended_sysroot_tests() { else echo "[BENCH COMPILE] ebobby/simple-raytracer (skipped)" echo "[COMPILE] ebobby/simple-raytracer" - ../cargo.sh build + ../build/cargo.sh build --target $TARGET_TRIPLE echo "[BENCH RUN] ebobby/simple-raytracer (skipped)" fi popd pushd build_sysroot/sysroot_src/library/core/tests echo "[TEST] libcore" - rm -r ./target || true - ../../../../../build/cargo.sh test + cargo clean + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + ../../../../../build/cargo.sh test + else + ../../../../../build/cargo.sh build --target $TARGET_TRIPLE --tests + fi popd pushd regex echo "[TEST] rust-lang/regex example shootout-regex-dna" - ../build/cargo.sh clean + cargo clean # Make sure `[codegen mono items] start` doesn't poison the diff - ../build/cargo.sh build --example shootout-regex-dna - cat examples/regexdna-input.txt | ../build/cargo.sh run --example shootout-regex-dna | grep -v "Spawned thread" > res.txt - diff -u res.txt examples/regexdna-output.txt + ../build/cargo.sh build --example shootout-regex-dna --target $TARGET_TRIPLE + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + cat examples/regexdna-input.txt \ + | ../build/cargo.sh run --example shootout-regex-dna --target $TARGET_TRIPLE \ + | grep -v "Spawned thread" > res.txt + diff -u res.txt examples/regexdna-output.txt + fi - echo "[TEST] rust-lang/regex tests" - ../build/cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q + if [[ "$HOST_TRIPLE" = "$TARGET_TRIPLE" ]]; then + echo "[TEST] rust-lang/regex tests" + ../build/cargo.sh test --tests -- --exclude-should-panic --test-threads 1 -Zunstable-options -q + else + echo "[AOT] rust-lang/regex tests" + ../build/cargo.sh build --tests --target $TARGET_TRIPLE + fi popd } From 00f1cddb9c8ecd82ada4ea30430cb6cf178c50ba Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Feb 2021 14:54:52 +0100 Subject: [PATCH 06/51] Test Windows cross-compilation on CI --- .github/workflows/main.yml | 17 ++++++++++++++++- prepare.sh | 1 - 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e6d3375fb1bab..e06a1fb88bad8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,7 +11,13 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + include: + - os: ubuntu-latest + - os: macos-latest + # cross-compile from Linux to Windows using mingw + - os: ubuntu-latest + env: + TARGET_TRIPLE: x86_64-pc-windows-gnu steps: - uses: actions/checkout@v2 @@ -36,6 +42,12 @@ jobs: path: target key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + - name: Install MinGW toolchain and wine + if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu' + run: | + sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable + rustup target add x86_64-pc-windows-gnu + - name: Prepare dependencies run: | git config --global user.email "user@example.com" @@ -43,6 +55,8 @@ jobs: ./prepare.sh - name: Test + env: + TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }} run: | # Enable backtraces for easier debugging export RUST_BACKTRACE=1 @@ -57,6 +71,7 @@ jobs: run: tar cvfJ cg_clif.tar.xz build - name: Upload prebuilt cg_clif + if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu' uses: actions/upload-artifact@v2 with: name: cg_clif-${{ runner.os }} diff --git a/prepare.sh b/prepare.sh index d391399bee070..ee995ffcfa9f7 100755 --- a/prepare.sh +++ b/prepare.sh @@ -2,7 +2,6 @@ set -e rustup component add rust-src rustc-dev llvm-tools-preview -rustup target add x86_64-pc-windows-gnu ./build_sysroot/prepare_sysroot_src.sh cargo install hyperfine || echo "Skipping hyperfine install" From 0985044c75fff285928c451a3d43056b0955b761 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 14:46:38 +0100 Subject: [PATCH 07/51] Use --print file-names instead of a match on uname --- scripts/config.sh | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/scripts/config.sh b/scripts/config.sh index c2ed2bf256d59..99b302ee1d94b 100644 --- a/scripts/config.sh +++ b/scripts/config.sh @@ -2,15 +2,7 @@ set -e -unamestr=$(uname) -if [[ "$unamestr" == 'Linux' || "$unamestr" == 'FreeBSD' ]]; then - dylib_ext='so' -elif [[ "$unamestr" == 'Darwin' ]]; then - dylib_ext='dylib' -else - echo "Unsupported os" - exit 1 -fi +dylib=$(echo "" | rustc --print file-names --crate-type dylib --crate-name rustc_codegen_cranelift -) if echo "$RUSTC_WRAPPER" | grep sccache; then echo @@ -24,10 +16,10 @@ dir=$(cd "$(dirname "${BASH_SOURCE[0]}")"; pwd) export RUSTC=$dir"/bin/cg_clif" export RUSTDOCFLAGS=$linker' -Cpanic=abort -Zpanic-abort-tests '\ -'-Zcodegen-backend='$dir'/lib/librustc_codegen_cranelift.'$dylib_ext' --sysroot '$dir +'-Zcodegen-backend='$dir'/lib/'$dylib' --sysroot '$dir # FIXME fix `#[linkage = "extern_weak"]` without this -if [[ "$unamestr" == 'Darwin' ]]; then +if [[ "$(uname)" == 'Darwin' ]]; then export RUSTFLAGS="$RUSTFLAGS -Clink-arg=-undefined -Clink-arg=dynamic_lookup" fi From 5f3d640d45d88410511f610796b9a36465899eee Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 14:49:55 +0100 Subject: [PATCH 08/51] Fix warning --- src/value_and_place.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index cffaf79ded10b..c2c59773848cb 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -2,7 +2,6 @@ use crate::prelude::*; -use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::immediates::Offset32; fn codegen_field<'tcx>( From bd1b1dd58e257322821267614ef6009d9c3ff5c8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 14:58:29 +0100 Subject: [PATCH 09/51] Handle #![windows_subsystem] --- src/driver/aot.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index b87dcc41928b6..0f1da66170a32 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -163,6 +163,22 @@ pub(super) fn run_aot( metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box<(CodegenResults, FxHashMap)> { + use rustc_span::symbol::sym; + + let subsystem = tcx + .sess + .first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem); + let windows_subsystem = subsystem.map(|subsystem| { + if subsystem != sym::windows && subsystem != sym::console { + tcx.sess.fatal(&format!( + "invalid windows subsystem `{}`, only \ + `windows` and `console` are allowed", + subsystem + )); + } + subsystem.to_string() + }); + let mut work_products = FxHashMap::default(); let cgus = if tcx.sess.opts.output_types.should_codegen() { @@ -280,7 +296,7 @@ pub(super) fn run_aot( allocator_module, metadata_module, metadata, - windows_subsystem: None, // Windows is not yet supported + windows_subsystem, linker_info: LinkerInfo::new(tcx), crate_info: CrateInfo::new(tcx), }, From 4ca3384db63fcc938b2ed58b9c6f42ef93442e47 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 15:33:47 +0100 Subject: [PATCH 10/51] Make it possible to enable the verifier in release mode --- .github/workflows/main.yml | 3 +++ docs/env_vars.md | 5 ++++- src/lib.rs | 6 +++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e06a1fb88bad8..3b29225f60107 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -65,6 +65,9 @@ jobs: export COMPILE_RUNS=2 export RUN_RUNS=2 + # Enable extra checks + export CG_CLIF_ENABLE_VERIFIER=1 + ./test.sh - name: Package prebuilt cg_clif diff --git a/docs/env_vars.md b/docs/env_vars.md index f0a0a6ad42ef5..f7fde1b4f3a87 100644 --- a/docs/env_vars.md +++ b/docs/env_vars.md @@ -8,5 +8,8 @@ to make it possible to use incremental mode for all analyses performed by rustc without caching object files when their content should have been changed by a change to cg_clif.
CG_CLIF_DISPLAY_CG_TIME
-
If "1", display the time it took to perform codegen for a crate
+
If "1", display the time it took to perform codegen for a crate.
+
CG_CLIF_ENABLE_VERIFIER
+
Enable the Cranelift ir verifier for all compilation passes. If not set it will only run once + before passing the clif ir to Cranelift for compilation. diff --git a/src/lib.rs b/src/lib.rs index 5db2499709a62..f38d943afbfe9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -299,9 +299,9 @@ fn build_isa(sess: &Session) -> Box { let mut flags_builder = settings::builder(); flags_builder.enable("is_pic").unwrap(); flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided - flags_builder - .set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" }) - .unwrap(); + let enable_verifier = + cfg!(debug_assertions) || std::env::var("CG_CLIF_ENABLE_VERIFIER").is_ok(); + flags_builder.set("enable_verifier", if enable_verifier { "true" } else { "false" }).unwrap(); let tls_model = match target_triple.binary_format { BinaryFormat::Elf => "elf_gd", From cecd7a9ae69689a884b4baf0a0c871a5b9eb1bb4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 18:45:04 +0100 Subject: [PATCH 11/51] Add clif comments when in release mode Fixes #1130 --- src/abi/comments.rs | 27 ++++++++---- src/abi/mod.rs | 19 +++------ src/abi/pass_mode.rs | 5 +-- src/abi/returning.rs | 4 -- src/base.rs | 11 ++--- src/common.rs | 3 +- src/constant.rs | 25 ++++++----- src/inline_asm.rs | 10 +++-- src/optimize/stack2reg.rs | 89 +++++++++++++++++++++------------------ src/pointer.rs | 3 +- src/pretty_clif.rs | 15 +++++-- src/trap.rs | 3 +- src/value_and_place.rs | 5 +-- 13 files changed, 117 insertions(+), 102 deletions(-) diff --git a/src/abi/comments.rs b/src/abi/comments.rs index c3cf90e1e70be..5fbaed7283a67 100644 --- a/src/abi/comments.rs +++ b/src/abi/comments.rs @@ -11,9 +11,11 @@ use cranelift_codegen::entity::EntityRef; use crate::prelude::*; pub(super) fn add_args_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { - fx.add_global_comment( - "kind loc.idx param pass mode ty".to_string(), - ); + if fx.clif_comments.enabled() { + fx.add_global_comment( + "kind loc.idx param pass mode ty".to_string(), + ); + } } pub(super) fn add_arg_comment<'tcx>( @@ -25,6 +27,10 @@ pub(super) fn add_arg_comment<'tcx>( arg_abi_mode: PassMode, arg_layout: TyAndLayout<'tcx>, ) { + if !fx.clif_comments.enabled() { + return; + } + let local = if let Some(local) = local { Cow::Owned(format!("{:?}", local)) } else { @@ -59,10 +65,12 @@ pub(super) fn add_arg_comment<'tcx>( } pub(super) fn add_locals_header_comment(fx: &mut FunctionCx<'_, '_, '_>) { - fx.add_global_comment(String::new()); - fx.add_global_comment( - "kind local ty size align (abi,pref)".to_string(), - ); + if fx.clif_comments.enabled() { + fx.add_global_comment(String::new()); + fx.add_global_comment( + "kind local ty size align (abi,pref)".to_string(), + ); + } } pub(super) fn add_local_place_comments<'tcx>( @@ -70,6 +78,9 @@ pub(super) fn add_local_place_comments<'tcx>( place: CPlace<'tcx>, local: Local, ) { + if !fx.clif_comments.enabled() { + return; + } let TyAndLayout { ty, layout } = place.layout(); let rustc_target::abi::Layout { size, align, abi: _, variants: _, fields: _, largest_niche: _ } = layout; @@ -90,7 +101,7 @@ pub(super) fn add_local_place_comments<'tcx>( } else { Cow::Borrowed("") }; - match ptr.base_and_offset() { + match ptr.debug_base_and_offset() { (crate::pointer::PointerBase::Addr(addr), offset) => { ("reuse", format!("storage={}{}{}", addr, offset, meta).into()) } diff --git a/src/abi/mod.rs b/src/abi/mod.rs index c79889f8ca1da..2328d40111a3d 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -1,6 +1,5 @@ //! Handling of everything related to the calling convention. Also fills `fx.local_map`. -#[cfg(debug_assertions)] mod comments; mod pass_mode; mod returning; @@ -75,8 +74,9 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let func_id = import_function(self.tcx, self.cx.module, inst); let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); - #[cfg(debug_assertions)] - self.add_comment(func_ref, format!("{:?}", inst)); + if self.clif_comments.enabled() { + self.add_comment(func_ref, format!("{:?}", inst)); + } func_ref } @@ -92,8 +92,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let func_id = self.cx.module.declare_function(&name, Linkage::Import, &sig).unwrap(); let func_ref = self.cx.module.declare_func_in_func(func_id, &mut self.bcx.func); let call_inst = self.bcx.ins().call(func_ref, args); - #[cfg(debug_assertions)] - { + if self.clif_comments.enabled() { self.add_comment(call_inst, format!("easy_call {}", name)); } let results = self.bcx.inst_results(call_inst); @@ -149,7 +148,6 @@ fn make_local_place<'tcx>( CPlace::new_stack_slot(fx, layout) }; - #[cfg(debug_assertions)] self::comments::add_local_place_comments(fx, place, local); place @@ -163,7 +161,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ let ssa_analyzed = crate::analyze::analyze(fx); - #[cfg(debug_assertions)] self::comments::add_args_header_comment(fx); let mut block_params_iter = fx.bcx.func.dfg.block_params(start_block).to_vec().into_iter(); @@ -228,7 +225,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ fx.fn_abi = Some(fn_abi); assert!(block_params_iter.next().is_none(), "arg_value left behind"); - #[cfg(debug_assertions)] self::comments::add_locals_header_comment(fx); for (local, arg_kind, ty) in func_params { @@ -256,7 +252,6 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ CPlace::for_ptr(addr, val.layout()) }; - #[cfg(debug_assertions)] self::comments::add_local_place_comments(fx, place, local); assert_eq!(fx.local_map.push(place), local); @@ -392,8 +387,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( let (func_ref, first_arg) = match instance { // Trait object call Some(Instance { def: InstanceDef::Virtual(_, idx), .. }) => { - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { let nop_inst = fx.bcx.ins().nop(); fx.add_comment( nop_inst, @@ -414,8 +408,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // Indirect call None => { - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { let nop_inst = fx.bcx.ins().nop(); fx.add_comment(nop_inst, "indirect call"); } diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index d58f952f53c1a..06b52168e6533 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -248,8 +248,8 @@ pub(super) fn adjust_arg_for_abi<'tcx>( /// as necessary. pub(super) fn cvalue_for_param<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] local: Option, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] local_field: Option, + local: Option, + local_field: Option, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>, block_params_iter: &mut impl Iterator, ) -> Option> { @@ -263,7 +263,6 @@ pub(super) fn cvalue_for_param<'tcx>( }) .collect::>(); - #[cfg(debug_assertions)] crate::abi::comments::add_arg_comment( fx, "arg", diff --git a/src/abi/returning.rs b/src/abi/returning.rs index 9fa066df69b3c..b68c3a053b392 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -84,10 +84,6 @@ pub(super) fn codegen_return_param<'tcx>( } }; - #[cfg(not(debug_assertions))] - let _ = ret_param; - - #[cfg(debug_assertions)] crate::abi::comments::add_arg_comment( fx, "ret", diff --git a/src/base.rs b/src/base.rs index 0a7734d6a0443..76425309ed5f9 100644 --- a/src/base.rs +++ b/src/base.rs @@ -219,8 +219,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) { codegen_stmt(fx, block, stmt); } - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { let mut terminator_head = "\n".to_string(); bb_data.terminator().kind.fmt_head(&mut terminator_head).unwrap(); let inst = fx.bcx.func.layout.last_inst(block).unwrap(); @@ -433,12 +432,14 @@ fn codegen_stmt<'tcx>( fx.set_debug_loc(stmt.source_info); - #[cfg(false_debug_assertions)] + #[cfg(disabled)] match &stmt.kind { StatementKind::StorageLive(..) | StatementKind::StorageDead(..) => {} // Those are not very useful _ => { - let inst = fx.bcx.func.layout.last_inst(cur_block).unwrap(); - fx.add_comment(inst, format!("{:?}", stmt)); + if fx.clif_comments.enabled() { + let inst = fx.bcx.func.layout.last_inst(cur_block).unwrap(); + fx.add_comment(inst, format!("{:?}", stmt)); + } } } diff --git a/src/common.rs b/src/common.rs index 6a4a6744a5cf7..b5874f62535ca 100644 --- a/src/common.rs +++ b/src/common.rs @@ -361,8 +361,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { let _ = self.cx.module.define_data(msg_id, &data_ctx); let local_msg_id = self.cx.module.declare_data_in_func(msg_id, self.bcx.func); - #[cfg(debug_assertions)] - { + if self.clif_comments.enabled() { self.add_comment(local_msg_id, msg); } self.bcx.ins().global_value(self.pointer_type, local_msg_id) diff --git a/src/constant.rs b/src/constant.rs index b0639cf9e15fe..2f0687b0364db 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -82,8 +82,9 @@ pub(crate) fn codegen_tls_ref<'tcx>( ) -> CValue<'tcx> { let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("tls {:?}", def_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("tls {:?}", def_id)); + } let tls_ptr = fx.bcx.ins().tls_value(fx.pointer_type, local_data_id); CValue::by_val(tls_ptr, layout) } @@ -95,8 +96,9 @@ fn codegen_static_ref<'tcx>( ) -> CPlace<'tcx> { let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", def_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", def_id)); + } let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); assert!(!layout.is_unsized(), "unsized statics aren't supported"); assert!( @@ -182,8 +184,9 @@ pub(crate) fn codegen_const_value<'tcx>( data_id_for_alloc_id(fx.cx.module, ptr.alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", ptr.alloc_id)); + } fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } Some(GlobalAlloc::Function(instance)) => { @@ -198,8 +201,9 @@ pub(crate) fn codegen_const_value<'tcx>( let data_id = data_id_for_static(fx.tcx, fx.cx.module, def_id, false); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", def_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", def_id)); + } fx.bcx.ins().global_value(fx.pointer_type, local_data_id) } None => bug!("missing allocation {:?}", ptr.alloc_id), @@ -240,8 +244,9 @@ fn pointer_for_allocation<'tcx>( let data_id = data_id_for_alloc_id(fx.cx.module, alloc_id, alloc.mutability); let local_data_id = fx.cx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("{:?}", alloc_id)); + } let global_ptr = fx.bcx.ins().global_value(fx.pointer_type, local_data_id); crate::pointer::Pointer::new(global_ptr) } diff --git a/src/inline_asm.rs b/src/inline_asm.rs index 33234f820aa8f..1fb5e86aed7df 100644 --- a/src/inline_asm.rs +++ b/src/inline_asm.rs @@ -197,8 +197,9 @@ fn call_inline_asm<'tcx>( offset: None, size: u32::try_from(slot_size.bytes()).unwrap(), }); - #[cfg(debug_assertions)] - fx.add_comment(stack_slot, "inline asm scratch slot"); + if fx.clif_comments.enabled() { + fx.add_comment(stack_slot, "inline asm scratch slot"); + } let inline_asm_func = fx .cx @@ -214,8 +215,9 @@ fn call_inline_asm<'tcx>( ) .unwrap(); let inline_asm_func = fx.cx.module.declare_func_in_func(inline_asm_func, &mut fx.bcx.func); - #[cfg(debug_assertions)] - fx.add_comment(inline_asm_func, asm_name); + if fx.clif_comments.enabled() { + fx.add_comment(inline_asm_func, asm_name); + } for (_reg, offset, value) in inputs { fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap()); diff --git a/src/optimize/stack2reg.rs b/src/optimize/stack2reg.rs index d111f37f5e455..8bb02a3e55854 100644 --- a/src/optimize/stack2reg.rs +++ b/src/optimize/stack2reg.rs @@ -181,7 +181,6 @@ impl<'a> OptimizeContext<'a> { pub(super) fn optimize_function( ctx: &mut Context, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] clif_comments: &mut crate::pretty_clif::CommentWriter, ) { combine_stack_addr_with_load_store(&mut ctx.func); @@ -192,8 +191,7 @@ pub(super) fn optimize_function( remove_unused_stack_addr_and_stack_load(&mut opt_ctx); - #[cfg(debug_assertions)] - { + if clif_comments.enabled() { for (&OrdStackSlot(stack_slot), usage) in &opt_ctx.stack_slot_usage_map { clif_comments.add_comment(stack_slot, format!("used by: {:?}", usage)); } @@ -209,25 +207,27 @@ pub(super) fn optimize_function( for load in users.stack_load.clone().into_iter() { let potential_stores = users.potential_stores_for_load(&opt_ctx.ctx, load); - #[cfg(debug_assertions)] - for &store in &potential_stores { - clif_comments.add_comment( - load, - format!( - "Potential store -> load forwarding {} -> {} ({:?}, {:?})", - opt_ctx.ctx.func.dfg.display_inst(store, None), - opt_ctx.ctx.func.dfg.display_inst(load, None), - spatial_overlap(&opt_ctx.ctx.func, store, load), - temporal_order(&opt_ctx.ctx, store, load), - ), - ); + if clif_comments.enabled() { + for &store in &potential_stores { + clif_comments.add_comment( + load, + format!( + "Potential store -> load forwarding {} -> {} ({:?}, {:?})", + opt_ctx.ctx.func.dfg.display_inst(store, None), + opt_ctx.ctx.func.dfg.display_inst(load, None), + spatial_overlap(&opt_ctx.ctx.func, store, load), + temporal_order(&opt_ctx.ctx, store, load), + ), + ); + } } match *potential_stores { [] => { - #[cfg(debug_assertions)] - clif_comments - .add_comment(load, "[BUG?] Reading uninitialized memory".to_string()); + if clif_comments.enabled() { + clif_comments + .add_comment(load, "[BUG?] Reading uninitialized memory".to_string()); + } } [store] if spatial_overlap(&opt_ctx.ctx.func, store, load) == SpatialOverlap::Full @@ -237,9 +237,12 @@ pub(super) fn optimize_function( // Only one store could have been the origin of the value. let stored_value = opt_ctx.ctx.func.dfg.inst_args(store)[0]; - #[cfg(debug_assertions)] - clif_comments - .add_comment(load, format!("Store to load forward {} -> {}", store, load)); + if clif_comments.enabled() { + clif_comments.add_comment( + load, + format!("Store to load forward {} -> {}", store, load), + ); + } users.change_load_to_alias(&mut opt_ctx.ctx.func, load, stored_value); } @@ -250,33 +253,35 @@ pub(super) fn optimize_function( for store in users.stack_store.clone().into_iter() { let potential_loads = users.potential_loads_of_store(&opt_ctx.ctx, store); - #[cfg(debug_assertions)] - for &load in &potential_loads { - clif_comments.add_comment( - store, - format!( - "Potential load from store {} <- {} ({:?}, {:?})", - opt_ctx.ctx.func.dfg.display_inst(load, None), - opt_ctx.ctx.func.dfg.display_inst(store, None), - spatial_overlap(&opt_ctx.ctx.func, store, load), - temporal_order(&opt_ctx.ctx, store, load), - ), - ); + if clif_comments.enabled() { + for &load in &potential_loads { + clif_comments.add_comment( + store, + format!( + "Potential load from store {} <- {} ({:?}, {:?})", + opt_ctx.ctx.func.dfg.display_inst(load, None), + opt_ctx.ctx.func.dfg.display_inst(store, None), + spatial_overlap(&opt_ctx.ctx.func, store, load), + temporal_order(&opt_ctx.ctx, store, load), + ), + ); + } } if potential_loads.is_empty() { // Never loaded; can safely remove all stores and the stack slot. // FIXME also remove stores when there is always a next store before a load. - #[cfg(debug_assertions)] - clif_comments.add_comment( - store, - format!( - "Remove dead stack store {} of {}", - opt_ctx.ctx.func.dfg.display_inst(store, None), - stack_slot.0 - ), - ); + if clif_comments.enabled() { + clif_comments.add_comment( + store, + format!( + "Remove dead stack store {} of {}", + opt_ctx.ctx.func.dfg.display_inst(store, None), + stack_slot.0 + ), + ); + } users.remove_dead_store(&mut opt_ctx.ctx.func, store); } diff --git a/src/pointer.rs b/src/pointer.rs index 88a78f3214d87..31d827f83bfab 100644 --- a/src/pointer.rs +++ b/src/pointer.rs @@ -39,8 +39,7 @@ impl Pointer { Pointer { base: PointerBase::Dangling(align), offset: Offset32::new(0) } } - #[cfg(debug_assertions)] - pub(crate) fn base_and_offset(self) -> (PointerBase, Offset32) { + pub(crate) fn debug_base_and_offset(self) -> (PointerBase, Offset32) { (self.base, self.offset) } diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 9c91b92e515b1..87f0e0c3738d7 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -69,13 +69,15 @@ use crate::prelude::*; #[derive(Debug)] pub(crate) struct CommentWriter { + enabled: bool, global_comments: Vec, entity_comments: FxHashMap, } impl CommentWriter { pub(crate) fn new<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> Self { - let global_comments = if cfg!(debug_assertions) { + let enabled = should_write_ir(tcx); + let global_comments = if enabled { vec![ format!("symbol {}", tcx.symbol_name(instance).name), format!("instance {:?}", instance), @@ -86,13 +88,17 @@ impl CommentWriter { vec![] }; - CommentWriter { global_comments, entity_comments: FxHashMap::default() } + CommentWriter { enabled, global_comments, entity_comments: FxHashMap::default() } } } -#[cfg(debug_assertions)] impl CommentWriter { + pub(crate) fn enabled(&self) -> bool { + self.enabled + } + pub(crate) fn add_global_comment>(&mut self, comment: S) { + debug_assert!(self.enabled); self.global_comments.push(comment.into()); } @@ -101,6 +107,8 @@ impl CommentWriter { entity: E, comment: S, ) { + debug_assert!(self.enabled); + use std::collections::hash_map::Entry; match self.entity_comments.entry(entity.into()) { Entry::Occupied(mut occ) => { @@ -179,7 +187,6 @@ impl FuncWriter for &'_ CommentWriter { } } -#[cfg(debug_assertions)] impl FunctionCx<'_, '_, '_> { pub(crate) fn add_global_comment>(&mut self, comment: S) { self.clif_comments.add_global_comment(comment); diff --git a/src/trap.rs b/src/trap.rs index bb63d72addf98..1ab0703e981e7 100644 --- a/src/trap.rs +++ b/src/trap.rs @@ -17,8 +17,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) { ) .unwrap(); let puts = fx.cx.module.declare_func_in_func(puts, &mut fx.bcx.func); - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { fx.add_comment(puts, "puts"); } diff --git a/src/value_and_place.rs b/src/value_and_place.rs index c2c59773848cb..1a6a301a45bbd 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -413,7 +413,7 @@ impl<'tcx> CPlace<'tcx> { self, fx: &mut FunctionCx<'_, '_, 'tcx>, from: CValue<'tcx>, - #[cfg_attr(not(debug_assertions), allow(unused_variables))] method: &'static str, + method: &'static str, ) { fn transmute_value<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, @@ -461,8 +461,7 @@ impl<'tcx> CPlace<'tcx> { assert_eq!(self.layout().size, from.layout().size); - #[cfg(debug_assertions)] - { + if fx.clif_comments.enabled() { use cranelift_codegen::cursor::{Cursor, CursorPosition}; let cur_block = match fx.bcx.cursor().position() { CursorPosition::After(block) => block, From d194c707c82198864cd1493a9e104f904d354e16 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 18:59:01 +0100 Subject: [PATCH 12/51] Use jemalloc --- Cargo.toml | 3 ++- src/bin/cg_clif.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9861af1f8eae2..79c9b57532d66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,9 +35,10 @@ smallvec = "1.6.1" #gimli = { path = "../" } [features] -default = ["jit", "inline_asm"] +default = ["jit", "inline_asm", "jemalloc"] jit = ["cranelift-jit", "libloading"] inline_asm = [] +jemalloc = [] [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs index 983839d48d2d7..b8d6958b3b251 100644 --- a/src/bin/cg_clif.rs +++ b/src/bin/cg_clif.rs @@ -1,5 +1,7 @@ #![feature(rustc_private)] +#[cfg(feature = "jemalloc")] +extern crate jemalloc_sys; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_interface; @@ -33,6 +35,46 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { } fn main() { + // Pull in jemalloc when enabled. + // + // Note that we're pulling in a static copy of jemalloc which means that to + // pull it in we need to actually reference its symbols for it to get + // linked. The two crates we link to here, std and rustc_driver, are both + // dynamic libraries. That means to pull in jemalloc we need to actually + // reference allocation symbols one way or another (as this file is the only + // object code in the rustc executable). + #[cfg(feature = "jemalloc")] + { + use std::os::raw::{c_int, c_void}; + #[used] + static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; + #[used] + static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = + jemalloc_sys::posix_memalign; + #[used] + static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; + #[used] + static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; + #[used] + static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; + #[used] + static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; + + // On OSX, jemalloc doesn't directly override malloc/free, but instead + // registers itself with the allocator's zone APIs in a ctor. However, + // the linker doesn't seem to consider ctors as "used" when statically + // linking, so we need to explicitly depend on the function. + #[cfg(target_os = "macos")] + { + extern "C" { + fn _rjem_je_zone_register(); + } + + #[used] + static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; + } + } + let start_time = std::time::Instant::now(); let start_rss = get_resident_set_size(); rustc_driver::init_rustc_env_logger(); From 76bb1f173f35c4d0fa4de6c7d4651a1367e61bdb Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:19:29 +0100 Subject: [PATCH 13/51] Move the more advanced ways to use cg_clif to usage.md --- Readme.md | 59 ++++----------------------------------------- docs/usage.md | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 55 deletions(-) create mode 100644 docs/usage.md diff --git a/Readme.md b/Readme.md index 6fa5eebdc2f3d..6848ce7809088 100644 --- a/Readme.md +++ b/Readme.md @@ -34,70 +34,19 @@ rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo bui Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`). -### Cargo - In the directory with your project (where you can do the usual `cargo build`), run: ```bash -$ $cg_clif_dir/build/cargo.sh run -``` - -This should build and run your project with rustc_codegen_cranelift instead of the usual LLVM backend. - -### Rustc - -> You should prefer using the Cargo method. - -```bash -$ $cg_clif_dir/build/bin/cg_clif my_crate.rs -``` - -### Jit mode - -In jit mode cg_clif will immediately execute your code without creating an executable file. - -> This requires all dependencies to be available as dynamic library. -> The jit mode will probably need cargo integration to make this possible. - -```bash -$ $cg_clif_dir/build/cargo.sh jit +$ $cg_clif_dir/build/cargo.sh build ``` -or +This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. -```bash -$ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs -``` - -There is also an experimental lazy jit mode. In this mode functions are only compiled once they are -first called. It currently does not work with multi-threaded programs. When a not yet compiled -function is called from another thread than the main thread, you will get an ICE. - -```bash -$ $cg_clif_dir/build/cargo.sh lazy-jit -``` - -### Shell - -These are a few functions that allow you to easily run rust code from the shell using cg_clif as jit. - -```bash -function jit_naked() { - echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Cllvm-args=mode=jit -Cprefer-dynamic -} - -function jit() { - jit_naked "fn main() { $@ }" -} - -function jit_calc() { - jit 'println!("0x{:x}", ' $@ ');'; -} -``` +For additional ways to use rustc_codegen_cranelift like the JIT mode see [full_usage.md](docs/full_usage.md). ## Env vars -[see env_vars.md](docs/env_vars.md) +See [env_vars.md](docs/env_vars.md) for all env vars used by rustc_codegen_cranelift. ## Not yet supported diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000000000..defe16ab3af09 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,66 @@ +# Usage + +rustc_codegen_cranelift can be used as a near-drop-in replacement for `cargo build` or `cargo run` for existing projects. + +Assuming `$cg_clif_dir` is the directory you cloned this repo into and you followed the instructions (`prepare.sh` and `build.sh` or `test.sh`). + +## Cargo + +In the directory with your project (where you can do the usual `cargo build`), run: + +```bash +$ $cg_clif_dir/build/cargo.sh build +``` + +This will build and run your project with rustc_codegen_cranelift instead of the usual LLVM backend. + +## Rustc + +> You should prefer using the Cargo method. + +```bash +$ $cg_clif_dir/build/bin/cg_clif my_crate.rs +``` + +## Jit mode + +In jit mode cg_clif will immediately execute your code without creating an executable file. + +> This requires all dependencies to be available as dynamic library. +> The jit mode will probably need cargo integration to make this possible. + +```bash +$ $cg_clif_dir/build/cargo.sh jit +``` + +or + +```bash +$ $cg_clif_dir/build/bin/cg_clif -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs +``` + +There is also an experimental lazy jit mode. In this mode functions are only compiled once they are +first called. It currently does not work with multi-threaded programs. When a not yet compiled +function is called from another thread than the main thread, you will get an ICE. + +```bash +$ $cg_clif_dir/build/cargo.sh lazy-jit +``` + +## Shell + +These are a few functions that allow you to easily run rust code from the shell using cg_clif as jit. + +```bash +function jit_naked() { + echo "$@" | $cg_clif_dir/build/bin/cg_clif - -Cllvm-args=mode=jit -Cprefer-dynamic +} + +function jit() { + jit_naked "fn main() { $@ }" +} + +function jit_calc() { + jit 'println!("0x{:x}", ' $@ ');'; +} +``` From be3aa0689e7c5e58b1d8daa2e2b2ba90d5eccc46 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:21:30 +0100 Subject: [PATCH 14/51] Revert "Use jemalloc" This reverts commit d194c707c82198864cd1493a9e104f904d354e16. It fails the bootstrap test as jemalloc_sys is not built --- Cargo.toml | 3 +-- src/bin/cg_clif.rs | 42 ------------------------------------------ 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 79c9b57532d66..9861af1f8eae2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,10 +35,9 @@ smallvec = "1.6.1" #gimli = { path = "../" } [features] -default = ["jit", "inline_asm", "jemalloc"] +default = ["jit", "inline_asm"] jit = ["cranelift-jit", "libloading"] inline_asm = [] -jemalloc = [] [profile.dev] # By compiling dependencies with optimizations, performing tests gets much faster. diff --git a/src/bin/cg_clif.rs b/src/bin/cg_clif.rs index b8d6958b3b251..983839d48d2d7 100644 --- a/src/bin/cg_clif.rs +++ b/src/bin/cg_clif.rs @@ -1,7 +1,5 @@ #![feature(rustc_private)] -#[cfg(feature = "jemalloc")] -extern crate jemalloc_sys; extern crate rustc_data_structures; extern crate rustc_driver; extern crate rustc_interface; @@ -35,46 +33,6 @@ impl rustc_driver::Callbacks for CraneliftPassesCallbacks { } fn main() { - // Pull in jemalloc when enabled. - // - // Note that we're pulling in a static copy of jemalloc which means that to - // pull it in we need to actually reference its symbols for it to get - // linked. The two crates we link to here, std and rustc_driver, are both - // dynamic libraries. That means to pull in jemalloc we need to actually - // reference allocation symbols one way or another (as this file is the only - // object code in the rustc executable). - #[cfg(feature = "jemalloc")] - { - use std::os::raw::{c_int, c_void}; - #[used] - static _F1: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::calloc; - #[used] - static _F2: unsafe extern "C" fn(*mut *mut c_void, usize, usize) -> c_int = - jemalloc_sys::posix_memalign; - #[used] - static _F3: unsafe extern "C" fn(usize, usize) -> *mut c_void = jemalloc_sys::aligned_alloc; - #[used] - static _F4: unsafe extern "C" fn(usize) -> *mut c_void = jemalloc_sys::malloc; - #[used] - static _F5: unsafe extern "C" fn(*mut c_void, usize) -> *mut c_void = jemalloc_sys::realloc; - #[used] - static _F6: unsafe extern "C" fn(*mut c_void) = jemalloc_sys::free; - - // On OSX, jemalloc doesn't directly override malloc/free, but instead - // registers itself with the allocator's zone APIs in a ctor. However, - // the linker doesn't seem to consider ctors as "used" when statically - // linking, so we need to explicitly depend on the function. - #[cfg(target_os = "macos")] - { - extern "C" { - fn _rjem_je_zone_register(); - } - - #[used] - static _F7: unsafe extern "C" fn() = _rjem_je_zone_register; - } - } - let start_time = std::time::Instant::now(); let start_rss = get_resident_set_size(); rustc_driver::init_rustc_env_logger(); From 95e4db3e0338ce88b724b41a19ce0fc9d2ed1395 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:22:36 +0100 Subject: [PATCH 15/51] More doc fixes --- Readme.md | 2 +- docs/usage.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 6848ce7809088..86e62f74478a6 100644 --- a/Readme.md +++ b/Readme.md @@ -42,7 +42,7 @@ $ $cg_clif_dir/build/cargo.sh build This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. -For additional ways to use rustc_codegen_cranelift like the JIT mode see [full_usage.md](docs/full_usage.md). +For additional ways to use rustc_codegen_cranelift like the JIT mode see [usage.md](docs/usage.md). ## Env vars diff --git a/docs/usage.md b/docs/usage.md index defe16ab3af09..3eee3b554e3b6 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -12,7 +12,7 @@ In the directory with your project (where you can do the usual `cargo build`), r $ $cg_clif_dir/build/cargo.sh build ``` -This will build and run your project with rustc_codegen_cranelift instead of the usual LLVM backend. +This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend. ## Rustc From 05339134de9d3977002752b79b5f280f33ab1993 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 6 Mar 2021 19:26:11 +0100 Subject: [PATCH 16/51] Add license section to the readme Just in case --- Readme.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Readme.md b/Readme.md index 86e62f74478a6..ffe1d9a1e6580 100644 --- a/Readme.md +++ b/Readme.md @@ -55,3 +55,20 @@ See [env_vars.md](docs/env_vars.md) for all env vars used by rustc_codegen_crane `llvm_asm!` will remain unimplemented forever. `asm!` doesn't yet support reg classes. You have to specify specific registers instead. * SIMD ([tracked here](https://github.com/bjorn3/rustc_codegen_cranelift/issues/171), some basic things work) + +## License + +Licensed under either of + + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or + http://www.apache.org/licenses/LICENSE-2.0) + * MIT license ([LICENSE-MIT](LICENSE-MIT) or + http://opensource.org/licenses/MIT) + +at your option. + +### Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you shall be dual licensed as above, without any +additional terms or conditions. From 341a4863fabe8c67b1b72c6d3183ee824878f950 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 27 Nov 2020 16:52:17 +0100 Subject: [PATCH 17/51] Use the new component dependency option of the rust-toolchain file (take 2) --- prepare.sh | 1 - rust-toolchain | 4 +++- scripts/cargo.sh | 2 +- scripts/rustup.sh | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/prepare.sh b/prepare.sh index ee995ffcfa9f7..64c097261c908 100755 --- a/prepare.sh +++ b/prepare.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash set -e -rustup component add rust-src rustc-dev llvm-tools-preview ./build_sysroot/prepare_sysroot_src.sh cargo install hyperfine || echo "Skipping hyperfine install" diff --git a/rust-toolchain b/rust-toolchain index 908ca52135b66..495d8ea77347e 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1,3 @@ -nightly-2021-03-05 +[toolchain] +channel = "nightly-2021-03-05" +components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/scripts/cargo.sh b/scripts/cargo.sh index 669d2d45b71b5..1daa5a78f7bd2 100755 --- a/scripts/cargo.sh +++ b/scripts/cargo.sh @@ -4,7 +4,7 @@ dir=$(dirname "$0") source "$dir/config.sh" # read nightly compiler from rust-toolchain file -TOOLCHAIN=$(cat "$dir/rust-toolchain") +TOOLCHAIN=$(cat "$dir/rust-toolchain" | grep channel | sed "s/channel = \"\(.*\)\"/\1/") cmd=$1 shift || true diff --git a/scripts/rustup.sh b/scripts/rustup.sh index 694945a87c268..fa7557653d879 100755 --- a/scripts/rustup.sh +++ b/scripts/rustup.sh @@ -8,7 +8,7 @@ case $1 in echo "=> Installing new nightly" rustup toolchain install --profile minimal "nightly-${TOOLCHAIN}" # Sanity check to see if the nightly exists - echo "nightly-${TOOLCHAIN}" > rust-toolchain + sed -i "s/\"nightly-.*\"/\"nightly-${TOOLCHAIN}\"/" rust-toolchain rustup component add rustfmt || true echo "=> Uninstalling all old nighlies" From 8f62149d071ad1a42deef3bd67c9a414d73559f8 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 10:16:43 +0100 Subject: [PATCH 18/51] Rustup to rustc 1.52.0-nightly (8f349be27 2021-03-08) --- build_sysroot/Cargo.lock | 12 ++++++------ rust-toolchain | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index a7650ab995b0f..cd0526b0129a0 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -16,9 +16,9 @@ dependencies = [ [[package]] name = "adler" -version = "0.2.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" dependencies = [ "compiler_builtins", "rustc-std-workspace-core", @@ -132,18 +132,18 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.86" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c" +checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" dependencies = [ "rustc-std-workspace-core", ] [[package]] name = "miniz_oxide" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" dependencies = [ "adler", "autocfg", diff --git a/rust-toolchain b/rust-toolchain index 495d8ea77347e..d00e2bee74656 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-05" +channel = "nightly-2021-03-09" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From 826189ef51c4f0ad5f6e10d44cf8e9e7a229891e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 12:37:39 +0100 Subject: [PATCH 19/51] Some clippy fixes --- src/abi/pass_mode.rs | 2 +- src/abi/returning.rs | 2 +- src/debuginfo/line_info.rs | 4 ++-- src/intrinsics/simd.rs | 2 +- src/lib.rs | 8 +++----- src/num.rs | 6 +++--- src/pretty_clif.rs | 4 ++-- 7 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 06b52168e6533..7c275965199e0 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -208,7 +208,7 @@ pub(super) fn from_casted_value<'tcx>( }); let ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0)); let mut offset = 0; - let mut block_params_iter = block_params.into_iter().copied(); + let mut block_params_iter = block_params.iter().copied(); for param in abi_params { let val = ptr.offset_i64(fx, offset).store( fx, diff --git a/src/abi/returning.rs b/src/abi/returning.rs index b68c3a053b392..e1c53224b4f84 100644 --- a/src/abi/returning.rs +++ b/src/abi/returning.rs @@ -142,7 +142,7 @@ pub(super) fn codegen_with_call_return_arg<'tcx, T>( let results = fx .bcx .inst_results(call_inst) - .into_iter() + .iter() .copied() .collect::>(); let result = diff --git a/src/debuginfo/line_info.rs b/src/debuginfo/line_info.rs index 30ed356c7627f..8578ab33ced68 100644 --- a/src/debuginfo/line_info.rs +++ b/src/debuginfo/line_info.rs @@ -39,11 +39,11 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] { #[cfg(unix)] { use std::os::unix::ffi::OsStrExt; - return path.as_bytes(); + path.as_bytes() } #[cfg(not(unix))] { - return path.to_str().unwrap().as_bytes(); + path.to_str().unwrap().as_bytes() } } diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 1f8eeb1e71491..337f4d6766afa 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -88,7 +88,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( let idx_bytes = match idx_const.val { ty::ConstKind::Value(ConstValue::ByRef { alloc, offset }) => { let ptr = Pointer::new(AllocId(0 /* dummy */), offset); - let size = Size::from_bytes(4 * u64::from(ret_lane_count) /* size_of([u32; ret_lane_count]) */); + let size = Size::from_bytes(4 * ret_lane_count /* size_of([u32; ret_lane_count]) */); alloc.get_bytes(fx, ptr, size).unwrap() } _ => unreachable!("{:?}", idx_const), diff --git a/src/lib.rs b/src/lib.rs index c07b33cc83c82..650e5e04bdbd5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -240,9 +240,9 @@ impl CodegenBackend for CraneliftCodegenBackend { vec![] } - fn codegen_crate<'tcx>( + fn codegen_crate( &self, - tcx: TyCtxt<'tcx>, + tcx: TyCtxt<'_>, metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box { @@ -252,9 +252,7 @@ impl CodegenBackend for CraneliftCodegenBackend { BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args) .unwrap_or_else(|err| tcx.sess.fatal(&err)) }; - let res = driver::codegen_crate(tcx, metadata, need_metadata_module, config); - - res + driver::codegen_crate(tcx, metadata, need_metadata_module, config) } fn join_codegen( diff --git a/src/num.rs b/src/num.rs index da49e1c6c91db..9ee564a9a5413 100644 --- a/src/num.rs +++ b/src/num.rs @@ -387,7 +387,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>( let lhs = in_lhs.load_scalar(fx); let rhs = in_rhs.load_scalar(fx); - return codegen_compare_bin_op(fx, bin_op, false, lhs, rhs); + codegen_compare_bin_op(fx, bin_op, false, lhs, rhs) } BinOp::Offset => { let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty; @@ -396,10 +396,10 @@ pub(crate) fn codegen_ptr_binop<'tcx>( let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64); let base_val = base.load_scalar(fx); let res = fx.bcx.ins().iadd(base_val, ptr_diff); - return CValue::by_val(res, base.layout()); + CValue::by_val(res, base.layout()) } _ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs), - }; + } } else { let (lhs_ptr, lhs_extra) = in_lhs.load_scalar_pair(fx); let (rhs_ptr, rhs_extra) = in_rhs.load_scalar_pair(fx); diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 87f0e0c3738d7..855a0cc8e4a16 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -205,8 +205,8 @@ pub(crate) fn should_write_ir(tcx: TyCtxt<'_>) -> bool { tcx.sess.opts.output_types.contains_key(&OutputType::LlvmAssembly) } -pub(crate) fn write_ir_file<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn write_ir_file( + tcx: TyCtxt<'_>, name: &str, write: impl FnOnce(&mut dyn Write) -> std::io::Result<()>, ) { From 9adb1393563f4bfa1a035e7de4018a3cec249f50 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 12:46:04 +0100 Subject: [PATCH 20/51] Add rustc_private=true to the package metadata for rust-analyzer --- Cargo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 9861af1f8eae2..e51714b56d70d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,3 +75,6 @@ debug = false [profile.release.package.syn] opt-level = 0 debug = false + +[package.metadata.rust-analyzer] +rustc_private = true From eefe1ede8222867558e115dfeceee44104806f29 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 12:52:43 +0100 Subject: [PATCH 21/51] Update config name for latest rust-analyzer --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index a13d5931ffa89..0cd576e160f86 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ // source for rustc_* is not included in the rust-src component; disable the errors about this "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "macro-error"], "rust-analyzer.assist.importMergeBehavior": "last", - "rust-analyzer.cargo.loadOutDirsFromCheck": true, + "rust-analyzer.cargo.runBuildScripts": true, "rust-analyzer.linkedProjects": [ "./Cargo.toml", //"./build_sysroot/sysroot_src/src/libstd/Cargo.toml", From 871874817b06bc066ff14fadcbec80fd85bfb2ed Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 16:30:31 +0100 Subject: [PATCH 22/51] Lower GHA timeout to 60 min --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3b29225f60107..2ac516381cf7a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,6 +7,7 @@ on: jobs: build: runs-on: ${{ matrix.os }} + timeout-minutes: 60 strategy: fail-fast: false From 6b58ed225ec0d5048ab188ef68e47c07bc8547e9 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Tue, 9 Mar 2021 16:45:55 +0100 Subject: [PATCH 23/51] Adjust for changed -Zmir-opt-level numbering --- build_sysroot/build_sysroot.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_sysroot/build_sysroot.sh b/build_sysroot/build_sysroot.sh index 636aa5f3f3dc2..0354304e55bf7 100755 --- a/build_sysroot/build_sysroot.sh +++ b/build_sysroot/build_sysroot.sh @@ -28,7 +28,7 @@ export __CARGO_DEFAULT_LIB_METADATA="cg_clif" if [[ "$1" != "--debug" ]]; then sysroot_channel='release' # FIXME Enable incremental again once rust-lang/rust#74946 is fixed - CARGO_INCREMENTAL=0 RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=2" cargo build --target "$TARGET_TRIPLE" --release + CARGO_INCREMENTAL=0 RUSTFLAGS="$RUSTFLAGS -Zmir-opt-level=3" cargo build --target "$TARGET_TRIPLE" --release else sysroot_channel='debug' cargo build --target "$TARGET_TRIPLE" From 83e6251f21984764cac52d5d50408437dc000e57 Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 29 Dec 2020 02:00:04 +0000 Subject: [PATCH 24/51] Update cranelift --- src/base.rs | 10 ++++++++++ src/lib.rs | 1 + 2 files changed, 11 insertions(+) diff --git a/src/base.rs b/src/base.rs index f2c61c95f4ff2..ba7c82d24c517 100644 --- a/src/base.rs +++ b/src/base.rs @@ -832,6 +832,16 @@ fn codegen_stmt<'tcx>( } } StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), + StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { + src, + dst, + count, + }) => { + let dst = codegen_operand(fx, dst).load_scalar(fx); + let src = codegen_operand(fx, src).load_scalar(fx); + let count = codegen_operand(fx, count).load_scalar(fx); + fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, count); + } } } diff --git a/src/lib.rs b/src/lib.rs index 8edb883ccb5f9..fae71fef9e676 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,7 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] +#![feature(box_patterns)] extern crate snap; #[macro_use] From d30c497de6dc625012293efd29fa2f98a479947b Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 23 Jan 2021 03:55:41 +0000 Subject: [PATCH 25/51] Build StKind::CopyOverlapping This replaces where it was previously being constructed in intrinsics, with direct construction of the Statement. --- src/base.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/base.rs b/src/base.rs index ba7c82d24c517..8b5ae9e0541ad 100644 --- a/src/base.rs +++ b/src/base.rs @@ -837,10 +837,21 @@ fn codegen_stmt<'tcx>( dst, count, }) => { - let dst = codegen_operand(fx, dst).load_scalar(fx); + let dst = codegen_operand(fx, dst); + let pointee = dst + .layout() + .pointee_info_at(fx, rustc_target::abi::Size::ZERO) + .expect("Expected pointer"); + let dst = dst.load_scalar(fx); let src = codegen_operand(fx, src).load_scalar(fx); let count = codegen_operand(fx, count).load_scalar(fx); - fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, count); + let elem_size: u64 = pointee.size.bytes(); + let bytes = if elem_size != 1 { + fx.bcx.ins().imul_imm(count, elem_size as i64) + } else { + count + }; + fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes); } } } From d674d3dad89a4906e0473ed2717db391625732fa Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 26 Feb 2021 16:42:51 +0000 Subject: [PATCH 26/51] Clean up todos Also add some span_bugs where it is unreachable --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index fae71fef9e676..8edb883ccb5f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,7 +11,6 @@ #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] -#![feature(box_patterns)] extern crate snap; #[macro_use] From 95182bb2ccff3ba7cd4fe1e09488ab1fd6411244 Mon Sep 17 00:00:00 2001 From: "katelyn a. martin" Date: Thu, 27 Aug 2020 11:49:18 -0400 Subject: [PATCH 27/51] rustc_target: add "unwind" payloads to `Abi` ### Overview This commit begins the implementation work for RFC 2945. For more information, see the rendered RFC [1] and tracking issue [2]. A boolean `unwind` payload is added to the `C`, `System`, `Stdcall`, and `Thiscall` variants, marking whether unwinding across FFI boundaries is acceptable. The cases where each of these variants' `unwind` member is true correspond with the `C-unwind`, `system-unwind`, `stdcall-unwind`, and `thiscall-unwind` ABI strings introduced in RFC 2945 [3]. ### Feature Gate and Unstable Book This commit adds a `c_unwind` feature gate for the new ABI strings. Tests for this feature gate are included in `src/test/ui/c-unwind/`, which ensure that this feature gate works correctly for each of the new ABIs. A new language features entry in the unstable book is added as well. ### Further Work To Be Done This commit does not proceed to implement the new unwinding ABIs, and is intentionally scoped specifically to *defining* the ABIs and their feature flag. ### One Note on Test Churn This will lead to some test churn, in re-blessing hash tests, as the deleted comment in `src/librustc_target/spec/abi.rs` mentioned, because we can no longer guarantee the ordering of the `Abi` variants. While this is a downside, this decision was made bearing in mind that RFC 2945 states the following, in the "Other `unwind` Strings" section [3]: > More unwind variants of existing ABI strings may be introduced, > with the same semantics, without an additional RFC. Adding a new variant for each of these cases, rather than specifying a payload for a given ABI, would quickly become untenable, and make working with the `Abi` enum prone to mistakes. This approach encodes the unwinding information *into* a given ABI, to account for the future possibility of other `-unwind` ABI strings. ### Ignore Directives `ignore-*` directives are used in two of our `*-unwind` ABI test cases. Specifically, the `stdcall-unwind` and `thiscall-unwind` test cases ignore architectures that do not support `stdcall` and `thiscall`, respectively. These directives are cribbed from `src/test/ui/c-variadic/variadic-ffi-1.rs` for `stdcall`, and `src/test/ui/extern/extern-thiscall.rs` for `thiscall`. This would otherwise fail on some targets, see: https://github.com/rust-lang-ci/rust/commit/fcf697f90206e9c87b39d494f94ab35d976bfc60 ### Footnotes [1]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md [2]: https://github.com/rust-lang/rust/issues/74990 [3]: https://github.com/rust-lang/rfcs/blob/master/text/2945-c-unwind-abi.md#other-unwind-abi-strings --- src/abi/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index c79889f8ca1da..b158d73f3a1a8 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -476,8 +476,11 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { - if fn_sig.abi != Abi::C { - fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); + if !matches!(fn_sig.abi, Abi::C { .. }) { + fx.tcx.sess.span_fatal( + span, + &format!("Variadic call for non-C abi {:?}", fn_sig.abi), + ); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args From 6b1dd82162d62fef5fee258b050c96686b5ccbf0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 8 Mar 2021 16:18:03 +0000 Subject: [PATCH 28/51] Prepare mir::Constant for ty::Const only supporting valtrees --- src/constant.rs | 30 +++++++++++++++++------------- src/intrinsics/llvm.rs | 6 +++--- src/intrinsics/simd.rs | 8 ++++---- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index b0639cf9e15fe..23ad5267c569c 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -8,7 +8,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::interpret::{ read_target_uint, AllocId, Allocation, ConstValue, ErrorHandled, GlobalAlloc, Pointer, Scalar, }; -use rustc_middle::ty::{Const, ConstKind}; +use rustc_middle::ty::ConstKind; use cranelift_codegen::ir::GlobalValueData; use cranelift_module::*; @@ -39,7 +39,10 @@ impl ConstantCx { pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let mut all_constants_ok = true; for constant in &fx.mir.required_consts { - let const_ = fx.monomorphize(constant.literal); + let const_ = match fx.monomorphize(constant.literal) { + ConstantSource::Ty(ct) => ct, + ConstantSource::Val(..) => continue, + }; match const_.val { ConstKind::Value(_) => {} ConstKind::Unevaluated(def, ref substs, promoted) => { @@ -113,19 +116,17 @@ pub(crate) fn codegen_constant<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let const_ = fx.monomorphize(constant.literal); + let const_ = match fx.monomorphize(constant.literal) { + ConstantSource::Ty(ct) => ct, + ConstantSource::Val(val, ty) => return codegen_const_value(fx, val, ty), + }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, ConstKind::Unevaluated(def, ref substs, promoted) 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(fx.monomorphize(&constant.literal.ty)), - ) - .to_cvalue(fx); + return codegen_static_ref(fx, def.did, fx.layout_of(const_.ty)).to_cvalue(fx); } ConstKind::Unevaluated(def, ref substs, promoted) => { match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { @@ -422,11 +423,14 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant pub(crate) fn mir_operand_get_const_val<'tcx>( fx: &FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, -) -> Option<&'tcx Const<'tcx>> { +) -> Option> { match operand { Operand::Copy(_) | Operand::Move(_) => None, - Operand::Constant(const_) => { - Some(fx.monomorphize(const_.literal).eval(fx.tcx, ParamEnv::reveal_all())) - } + Operand::Constant(const_) => match const_.literal { + ConstantSource::Ty(const_) => { + fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value() + } + ConstantSource::Val(val, _) => Some(val), + }, } } diff --git a/src/intrinsics/llvm.rs b/src/intrinsics/llvm.rs index 0692da397eb94..83c91f789cd25 100644 --- a/src/intrinsics/llvm.rs +++ b/src/intrinsics/llvm.rs @@ -53,7 +53,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( }; llvm.x86.sse2.cmp.ps | llvm.x86.sse2.cmp.pd, (c x, c y, o kind) { let kind_const = crate::constant::mir_operand_get_const_val(fx, kind).expect("llvm.x86.sse2.cmp.* kind not const"); - let flt_cc = match kind_const.val.try_to_bits(Size::from_bytes(1)).unwrap_or_else(|| panic!("kind not scalar: {:?}", kind_const)) { + let flt_cc = match kind_const.try_to_bits(Size::from_bytes(1)).unwrap_or_else(|| panic!("kind not scalar: {:?}", kind_const)) { 0 => FloatCC::Equal, 1 => FloatCC::LessThan, 2 => FloatCC::LessThanOrEqual, @@ -84,7 +84,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( llvm.x86.sse2.psrli.d, (c a, o imm8) { let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8).expect("llvm.x86.sse2.psrli.d imm8 not const"); simd_for_each_lane(fx, a, ret, |fx, _lane_layout, res_lane_layout, lane| { - let res_lane = match imm8.val.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { + let res_lane = match imm8.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { imm8 if imm8 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm8 as u8)), _ => fx.bcx.ins().iconst(types::I32, 0), }; @@ -94,7 +94,7 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>( llvm.x86.sse2.pslli.d, (c a, o imm8) { let imm8 = crate::constant::mir_operand_get_const_val(fx, imm8).expect("llvm.x86.sse2.psrli.d imm8 not const"); simd_for_each_lane(fx, a, ret, |fx, _lane_layout, res_lane_layout, lane| { - let res_lane = match imm8.val.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { + let res_lane = match imm8.try_to_bits(Size::from_bytes(4)).unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8)) { imm8 if imm8 < 32 => fx.bcx.ins().ishl_imm(lane, i64::from(imm8 as u8)), _ => fx.bcx.ins().iconst(types::I32, 0), }; diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index 1f8eeb1e71491..d17136080fea3 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -85,8 +85,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( use rustc_middle::mir::interpret::*; let idx_const = crate::constant::mir_operand_get_const_val(fx, idx).expect("simd_shuffle* idx not const"); - let idx_bytes = match idx_const.val { - ty::ConstKind::Value(ConstValue::ByRef { alloc, offset }) => { + let idx_bytes = match idx_const { + ConstValue::ByRef { alloc, offset } => { let ptr = Pointer::new(AllocId(0 /* dummy */), offset); let size = Size::from_bytes(4 * u64::from(ret_lane_count) /* size_of([u32; ret_lane_count]) */); alloc.get_bytes(fx, ptr, size).unwrap() @@ -130,7 +130,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( ); }; - let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); let (lane_count, _lane_ty) = base.layout().ty.simd_size_and_type(fx.tcx); if idx >= lane_count.into() { fx.tcx.sess.span_fatal(fx.mir.span, &format!("[simd_insert] idx {} >= lane_count {}", idx, lane_count)); @@ -159,7 +159,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( return; }; - let idx = idx_const.val.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); + let idx = idx_const.try_to_bits(Size::from_bytes(4 /* u32*/)).unwrap_or_else(|| panic!("kind not scalar: {:?}", idx_const)); let (lane_count, _lane_ty) = v.layout().ty.simd_size_and_type(fx.tcx); if idx >= lane_count.into() { fx.tcx.sess.span_fatal(fx.mir.span, &format!("[simd_extract] idx {} >= lane_count {}", idx, lane_count)); From 578fcdef5fbd02bd3ae7d30349f62aa9143a0bf2 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 10:22:21 +0100 Subject: [PATCH 29/51] Special case ZST's in Rvalue::Repeat Fixes #1146 by preventing a hang for [(); usize::MAX], which is used in a test of libcore. --- src/base.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/base.rs b/src/base.rs index 362ba7e1c2c74..5a28656add2d9 100644 --- a/src/base.rs +++ b/src/base.rs @@ -660,7 +660,9 @@ fn codegen_stmt<'tcx>( .val .try_to_bits(fx.tcx.data_layout.pointer_size) .unwrap(); - if fx.clif_type(operand.layout().ty) == Some(types::I8) { + if operand.layout().size.bytes() == 0 { + // Do nothing for ZST's + } else if fx.clif_type(operand.layout().ty) == Some(types::I8) { let times = fx.bcx.ins().iconst(fx.pointer_type, times as i64); // FIXME use emit_small_memset where possible let addr = lval.to_ptr().get_addr(fx); From b1d14ca05d6b34423c31fd237fdf2d6cd6f70333 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 11:59:06 +0100 Subject: [PATCH 30/51] Use mmap for metadata loading This can have a significant improvement on compilation times. In addition it reduces the memory consumption. Fixes #927 --- Cargo.lock | 10 +++++++ Cargo.toml | 3 ++- src/metadata.rs | 70 +++++++++++++++++++++++++++++++------------------ 3 files changed, 56 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ed186032ff20..a033912364e88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -240,6 +240,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memmap2" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.23.0" @@ -310,6 +319,7 @@ dependencies = [ "gimli", "indexmap", "libloading", + "memmap2", "object", "smallvec", "target-lexicon", diff --git a/Cargo.toml b/Cargo.toml index e51714b56d70d..59542c414fa85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,12 +16,13 @@ cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime/", branch cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime/", branch = "main" } target-lexicon = "0.11.0" gimli = { version = "0.23.0", default-features = false, features = ["write"]} -object = { version = "0.23.0", default-features = false, features = ["std", "read_core", "write", "coff", "elf", "macho", "pe"] } +object = { version = "0.23.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" } indexmap = "1.0.2" libloading = { version = "0.6.0", optional = true } smallvec = "1.6.1" +memmap2 = "0.2.1" # Uncomment to use local checkout of cranelift #[patch."https://github.com/bytecodealliance/wasmtime/"] diff --git a/src/metadata.rs b/src/metadata.rs index 190c4f45ccafd..dda9285a38a99 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -1,11 +1,11 @@ //! Reading and writing of the rustc metadata for rlibs and dylibs -use std::convert::TryFrom; use std::fs::File; +use std::ops::Deref; use std::path::Path; use rustc_codegen_ssa::METADATA_FILENAME; -use rustc_data_structures::owning_ref::OwningRef; +use rustc_data_structures::owning_ref::{OwningRef, StableAddress}; use rustc_data_structures::rustc_erase_owner; use rustc_data_structures::sync::MetadataRef; use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader}; @@ -17,38 +17,56 @@ use crate::backend::WriteMetadata; pub(crate) struct CraneliftMetadataLoader; +struct StableMmap(memmap2::Mmap); + +impl Deref for StableMmap { + type Target = [u8]; + + fn deref(&self) -> &[u8] { + &*self.0 + } +} + +unsafe impl StableAddress for StableMmap {} + +fn load_metadata_with( + path: &Path, + f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, +) -> Result { + let file = File::open(path).map_err(|e| format!("{:?}", e))?; + let data = unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file) } + .map_err(|e| format!("{:?}", e))?; + let metadata = OwningRef::new(StableMmap(data)).try_map(f)?; + return Ok(rustc_erase_owner!(metadata.map_owner_box())); +} + impl MetadataLoader for CraneliftMetadataLoader { fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result { - let mut archive = ar::Archive::new(File::open(path).map_err(|e| format!("{:?}", e))?); - // Iterate over all entries in the archive: - while let Some(entry_result) = archive.next_entry() { - let mut entry = entry_result.map_err(|e| format!("{:?}", e))?; - if entry.header().identifier() == METADATA_FILENAME.as_bytes() { - let mut buf = Vec::with_capacity( - usize::try_from(entry.header().size()) - .expect("Rlib metadata file too big to load into memory."), - ); - ::std::io::copy(&mut entry, &mut buf).map_err(|e| format!("{:?}", e))?; - let buf: OwningRef, [u8]> = OwningRef::new(buf); - return Ok(rustc_erase_owner!(buf.map_owner_box())); + load_metadata_with(path, |data| { + let archive = object::read::archive::ArchiveFile::parse(&*data) + .map_err(|e| format!("{:?}", e))?; + + for entry_result in archive.members() { + let entry = entry_result.map_err(|e| format!("{:?}", e))?; + if entry.name() == METADATA_FILENAME.as_bytes() { + return Ok(entry.data()); + } } - } - Err("couldn't find metadata entry".to_string()) + Err("couldn't find metadata entry".to_string()) + }) } fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result { use object::{Object, ObjectSection}; - let file = std::fs::read(path).map_err(|e| format!("read:{:?}", e))?; - let file = object::File::parse(&file).map_err(|e| format!("parse: {:?}", e))?; - let buf = file - .section_by_name(".rustc") - .ok_or("no .rustc section")? - .data() - .map_err(|e| format!("failed to read .rustc section: {:?}", e))? - .to_owned(); - let buf: OwningRef, [u8]> = OwningRef::new(buf); - Ok(rustc_erase_owner!(buf.map_owner_box())) + + load_metadata_with(path, |data| { + let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?; + file.section_by_name(".rustc") + .ok_or("no .rustc section")? + .data() + .map_err(|e| format!("failed to read .rustc section: {:?}", e)) + }) } } From 21a0c8e9e47942dcbc47f1680d076daeb5629451 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Mar 2021 11:23:44 +0000 Subject: [PATCH 31/51] s/ConstantSource/ConstantKind/ --- src/constant.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 23ad5267c569c..9d93370b7d0c9 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -40,8 +40,8 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let mut all_constants_ok = true; for constant in &fx.mir.required_consts { let const_ = match fx.monomorphize(constant.literal) { - ConstantSource::Ty(ct) => ct, - ConstantSource::Val(..) => continue, + ConstantKind::Ty(ct) => ct, + ConstantKind::Val(..) => continue, }; match const_.val { ConstKind::Value(_) => {} @@ -117,8 +117,8 @@ pub(crate) fn codegen_constant<'tcx>( constant: &Constant<'tcx>, ) -> CValue<'tcx> { let const_ = match fx.monomorphize(constant.literal) { - ConstantSource::Ty(ct) => ct, - ConstantSource::Val(val, ty) => return codegen_const_value(fx, val, ty), + ConstantKind::Ty(ct) => ct, + ConstantKind::Val(val, ty) => return codegen_const_value(fx, val, ty), }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, @@ -427,10 +427,10 @@ pub(crate) fn mir_operand_get_const_val<'tcx>( match operand { Operand::Copy(_) | Operand::Move(_) => None, Operand::Constant(const_) => match const_.literal { - ConstantSource::Ty(const_) => { + ConstantKind::Ty(const_) => { fx.monomorphize(const_).eval(fx.tcx, ParamEnv::reveal_all()).val.try_to_value() } - ConstantSource::Val(val, _) => Some(val), + ConstantKind::Val(val, _) => Some(val), }, } } From 3d85f05dfd85be2ea8c61fd2e6a5b6816c0abfdc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 13:55:54 +0100 Subject: [PATCH 32/51] Remove no longer necessary intcasts --- src/num.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/num.rs b/src/num.rs index 9ee564a9a5413..2ebf30da2d8ba 100644 --- a/src/num.rs +++ b/src/num.rs @@ -166,13 +166,11 @@ pub(crate) fn codegen_int_binop<'tcx>( BinOp::Shl => { 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)); - let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); fx.bcx.ins().ishl(lhs, actual_shift) } 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)); - let actual_shift = clif_intcast(fx, actual_shift, types::I8, false); if signed { fx.bcx.ins().sshr(lhs, actual_shift) } else { From 78d0b7765107bcad95a5279b6a78fd0753159e1b Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:04:22 +0100 Subject: [PATCH 33/51] Update Cranelift --- Cargo.lock | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a033912364e88..9184074e92fa0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-entity", ] @@ -48,7 +48,7 @@ dependencies = [ [[package]] name = "cranelift-codegen" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "byteorder", "cranelift-bforest", @@ -66,7 +66,7 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -75,17 +75,17 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" [[package]] name = "cranelift-entity" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" [[package]] name = "cranelift-frontend" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-codegen", "log", @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "cranelift-jit" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "anyhow", "cranelift-codegen", @@ -114,7 +114,7 @@ dependencies = [ [[package]] name = "cranelift-module" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "anyhow", "cranelift-codegen", @@ -126,7 +126,7 @@ dependencies = [ [[package]] name = "cranelift-native" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "cranelift-codegen", "target-lexicon", @@ -135,7 +135,7 @@ dependencies = [ [[package]] name = "cranelift-object" version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#e41d88214455987751997b9d6173c5dee93204da" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" dependencies = [ "anyhow", "cranelift-codegen", From f545a21fbe9f32b6f489b064488647997f3af70e Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:21:15 +0100 Subject: [PATCH 34/51] Split rust fork setup out of test_bootstrap.sh --- scripts/setup_rust_fork.sh | 68 ++++++++++++++++++++++++++++++++++++++ scripts/test_bootstrap.sh | 62 +--------------------------------- 2 files changed, 69 insertions(+), 61 deletions(-) create mode 100644 scripts/setup_rust_fork.sh diff --git a/scripts/setup_rust_fork.sh b/scripts/setup_rust_fork.sh new file mode 100644 index 0000000000000..e8bedf625f796 --- /dev/null +++ b/scripts/setup_rust_fork.sh @@ -0,0 +1,68 @@ +#!/bin/bash +set -e + +./build.sh +source build/config.sh + +echo "[SETUP] Rust fork" +git clone https://github.com/rust-lang/rust.git || true +pushd rust +git fetch +git checkout -- . +git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')" + +git apply - < config.toml < config.toml < Date: Mon, 15 Mar 2021 14:22:11 +0100 Subject: [PATCH 35/51] Fix assert_assignable adt checking --- src/value_and_place.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/value_and_place.rs b/src/value_and_place.rs index 1a6a301a45bbd..b97d39009847a 100644 --- a/src/value_and_place.rs +++ b/src/value_and_place.rs @@ -705,6 +705,19 @@ pub(crate) fn assert_assignable<'tcx>( } // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed } + (&ty::Adt(adt_def_a, substs_a), &ty::Adt(adt_def_b, substs_b)) + if adt_def_a.did == adt_def_b.did => + { + let mut types_a = substs_a.types(); + let mut types_b = substs_b.types(); + loop { + match (types_a.next(), types_b.next()) { + (Some(a), Some(b)) => assert_assignable(fx, a, b), + (None, None) => return, + (Some(_), None) | (None, Some(_)) => panic!("{:#?}/{:#?}", from_ty, to_ty), + } + } + } _ => { assert_eq!( from_ty, to_ty, From 154668bd02a6bf29632ee500ec1778b7fb820c5d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:48:58 +0100 Subject: [PATCH 36/51] Suppress an unnecessary warning and fix an incorrect warning --- src/lib.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 650e5e04bdbd5..158f5d4b9d2b4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -224,8 +224,10 @@ pub struct CraneliftCodegenBackend { impl CodegenBackend for CraneliftCodegenBackend { fn init(&self, sess: &Session) { - if sess.lto() != rustc_session::config::Lto::No && sess.opts.cg.embed_bitcode { - sess.warn("LTO is not supported. You may get a linker error."); + use rustc_session::config::Lto; + match sess.lto() { + Lto::No | Lto::ThinLocal => {} + Lto::Thin | Lto::Fat => sess.warn("LTO is not supported. You may get a linker error."), } } @@ -320,12 +322,9 @@ fn build_isa(sess: &Session) -> Box { flags_builder.set("opt_level", "none").unwrap(); } OptLevel::Less | OptLevel::Default => {} - OptLevel::Aggressive => { + OptLevel::Size | OptLevel::SizeMin | OptLevel::Aggressive => { flags_builder.set("opt_level", "speed_and_size").unwrap(); } - OptLevel::Size | OptLevel::SizeMin => { - sess.warn("Optimizing for size is not supported. Just ignoring the request"); - } } let flags = settings::Flags::new(flags_builder); From 80b2feae1a808aeed5ff4df7eee5d33c211081f6 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 14:49:57 +0100 Subject: [PATCH 37/51] Run the rustc test suite on CI --- .github/workflows/bootstrap_rustc.yml | 44 -------------- .github/workflows/rustc.yml | 82 +++++++++++++++++++++++++ scripts/test_rustc_tests.sh | 86 +++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 44 deletions(-) delete mode 100644 .github/workflows/bootstrap_rustc.yml create mode 100644 .github/workflows/rustc.yml create mode 100755 scripts/test_rustc_tests.sh diff --git a/.github/workflows/bootstrap_rustc.yml b/.github/workflows/bootstrap_rustc.yml deleted file mode 100644 index 8c94a0aa5e6eb..0000000000000 --- a/.github/workflows/bootstrap_rustc.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Bootstrap rustc using cg_clif - -on: - - push - -jobs: - bootstrap_rustc: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - - name: Cache cargo installed crates - uses: actions/cache@v2 - with: - path: ~/.cargo/bin - key: ${{ runner.os }}-cargo-installed-crates - - - name: Cache cargo registry and index - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} - - - name: Cache cargo target dir - uses: actions/cache@v2 - with: - path: target - key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} - - - name: Prepare dependencies - run: | - git config --global user.email "user@example.com" - git config --global user.name "User" - ./prepare.sh - - - name: Test - run: | - # Enable backtraces for easier debugging - export RUST_BACKTRACE=1 - - ./scripts/test_bootstrap.sh diff --git a/.github/workflows/rustc.yml b/.github/workflows/rustc.yml new file mode 100644 index 0000000000000..e01a92598bab7 --- /dev/null +++ b/.github/workflows/rustc.yml @@ -0,0 +1,82 @@ +name: Various rustc tests + +on: + - push + +jobs: + bootstrap_rustc: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache cargo installed crates + uses: actions/cache@v2 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-installed-crates + + - name: Cache cargo registry and index + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo target dir + uses: actions/cache@v2 + with: + path: target + key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Prepare dependencies + run: | + git config --global user.email "user@example.com" + git config --global user.name "User" + ./prepare.sh + + - name: Test + run: | + # Enable backtraces for easier debugging + export RUST_BACKTRACE=1 + + ./scripts/test_bootstrap.sh + rustc_test_suite: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache cargo installed crates + uses: actions/cache@v2 + with: + path: ~/.cargo/bin + key: ${{ runner.os }}-cargo-installed-crates + + - name: Cache cargo registry and index + uses: actions/cache@v2 + with: + path: | + ~/.cargo/registry + ~/.cargo/git + key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }} + + - name: Cache cargo target dir + uses: actions/cache@v2 + with: + path: target + key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }} + + - name: Prepare dependencies + run: | + git config --global user.email "user@example.com" + git config --global user.name "User" + ./prepare.sh + + - name: Test + run: | + # Enable backtraces for easier debugging + export RUST_BACKTRACE=1 + + ./scripts/test_rustc_tests.sh diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh new file mode 100755 index 0000000000000..1c3318d53de77 --- /dev/null +++ b/scripts/test_rustc_tests.sh @@ -0,0 +1,86 @@ +#!/bin/bash +set -e + +cd $(dirname "$0")/../ + +source ./scripts/setup_rust_fork.sh + +echo "[TEST] Test suite of rustc" +pushd rust + +cargo install ripgrep + +rm -r src/test/ui/{extern/,panics/,unsized-locals/,thinlto/,simd*,*lto*.rs,linkage*,unwind-*.rs} || true +for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto" src/test/ui); do + rm $test +done + +for test in $(rg -i --files-with-matches "//(\[\w+\])?~|// error-pattern:|// build-fail|// run-fail|-Cllvm-args" src/test/ui); do + rm $test +done + +git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed + +# these all depend on unwinding support +rm src/test/ui/backtrace.rs +rm src/test/ui/array-slice-vec/box-of-array-of-drop-*.rs +rm src/test/ui/array-slice-vec/slice-panic-*.rs +rm src/test/ui/array-slice-vec/nested-vec-3.rs +rm src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs +rm src/test/ui/issues/issue-26655.rs +rm src/test/ui/issues/issue-29485.rs +rm src/test/ui/issues/issue-30018-panic.rs +rm src/test/ui/multi-panic.rs +rm src/test/ui/sepcomp/sepcomp-unwind.rs +rm src/test/ui/structs-enums/unit-like-struct-drop-run.rs +rm src/test/ui/terminate-in-initializer.rs +rm src/test/ui/threads-sendsync/task-stderr.rs +rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs +rm src/test/ui/drop/drop-trait-enum.rs +rm src/test/ui/numbers-arithmetic/issue-8460.rs + +rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations +rm src/test/ui/init-large-type.rs # same +rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected +rm src/test/ui/issues/issue-33992.rs # unsupported linkages +rm src/test/ui/issues/issue-51947.rs # same +rm src/test/ui/numbers-arithmetic/saturating-float-casts.rs # intrinsic gives different but valid result +rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants +rm src/test/ui/mir/mir_raw_fat_ptr.rs # same +rm src/test/ui/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 src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment +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/intrinsics/intrinsic-nearby.rs # unimplemented nearbyintf32 and nearbyintf64 intrinsics + +rm src/test/incremental/hashes/inline_asm.rs # inline asm +rm src/test/incremental/issue-72386.rs # same +rm src/test/incremental/change_crate_dep_kind.rs # requires -Cpanic=unwind +rm src/test/incremental/issue-49482.rs # same +rm src/test/incremental/issue-54059.rs # same +rm src/test/incremental/lto.rs # requires lto + +rm src/test/pretty/asm.rs # inline asm +rm src/test/pretty/raw-str-nonexpr.rs # same + +rm -r src/test/run-pass-valgrind/unsized-locals + +rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning +rm src/test/ui/json-bom-plus-crlf.rs # same + +rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition +rm src/test/ui/cfg/cfg-panic.rs +rm src/test/ui/default-alloc-error-hook.rs +rm -r src/test/ui/hygiene/ + +rm -r src/test/ui/polymorphization/ # polymorphization not yet supported +rm src/test/codegen-units/polymorphization/unused_type_parameters.rs # same + +rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization +rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs +rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support + +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} +popd From 53235d2abb881876dd4ec8119c6a31da53d328a4 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 15 Mar 2021 18:01:48 +0100 Subject: [PATCH 38/51] Enable thread test in std_example Turns out libstd doesn't use #[thread_local] on Windows at all --- example/std_example.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example/std_example.rs b/example/std_example.rs index 221b512e3bd4c..015bbdfed4648 100644 --- a/example/std_example.rs +++ b/example/std_example.rs @@ -16,8 +16,7 @@ fn main() { let mut stderr = stderr.lock(); // FIXME support lazy jit when multi threading - // FIXME support TLS on windows - #[cfg(not(any(lazy_jit, windows)))] + #[cfg(not(lazy_jit))] std::thread::spawn(move || { println!("Hello from another thread!"); }); From 218b383f8f00808a08c08e131470e1ab5c2e6749 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 17 Mar 2021 13:54:40 +0100 Subject: [PATCH 39/51] Rustfmt --- src/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metadata.rs b/src/metadata.rs index dda9285a38a99..c5189c972cd2e 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -46,7 +46,7 @@ impl MetadataLoader for CraneliftMetadataLoader { let archive = object::read::archive::ArchiveFile::parse(&*data) .map_err(|e| format!("{:?}", e))?; - for entry_result in archive.members() { + for entry_result in archive.members() { let entry = entry_result.map_err(|e| format!("{:?}", e))?; if entry.name() == METADATA_FILENAME.as_bytes() { return Ok(entry.data()); From e86b95480fac70673bd837e7fcfa45458bd52eb7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 17 Mar 2021 13:56:54 +0100 Subject: [PATCH 40/51] Directly invoke the main function in JIT mode Fixes #1151 --- src/driver/jit.rs | 74 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 245df03ffb84d..dec95d6571469 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -7,6 +7,7 @@ use std::os::raw::{c_char, c_int}; use rustc_codegen_ssa::CrateInfo; use rustc_middle::mir::mono::MonoItem; +use rustc_session::config::EntryFnType; use cranelift_jit::{JITBuilder, JITModule}; @@ -32,16 +33,6 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { let mut jit_module = JITModule::new(jit_builder); assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); - let sig = Signature { - params: vec![ - AbiParam::new(jit_module.target_config().pointer_type()), - AbiParam::new(jit_module.target_config().pointer_type()), - ], - returns: vec![AbiParam::new(jit_module.target_config().pointer_type() /*isize*/)], - call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), - }; - let main_func_id = jit_module.declare_function("main", Linkage::Import, &sig).unwrap(); - let (_, cgus) = tcx.collect_and_partition_mono_items(LOCAL_CRATE); let mono_items = cgus .iter() @@ -86,24 +77,17 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { tcx.sess.fatal("Inline asm is not supported in JIT mode"); } - crate::main_shim::maybe_create_entry_wrapper(tcx, &mut jit_module, &mut unwind_context); crate::allocator::codegen(tcx, &mut jit_module, &mut unwind_context); tcx.sess.abort_if_errors(); jit_module.finalize_definitions(); - let _unwind_register_guard = unsafe { unwind_context.register_jit(&jit_module) }; - let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); - println!( "Rustc codegen cranelift will JIT run the executable, because -Cllvm-args=mode=jit was passed" ); - let f: extern "C" fn(c_int, *const *const c_char) -> c_int = - unsafe { ::std::mem::transmute(finalized_main) }; - let args = ::std::env::var("CG_CLIF_JIT_ARGS").unwrap_or_else(|_| String::new()); let args = std::iter::once(&*tcx.crate_name(LOCAL_CRATE).as_str().to_string()) .chain(args.split(' ')) @@ -118,12 +102,58 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { BACKEND_CONFIG.with(|tls_backend_config| { assert!(tls_backend_config.borrow_mut().replace(backend_config).is_none()) }); - CURRENT_MODULE - .with(|current_module| assert!(current_module.borrow_mut().replace(jit_module).is_none())); - let ret = f(args.len() as c_int, argv.as_ptr()); + let (main_def_id, entry_ty) = tcx.entry_fn(LOCAL_CRATE).unwrap(); + let instance = Instance::mono(tcx, main_def_id.to_def_id()).polymorphize(tcx); + + match entry_ty { + EntryFnType::Main => { + // FIXME set program arguments somehow - std::process::exit(ret); + let main_sig = Signature { + params: vec![], + returns: vec![], + call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), + }; + let main_func_id = jit_module + .declare_function(tcx.symbol_name(instance).name, Linkage::Import, &main_sig) + .unwrap(); + let finalized_main: *const u8 = jit_module.get_finalized_function(main_func_id); + + CURRENT_MODULE.with(|current_module| { + assert!(current_module.borrow_mut().replace(jit_module).is_none()) + }); + + let f: extern "C" fn() = unsafe { ::std::mem::transmute(finalized_main) }; + f(); + std::process::exit(0); + } + EntryFnType::Start => { + let start_sig = Signature { + params: vec![ + AbiParam::new(jit_module.target_config().pointer_type()), + AbiParam::new(jit_module.target_config().pointer_type()), + ], + returns: vec![AbiParam::new( + jit_module.target_config().pointer_type(), /*isize*/ + )], + call_conv: CallConv::triple_default(&crate::target_triple(tcx.sess)), + }; + let start_func_id = jit_module + .declare_function(tcx.symbol_name(instance).name, Linkage::Import, &start_sig) + .unwrap(); + let finalized_start: *const u8 = jit_module.get_finalized_function(start_func_id); + + CURRENT_MODULE.with(|current_module| { + assert!(current_module.borrow_mut().replace(jit_module).is_none()) + }); + + let f: extern "C" fn(c_int, *const *const c_char) -> c_int = + unsafe { ::std::mem::transmute(finalized_start) }; + let ret = f(args.len() as c_int, argv.as_ptr()); + std::process::exit(ret); + } + } } #[no_mangle] @@ -220,7 +250,7 @@ fn load_imported_symbols_for_jit(tcx: TyCtxt<'_>) -> Vec<(String, *const u8)> { imported_symbols } -pub(super) fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { +fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { let tcx = cx.tcx; let pointer_type = cx.module.target_config().pointer_type(); From 664b25ea38f9a7e826048df1490a101adbc7d6d5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Mar 2021 12:19:31 +0100 Subject: [PATCH 41/51] Rustup to rustc 1.52.0-nightly (36f1f04f1 2021-03-17) --- build_sysroot/Cargo.lock | 4 ++-- rust-toolchain | 2 +- src/driver/aot.rs | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index cd0526b0129a0..225577268892d 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" +checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index d00e2bee74656..a0b828e39a4d1 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-09" +channel = "nightly-2021-03-18" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 0f1da66170a32..3f3cdab058b06 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -165,9 +165,8 @@ pub(super) fn run_aot( ) -> Box<(CodegenResults, FxHashMap)> { use rustc_span::symbol::sym; - let subsystem = tcx - .sess - .first_attr_value_str_by_name(&tcx.hir().krate().item.attrs, sym::windows_subsystem); + let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); + let subsystem = tcx.sess.first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem); let windows_subsystem = subsystem.map(|subsystem| { if subsystem != sym::windows && subsystem != sym::console { tcx.sess.fatal(&format!( From 0069007d5b17b19bf6a7686dec7dee7be46dcd47 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Mar 2021 12:20:24 +0100 Subject: [PATCH 42/51] Avoid nightly feature usage where easily possible --- example/mini_core_hello_world.rs | 5 +---- src/base.rs | 24 ++++++++++-------------- src/lib.rs | 4 ---- src/pretty_clif.rs | 5 +---- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/example/mini_core_hello_world.rs b/example/mini_core_hello_world.rs index 08ceaeb65443f..ea37ca98b59a7 100644 --- a/example/mini_core_hello_world.rs +++ b/example/mini_core_hello_world.rs @@ -1,7 +1,4 @@ -#![feature( - no_core, start, lang_items, box_syntax, never_type, linkage, - extern_types, thread_local -)] +#![feature(no_core, lang_items, box_syntax, never_type, linkage, extern_types, thread_local)] #![no_core] #![allow(dead_code, non_camel_case_types)] diff --git a/src/base.rs b/src/base.rs index ee0244b1ad02a..33a28ac733e76 100644 --- a/src/base.rs +++ b/src/base.rs @@ -465,16 +465,16 @@ fn codegen_stmt<'tcx>( let val = crate::constant::codegen_tls_ref(fx, def_id, lval.layout()); lval.write_cvalue(fx, val); } - Rvalue::BinaryOp(bin_op, box (ref lhs, ref rhs)) => { - let lhs = codegen_operand(fx, lhs); - let rhs = codegen_operand(fx, rhs); + Rvalue::BinaryOp(bin_op, ref lhs_rhs) => { + let lhs = codegen_operand(fx, &lhs_rhs.0); + let rhs = codegen_operand(fx, &lhs_rhs.1); let res = crate::num::codegen_binop(fx, bin_op, lhs, rhs); lval.write_cvalue(fx, res); } - Rvalue::CheckedBinaryOp(bin_op, box (ref lhs, ref rhs)) => { - let lhs = codegen_operand(fx, lhs); - let rhs = codegen_operand(fx, rhs); + Rvalue::CheckedBinaryOp(bin_op, ref lhs_rhs) => { + let lhs = codegen_operand(fx, &lhs_rhs.0); + let rhs = codegen_operand(fx, &lhs_rhs.1); let res = if !fx.tcx.sess.overflow_checks() { let val = @@ -835,19 +835,15 @@ fn codegen_stmt<'tcx>( } } StatementKind::Coverage { .. } => fx.tcx.sess.fatal("-Zcoverage is unimplemented"), - StatementKind::CopyNonOverlapping(box rustc_middle::mir::CopyNonOverlapping { - src, - dst, - count, - }) => { - let dst = codegen_operand(fx, dst); + StatementKind::CopyNonOverlapping(inner) => { + let dst = codegen_operand(fx, &inner.dst); let pointee = dst .layout() .pointee_info_at(fx, rustc_target::abi::Size::ZERO) .expect("Expected pointer"); let dst = dst.load_scalar(fx); - let src = codegen_operand(fx, src).load_scalar(fx); - let count = codegen_operand(fx, count).load_scalar(fx); + let src = codegen_operand(fx, &inner.src).load_scalar(fx); + let count = codegen_operand(fx, &inner.count).load_scalar(fx); let elem_size: u64 = pointee.size.bytes(); let bytes = if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) diff --git a/src/lib.rs b/src/lib.rs index 158f5d4b9d2b4..63fb1c4084463 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,7 @@ #![feature( rustc_private, decl_macro, - type_alias_impl_trait, - associated_type_bounds, never_type, - try_blocks, - box_patterns, hash_drain_filter )] #![warn(rust_2018_idioms)] diff --git a/src/pretty_clif.rs b/src/pretty_clif.rs index 855a0cc8e4a16..d22ea3772eee7 100644 --- a/src/pretty_clif.rs +++ b/src/pretty_clif.rs @@ -224,10 +224,7 @@ pub(crate) fn write_ir_file( let clif_file_name = clif_output_dir.join(name); - let res: std::io::Result<()> = try { - let mut file = std::fs::File::create(clif_file_name)?; - write(&mut file)?; - }; + let res = std::fs::File::create(clif_file_name).and_then(|mut file| write(&mut file)); if let Err(err) = res { tcx.sess.warn(&format!("error writing ir file: {}", err)); } From 7bd3950831bde1f8d4910e9435cf0c423e1a6772 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 18 Mar 2021 12:51:58 +0100 Subject: [PATCH 43/51] Fix rustc test suite --- scripts/test_rustc_tests.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/test_rustc_tests.sh b/scripts/test_rustc_tests.sh index 1c3318d53de77..fbc3feceec7ac 100755 --- a/scripts/test_rustc_tests.sh +++ b/scripts/test_rustc_tests.sh @@ -68,6 +68,7 @@ rm -r src/test/run-pass-valgrind/unsized-locals rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning rm src/test/ui/json-bom-plus-crlf.rs # same +rm src/test/ui/type-alias-impl-trait/cross_crate_ice*.rs # requires removed aux dep rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition rm src/test/ui/cfg/cfg-panic.rs From e4a1092b9f21a7dd966d7198846132f3dd17513a Mon Sep 17 00:00:00 2001 From: SparrowLii Date: Fri, 19 Mar 2021 02:16:21 +0800 Subject: [PATCH 44/51] Add simd_neg platform intrinsic --- src/intrinsics/simd.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/intrinsics/simd.rs b/src/intrinsics/simd.rs index d17136080fea3..86df71a0dfc91 100644 --- a/src/intrinsics/simd.rs +++ b/src/intrinsics/simd.rs @@ -276,5 +276,6 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( // simd_bitmask // simd_select // simd_rem + // simd_neg } } From 500bcfcdb3122d68cabdfc2eb9034d88b708e0bc Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 13 Mar 2021 16:31:38 +0100 Subject: [PATCH 45/51] update `const_eval_resolve` --- src/constant.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/constant.rs b/src/constant.rs index 9d93370b7d0c9..f4cbfb6967ff3 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -45,9 +45,9 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { }; match const_.val { ConstKind::Value(_) => {} - ConstKind::Unevaluated(def, ref substs, promoted) => { + ConstKind::Unevaluated(unevaluated) => { if let Err(err) = - fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) + fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { all_constants_ok = false; match err { @@ -122,14 +122,14 @@ pub(crate) fn codegen_constant<'tcx>( }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(def, ref substs, promoted) if fx.tcx.is_static(def.did) => { + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) 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(const_.ty)).to_cvalue(fx); } - ConstKind::Unevaluated(def, ref substs, promoted) => { - match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), def, substs, promoted, None) { + ConstKind::Unevaluated(unevaluated) => { + match fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { Ok(const_val) => const_val, Err(_) => { span_bug!(constant.span, "erroneous constant not captured by required_consts"); From 56fe51cb36eadcd360a7cf119d930c841dc6ea38 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 21 Mar 2021 10:05:22 +0100 Subject: [PATCH 46/51] Update Cranelift --- Cargo.lock | 40 ++++++++++++++++++++-------------------- src/allocator.rs | 5 +++-- src/base.rs | 3 ++- src/driver/jit.rs | 4 +++- src/main_shim.rs | 9 +++------ 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9184074e92fa0..3cb67032aaa24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,16 +39,16 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cranelift-bforest" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "byteorder", "cranelift-bforest", @@ -65,8 +65,8 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -74,18 +74,18 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" [[package]] name = "cranelift-entity" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" [[package]] name = "cranelift-frontend" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-codegen", "log", @@ -95,8 +95,8 @@ dependencies = [ [[package]] name = "cranelift-jit" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "anyhow", "cranelift-codegen", @@ -113,8 +113,8 @@ dependencies = [ [[package]] name = "cranelift-module" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "anyhow", "cranelift-codegen", @@ -125,8 +125,8 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "cranelift-codegen", "target-lexicon", @@ -134,8 +134,8 @@ dependencies = [ [[package]] name = "cranelift-object" -version = "0.71.0" -source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#df6812b8559c35230d44c6d6f94a83b2b97b5de3" +version = "0.72.0" +source = "git+https://github.com/bytecodealliance/wasmtime/?branch=main#8e43e96410a14143d368273cf1e708f8094bb8e0" dependencies = [ "anyhow", "cranelift-codegen", diff --git a/src/allocator.rs b/src/allocator.rs index efb64233ef2c3..f60645a9f97bc 100644 --- a/src/allocator.rs +++ b/src/allocator.rs @@ -3,6 +3,7 @@ use crate::prelude::*; +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_span::symbol::sym; @@ -92,7 +93,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) + .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } @@ -132,7 +133,7 @@ fn codegen_inner( bcx.finalize(); } module - .define_function(func_id, &mut ctx, &mut cranelift_codegen::binemit::NullTrapSink {}) + .define_function(func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {}) .unwrap(); unwind_context.add_function(func_id, &ctx, module.isa()); } diff --git a/src/base.rs b/src/base.rs index 33a28ac733e76..8c14e04eeebf5 100644 --- a/src/base.rs +++ b/src/base.rs @@ -1,5 +1,6 @@ //! Codegen of a single function +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_index::vec::IndexVec; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::layout::FnAbiExt; @@ -131,7 +132,7 @@ pub(crate) fn codegen_fn<'tcx>( let module = &mut cx.module; tcx.sess.time("define function", || { module - .define_function(func_id, context, &mut cranelift_codegen::binemit::NullTrapSink {}) + .define_function(func_id, context, &mut NullTrapSink {}, &mut NullStackMapSink {}) .unwrap() }); diff --git a/src/driver/jit.rs b/src/driver/jit.rs index dec95d6571469..1b08b4169132d 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -5,6 +5,7 @@ use std::cell::RefCell; use std::ffi::CString; use std::os::raw::{c_char, c_int}; +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_codegen_ssa::CrateInfo; use rustc_middle::mir::mono::MonoItem; use rustc_session::config::EntryFnType; @@ -297,7 +298,8 @@ fn codegen_shim<'tcx>(cx: &mut CodegenCx<'_, 'tcx>, inst: Instance<'tcx>) { .define_function( func_id, &mut Context::for_function(trampoline), - &mut cranelift_codegen::binemit::NullTrapSink {}, + &mut NullTrapSink {}, + &mut NullStackMapSink {}, ) .unwrap(); } diff --git a/src/main_shim.rs b/src/main_shim.rs index 62e551b186ff7..a6266f507765f 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -1,3 +1,4 @@ +use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink}; use rustc_hir::LangItem; use rustc_session::config::EntryFnType; @@ -100,12 +101,8 @@ pub(crate) fn maybe_create_entry_wrapper( bcx.seal_all_blocks(); bcx.finalize(); } - m.define_function( - cmain_func_id, - &mut ctx, - &mut cranelift_codegen::binemit::NullTrapSink {}, - ) - .unwrap(); + m.define_function(cmain_func_id, &mut ctx, &mut NullTrapSink {}, &mut NullStackMapSink {}) + .unwrap(); unwind_context.add_function(cmain_func_id, &ctx, m.isa()); } } From 73626efb26f61c68c8c9d4bec0a35928130a2010 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 21 Mar 2021 10:05:48 +0100 Subject: [PATCH 47/51] Rustfmt --- src/abi/mod.rs | 5 +---- src/base.rs | 13 +++++-------- src/lib.rs | 7 +------ 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/abi/mod.rs b/src/abi/mod.rs index b37a5f308c8f9..0e7829eaa26ac 100644 --- a/src/abi/mod.rs +++ b/src/abi/mod.rs @@ -470,10 +470,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( // FIXME find a cleaner way to support varargs if fn_sig.c_variadic { if !matches!(fn_sig.abi, Abi::C { .. }) { - fx.tcx.sess.span_fatal( - span, - &format!("Variadic call for non-C abi {:?}", fn_sig.abi), - ); + fx.tcx.sess.span_fatal(span, &format!("Variadic call for non-C abi {:?}", fn_sig.abi)); } let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap(); let abi_params = call_args diff --git a/src/base.rs b/src/base.rs index 8c14e04eeebf5..7cd7bb1de4141 100644 --- a/src/base.rs +++ b/src/base.rs @@ -839,18 +839,15 @@ fn codegen_stmt<'tcx>( StatementKind::CopyNonOverlapping(inner) => { let dst = codegen_operand(fx, &inner.dst); let pointee = dst - .layout() - .pointee_info_at(fx, rustc_target::abi::Size::ZERO) - .expect("Expected pointer"); + .layout() + .pointee_info_at(fx, rustc_target::abi::Size::ZERO) + .expect("Expected pointer"); let dst = dst.load_scalar(fx); let src = codegen_operand(fx, &inner.src).load_scalar(fx); let count = codegen_operand(fx, &inner.count).load_scalar(fx); let elem_size: u64 = pointee.size.bytes(); - let bytes = if elem_size != 1 { - fx.bcx.ins().imul_imm(count, elem_size as i64) - } else { - count - }; + let bytes = + if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count }; fx.bcx.call_memcpy(fx.cx.module.target_config(), dst, src, bytes); } } diff --git a/src/lib.rs b/src/lib.rs index 63fb1c4084463..2d18f585dc82e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,4 @@ -#![feature( - rustc_private, - decl_macro, - never_type, - hash_drain_filter -)] +#![feature(rustc_private, decl_macro, never_type, hash_drain_filter)] #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] #![warn(unreachable_pub)] From 7889a32c0fb764c1692ab33154668ef70992db64 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Mar 2021 13:33:03 +0100 Subject: [PATCH 48/51] Rustup to rustc 1.53.0-nightly (52e3dffa5 2021-03-25) --- build_sysroot/Cargo.lock | 8 ++++---- rust-toolchain | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build_sysroot/Cargo.lock b/build_sysroot/Cargo.lock index 225577268892d..09c5d7590ab86 100644 --- a/build_sysroot/Cargo.lock +++ b/build_sysroot/Cargo.lock @@ -110,9 +110,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ "compiler_builtins", "rustc-std-workspace-alloc", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "538c092e5586f4cdd7dd8078c4a79220e3e168880218124dcbce860f0ea938c6" +checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7" dependencies = [ "rustc-std-workspace-core", ] diff --git a/rust-toolchain b/rust-toolchain index a0b828e39a4d1..b3de18e555079 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-18" +channel = "nightly-2021-03-26" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] From f3e8f6dc0834134de85157c801d414e764ed6fef Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 26 Mar 2021 14:35:51 +0100 Subject: [PATCH 49/51] Rustfmt --- src/constant.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/constant.rs b/src/constant.rs index 1b64d6770d212..fcd41c844659d 100644 --- a/src/constant.rs +++ b/src/constant.rs @@ -124,7 +124,9 @@ pub(crate) fn codegen_constant<'tcx>( }; let const_val = match const_.val { ConstKind::Value(const_val) => const_val, - ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) if fx.tcx.is_static(def.did) => { + ConstKind::Unevaluated(ty::Unevaluated { def, substs, promoted }) + if fx.tcx.is_static(def.did) => + { assert!(substs.is_empty()); assert!(promoted.is_none()); From 94b51d14e6770f6e8cfec4bf4c0d5805caa58143 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Mar 2021 17:32:41 +0100 Subject: [PATCH 50/51] Make all compiler-builtins symbols hidden This matches cg_llvm Fixes #1152 --- src/base.rs | 8 ++------ src/compiler_builtins.rs | 41 ++++++++++++++++++++++++++++++++++++++++ src/driver/aot.rs | 5 ++--- src/driver/jit.rs | 11 ++++------- src/driver/mod.rs | 8 +++++++- src/lib.rs | 1 + src/linkage.rs | 2 ++ 7 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 src/compiler_builtins.rs diff --git a/src/base.rs b/src/base.rs index 7cd7bb1de4141..b34a29c25b92e 100644 --- a/src/base.rs +++ b/src/base.rs @@ -8,11 +8,7 @@ use rustc_target::abi::call::FnAbi; use crate::prelude::*; -pub(crate) fn codegen_fn<'tcx>( - cx: &mut crate::CodegenCx<'_, 'tcx>, - instance: Instance<'tcx>, - linkage: Linkage, -) { +pub(crate) fn codegen_fn<'tcx>(cx: &mut crate::CodegenCx<'_, 'tcx>, instance: Instance<'tcx>) { let tcx = cx.tcx; let _inst_guard = @@ -24,7 +20,7 @@ pub(crate) fn codegen_fn<'tcx>( // Declare function let name = tcx.symbol_name(instance).name.to_string(); let sig = get_function_sig(tcx, cx.module.isa().triple(), instance); - let func_id = cx.module.declare_function(&name, linkage, &sig).unwrap(); + let func_id = cx.module.declare_function(&name, Linkage::Local, &sig).unwrap(); cx.cached_context.clear(); diff --git a/src/compiler_builtins.rs b/src/compiler_builtins.rs new file mode 100644 index 0000000000000..177f850afb398 --- /dev/null +++ b/src/compiler_builtins.rs @@ -0,0 +1,41 @@ +macro builtin_functions($register:ident; $(fn $name:ident($($arg_name:ident: $arg_ty:ty),*) -> $ret_ty:ty;)*) { + #[cfg(feature = "jit")] + #[allow(improper_ctypes)] + extern "C" { + $(fn $name($($arg_name: $arg_ty),*) -> $ret_ty;)* + } + + #[cfg(feature = "jit")] + pub(crate) fn $register(builder: &mut cranelift_jit::JITBuilder) { + for &(name, val) in &[$((stringify!($name), $name as *const u8)),*] { + builder.symbol(name, val); + } + } +} + +builtin_functions! { + register_functions_for_jit; + + // integers + fn __multi3(a: i128, b: i128) -> i128; + fn __udivti3(n: u128, d: u128) -> u128; + fn __divti3(n: i128, d: i128) -> i128; + fn __umodti3(n: u128, d: u128) -> u128; + fn __modti3(n: i128, d: i128) -> i128; + fn __rust_u128_addo(a: u128, b: u128) -> (u128, bool); + fn __rust_i128_addo(a: i128, b: i128) -> (i128, bool); + fn __rust_u128_subo(a: u128, b: u128) -> (u128, bool); + fn __rust_i128_subo(a: i128, b: i128) -> (i128, bool); + fn __rust_u128_mulo(a: u128, b: u128) -> (u128, bool); + fn __rust_i128_mulo(a: i128, b: i128) -> (i128, bool); + + // floats + fn __floattisf(i: i128) -> f32; + fn __floattidf(i: i128) -> f64; + fn __floatuntisf(i: u128) -> f32; + fn __floatuntidf(i: u128) -> f64; + fn __fixsfti(f: f32) -> i128; + fn __fixdfti(f: f64) -> i128; + fn __fixunssfti(f: f32) -> u128; + fn __fixunsdfti(f: f64) -> u128; +} diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 3f3cdab058b06..ed3bdedddced5 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -119,11 +119,10 @@ fn module_codegen( tcx.sess.opts.debuginfo != DebugInfo::None, ); super::predefine_mono_items(&mut cx, &mono_items); - for (mono_item, (linkage, visibility)) in mono_items { - let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); + for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => { - cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); + cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst)); } MonoItem::Static(def_id) => { crate::constant::codegen_static(&mut cx.constants_cx, def_id) diff --git a/src/driver/jit.rs b/src/driver/jit.rs index 1b08b4169132d..dbe1ff083f0db 100644 --- a/src/driver/jit.rs +++ b/src/driver/jit.rs @@ -30,6 +30,7 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { let mut jit_builder = JITBuilder::with_isa(crate::build_isa(tcx.sess), cranelift_module::default_libcall_names()); jit_builder.hotswap(matches!(backend_config.codegen_mode, CodegenMode::JitLazy)); + crate::compiler_builtins::register_functions_for_jit(&mut jit_builder); jit_builder.symbols(imported_symbols); let mut jit_module = JITModule::new(jit_builder); assert_eq!(pointer_ty(tcx), jit_module.target_config().pointer_type()); @@ -47,15 +48,12 @@ pub(super) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! { super::time(tcx, "codegen mono items", || { super::predefine_mono_items(&mut cx, &mono_items); - for (mono_item, (linkage, visibility)) in mono_items { - let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); + for (mono_item, _) in mono_items { match mono_item { MonoItem::Fn(inst) => match backend_config.codegen_mode { CodegenMode::Aot => unreachable!(), CodegenMode::Jit => { - cx.tcx - .sess - .time("codegen fn", || crate::base::codegen_fn(&mut cx, inst, linkage)); + cx.tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, inst)); } CodegenMode::JitLazy => codegen_shim(&mut cx, inst), }, @@ -175,8 +173,7 @@ extern "C" fn __clif_jit_fn(instance_ptr: *const Instance<'static>) -> *const u8 jit_module.prepare_for_function_redefine(func_id).unwrap(); let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module, false); - tcx.sess - .time("codegen fn", || crate::base::codegen_fn(&mut cx, instance, Linkage::Export)); + tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, instance)); let (global_asm, _debug_context, unwind_context) = cx.finalize(); assert!(global_asm.is_empty()); diff --git a/src/driver/mod.rs b/src/driver/mod.rs index b994f28ffef5b..d49182a07b79e 100644 --- a/src/driver/mod.rs +++ b/src/driver/mod.rs @@ -44,13 +44,19 @@ fn predefine_mono_items<'tcx>( mono_items: &[(MonoItem<'tcx>, (RLinkage, Visibility))], ) { cx.tcx.sess.time("predefine functions", || { + let is_compiler_builtins = cx.tcx.is_compiler_builtins(LOCAL_CRATE); for &(mono_item, (linkage, visibility)) in mono_items { match mono_item { MonoItem::Fn(instance) => { let name = cx.tcx.symbol_name(instance).name.to_string(); let _inst_guard = crate::PrintOnPanic(|| format!("{:?} {}", instance, name)); let sig = get_function_sig(cx.tcx, cx.module.isa().triple(), instance); - let linkage = crate::linkage::get_clif_linkage(mono_item, linkage, visibility); + let linkage = crate::linkage::get_clif_linkage( + mono_item, + linkage, + visibility, + is_compiler_builtins, + ); cx.module.declare_function(&name, linkage, &sig).unwrap(); } MonoItem::Static(_) | MonoItem::GlobalAsm(_) => {} diff --git a/src/lib.rs b/src/lib.rs index 2d18f585dc82e..720d2a1253445 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,6 +48,7 @@ mod base; mod cast; mod codegen_i128; mod common; +mod compiler_builtins; mod constant; mod debuginfo; mod discriminant; diff --git a/src/linkage.rs b/src/linkage.rs index dc1e2107ce712..a564a59f72510 100644 --- a/src/linkage.rs +++ b/src/linkage.rs @@ -6,8 +6,10 @@ pub(crate) fn get_clif_linkage( mono_item: MonoItem<'_>, linkage: RLinkage, visibility: Visibility, + is_compiler_builtins: bool, ) -> Linkage { match (linkage, visibility) { + (RLinkage::External, Visibility::Default) if is_compiler_builtins => Linkage::Hidden, (RLinkage::External, Visibility::Default) => Linkage::Export, (RLinkage::Internal, Visibility::Default) => Linkage::Local, (RLinkage::External, Visibility::Hidden) => Linkage::Hidden, From 0969bc6dde001e01e7e1f58c8ccd7750f8a49ae1 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Mon, 29 Mar 2021 10:26:20 +0200 Subject: [PATCH 51/51] Rustup to rustc 1.53.0-nightly (4a20eb6a9 2021-03-28) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index b3de18e555079..2917fc7ee396d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2021-03-26" +channel = "nightly-2021-03-29" components = ["rust-src", "rustc-dev", "llvm-tools-preview"]