mirror of https://github.com/rust-lang/rust.git
Merge commit '2bb3996244cf1b89878da9e39841e9f6bf061602' into sync_cg_clif-2022-12-14
This commit is contained in:
parent
f7c76ad662
commit
98a276b589
|
@ -12,8 +12,6 @@ task:
|
||||||
folder: target
|
folder: target
|
||||||
prepare_script:
|
prepare_script:
|
||||||
- . $HOME/.cargo/env
|
- . $HOME/.cargo/env
|
||||||
- git config --global user.email "user@example.com"
|
|
||||||
- git config --global user.name "User"
|
|
||||||
- ./y.rs prepare
|
- ./y.rs prepare
|
||||||
test_script:
|
test_script:
|
||||||
- . $HOME/.cargo/env
|
- . $HOME/.cargo/env
|
||||||
|
|
|
@ -19,6 +19,7 @@ jobs:
|
||||||
- name: Rustfmt
|
- name: Rustfmt
|
||||||
run: |
|
run: |
|
||||||
cargo fmt --check
|
cargo fmt --check
|
||||||
|
rustfmt --check build_system/mod.rs
|
||||||
|
|
||||||
build:
|
build:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
@ -28,7 +29,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-20.04 # FIXME switch to ubuntu-22.04 once #1303 is fixed
|
||||||
env:
|
env:
|
||||||
TARGET_TRIPLE: x86_64-unknown-linux-gnu
|
TARGET_TRIPLE: x86_64-unknown-linux-gnu
|
||||||
- os: macos-latest
|
- os: macos-latest
|
||||||
|
@ -41,18 +42,22 @@ jobs:
|
||||||
- os: ubuntu-latest
|
- os: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
TARGET_TRIPLE: aarch64-unknown-linux-gnu
|
TARGET_TRIPLE: aarch64-unknown-linux-gnu
|
||||||
|
# s390x requires QEMU 6.1 or greater, we could build it from source, but ubuntu 22.04 comes with 6.2 by default
|
||||||
|
- os: ubuntu-latest
|
||||||
|
env:
|
||||||
|
TARGET_TRIPLE: s390x-unknown-linux-gnu
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache cargo installed crates
|
- name: Cache cargo installed crates
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin
|
path: ~/.cargo/bin
|
||||||
key: ${{ runner.os }}-cargo-installed-crates
|
key: ${{ runner.os }}-cargo-installed-crates
|
||||||
|
|
||||||
- name: Cache cargo registry and index
|
- name: Cache cargo registry and index
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
|
@ -60,9 +65,9 @@ jobs:
|
||||||
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Cache cargo target dir
|
- name: Cache cargo target dir
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: target
|
path: build/cg_clif
|
||||||
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Install MinGW toolchain and wine
|
- name: Install MinGW toolchain and wine
|
||||||
|
@ -78,11 +83,14 @@ jobs:
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user
|
sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user
|
||||||
|
|
||||||
- name: Prepare dependencies
|
- name: Install s390x toolchain and qemu
|
||||||
|
if: matrix.env.TARGET_TRIPLE == 's390x-unknown-linux-gnu'
|
||||||
run: |
|
run: |
|
||||||
git config --global user.email "user@example.com"
|
sudo apt-get update
|
||||||
git config --global user.name "User"
|
sudo apt-get install -y gcc-s390x-linux-gnu qemu-user
|
||||||
./y.rs prepare
|
|
||||||
|
- name: Prepare dependencies
|
||||||
|
run: ./y.rs prepare
|
||||||
|
|
||||||
- name: Build without unstable features
|
- name: Build without unstable features
|
||||||
env:
|
env:
|
||||||
|
@ -110,7 +118,7 @@ jobs:
|
||||||
./y.rs test
|
./y.rs test
|
||||||
|
|
||||||
- name: Package prebuilt cg_clif
|
- name: Package prebuilt cg_clif
|
||||||
run: tar cvfJ cg_clif.tar.xz build
|
run: tar cvfJ cg_clif.tar.xz dist
|
||||||
|
|
||||||
- name: Upload prebuilt cg_clif
|
- name: Upload prebuilt cg_clif
|
||||||
if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu'
|
if: matrix.env.TARGET_TRIPLE != 'x86_64-pc-windows-gnu'
|
||||||
|
@ -121,7 +129,7 @@ jobs:
|
||||||
|
|
||||||
- name: Upload prebuilt cg_clif (cross compile)
|
- name: Upload prebuilt cg_clif (cross compile)
|
||||||
if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
|
if: matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: cg_clif-${{ runner.os }}-cross-x86_64-mingw
|
name: cg_clif-${{ runner.os }}-cross-x86_64-mingw
|
||||||
path: cg_clif.tar.xz
|
path: cg_clif.tar.xz
|
||||||
|
@ -147,13 +155,13 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache cargo installed crates
|
- name: Cache cargo installed crates
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin
|
path: ~/.cargo/bin
|
||||||
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-installed-crates
|
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-installed-crates
|
||||||
|
|
||||||
- name: Cache cargo registry and index
|
- name: Cache cargo registry and index
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
|
@ -161,9 +169,9 @@ jobs:
|
||||||
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Cache cargo target dir
|
- name: Cache cargo target dir
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: target
|
path: build/cg_clif
|
||||||
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
key: ${{ runner.os }}-${{ matrix.env.TARGET_TRIPLE }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Set MinGW as the default toolchain
|
- name: Set MinGW as the default toolchain
|
||||||
|
@ -172,8 +180,6 @@ jobs:
|
||||||
|
|
||||||
- name: Prepare dependencies
|
- name: Prepare dependencies
|
||||||
run: |
|
run: |
|
||||||
git config --global user.email "user@example.com"
|
|
||||||
git config --global user.name "User"
|
|
||||||
git config --global core.autocrlf false
|
git config --global core.autocrlf false
|
||||||
rustc y.rs -o y.exe -g
|
rustc y.rs -o y.exe -g
|
||||||
./y.exe prepare
|
./y.exe prepare
|
||||||
|
@ -212,10 +218,10 @@ jobs:
|
||||||
|
|
||||||
- name: Package prebuilt cg_clif
|
- name: Package prebuilt cg_clif
|
||||||
# don't use compression as xzip isn't supported by tar on windows and bzip2 hangs
|
# don't use compression as xzip isn't supported by tar on windows and bzip2 hangs
|
||||||
run: tar cvf cg_clif.tar build
|
run: tar cvf cg_clif.tar dist
|
||||||
|
|
||||||
- name: Upload prebuilt cg_clif
|
- name: Upload prebuilt cg_clif
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: cg_clif-${{ matrix.env.TARGET_TRIPLE }}
|
name: cg_clif-${{ matrix.env.TARGET_TRIPLE }}
|
||||||
path: cg_clif.tar
|
path: cg_clif.tar
|
||||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache cargo installed crates
|
- name: Cache cargo installed crates
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin
|
path: ~/.cargo/bin
|
||||||
key: ubuntu-latest-cargo-installed-crates
|
key: ubuntu-latest-cargo-installed-crates
|
||||||
|
|
|
@ -11,13 +11,13 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache cargo installed crates
|
- name: Cache cargo installed crates
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin
|
path: ~/.cargo/bin
|
||||||
key: ${{ runner.os }}-cargo-installed-crates
|
key: ${{ runner.os }}-cargo-installed-crates
|
||||||
|
|
||||||
- name: Cache cargo registry and index
|
- name: Cache cargo registry and index
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
|
@ -25,9 +25,9 @@ jobs:
|
||||||
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Cache cargo target dir
|
- name: Cache cargo target dir
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: target
|
path: build/cg_clif
|
||||||
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Prepare dependencies
|
- name: Prepare dependencies
|
||||||
|
@ -49,13 +49,13 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Cache cargo installed crates
|
- name: Cache cargo installed crates
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo/bin
|
path: ~/.cargo/bin
|
||||||
key: ${{ runner.os }}-cargo-installed-crates
|
key: ${{ runner.os }}-cargo-installed-crates
|
||||||
|
|
||||||
- name: Cache cargo registry and index
|
- name: Cache cargo registry and index
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.cargo/registry
|
~/.cargo/registry
|
||||||
|
@ -63,9 +63,9 @@ jobs:
|
||||||
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-registry-and-index-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Cache cargo target dir
|
- name: Cache cargo target dir
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: target
|
path: build/cg_clif
|
||||||
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('rust-toolchain', '**/Cargo.lock') }}
|
||||||
|
|
||||||
- name: Prepare dependencies
|
- name: Prepare dependencies
|
||||||
|
|
|
@ -14,5 +14,6 @@ perf.data.old
|
||||||
/build_sysroot/sysroot_src
|
/build_sysroot/sysroot_src
|
||||||
/build_sysroot/compiler-builtins
|
/build_sysroot/compiler-builtins
|
||||||
/build_sysroot/rustc_version
|
/build_sysroot/rustc_version
|
||||||
|
/dist
|
||||||
/rust
|
/rust
|
||||||
/download
|
/download
|
||||||
|
|
|
@ -4,16 +4,10 @@
|
||||||
"rust-analyzer.imports.granularity.enforce": true,
|
"rust-analyzer.imports.granularity.enforce": true,
|
||||||
"rust-analyzer.imports.granularity.group": "module",
|
"rust-analyzer.imports.granularity.group": "module",
|
||||||
"rust-analyzer.imports.prefix": "crate",
|
"rust-analyzer.imports.prefix": "crate",
|
||||||
"rust-analyzer.cargo.features": ["unstable-features"],
|
"rust-analyzer.cargo.features": ["unstable-features", "__check_build_system_using_ra"],
|
||||||
"rust-analyzer.linkedProjects": [
|
"rust-analyzer.linkedProjects": [
|
||||||
"./Cargo.toml",
|
"./Cargo.toml",
|
||||||
//"./build_sysroot/sysroot_src/library/std/Cargo.toml",
|
|
||||||
{
|
{
|
||||||
"roots": [
|
|
||||||
"./example/mini_core.rs",
|
|
||||||
"./example/mini_core_hello_world.rs",
|
|
||||||
"./example/mod_bench.rs"
|
|
||||||
],
|
|
||||||
"crates": [
|
"crates": [
|
||||||
{
|
{
|
||||||
"root_module": "./example/mini_core.rs",
|
"root_module": "./example/mini_core.rs",
|
||||||
|
@ -36,34 +30,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"roots": ["./example/std_example.rs"],
|
"sysroot_src": "./build_sysroot/sysroot_src/library",
|
||||||
"crates": [
|
"crates": [
|
||||||
{
|
{
|
||||||
"root_module": "./example/std_example.rs",
|
"root_module": "./example/std_example.rs",
|
||||||
"edition": "2018",
|
"edition": "2015",
|
||||||
"deps": [{ "crate": 1, "name": "std" }],
|
|
||||||
"cfg": [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"root_module": "./build_sysroot/sysroot_src/library/std/src/lib.rs",
|
|
||||||
"edition": "2018",
|
|
||||||
"deps": [],
|
|
||||||
"cfg": [],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"roots": ["./y.rs"],
|
|
||||||
"crates": [
|
|
||||||
{
|
|
||||||
"root_module": "./y.rs",
|
|
||||||
"edition": "2018",
|
|
||||||
"deps": [{ "crate": 1, "name": "std" }],
|
|
||||||
"cfg": [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"root_module": "./build_sysroot/sysroot_src/library/std/src/lib.rs",
|
|
||||||
"edition": "2018",
|
|
||||||
"deps": [],
|
"deps": [],
|
||||||
"cfg": [],
|
"cfg": [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -15,9 +15,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.60"
|
version = "1.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
|
checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayvec"
|
name = "arrayvec"
|
||||||
|
@ -39,9 +39,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.11.0"
|
version = "3.11.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
|
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byteorder"
|
name = "byteorder"
|
||||||
|
@ -57,24 +57,25 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-bforest"
|
name = "cranelift-bforest"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44409ccf2d0f663920cab563d2b79fcd6b2e9a2bcc6e929fef76c8f82ad6c17a"
|
checksum = "b62c772976416112fa4484cbd688cb6fb35fd430005c1c586224fc014018abad"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen"
|
name = "cranelift-codegen"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "98de2018ad96eb97f621f7d6b900a0cc661aec8d02ea4a50e56ecb48e5a2fcaf"
|
checksum = "9b40ed2dd13c2ac7e24f88a3090c68ad3414eb1d066a95f8f1f7b3b819cb4e46"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"cranelift-bforest",
|
"cranelift-bforest",
|
||||||
"cranelift-codegen-meta",
|
"cranelift-codegen-meta",
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
|
"cranelift-egraph",
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
"cranelift-isle",
|
"cranelift-isle",
|
||||||
"gimli",
|
"gimli",
|
||||||
|
@ -86,30 +87,44 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-meta"
|
name = "cranelift-codegen-meta"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5287ce36e6c4758fbaf298bd1a8697ad97a4f2375a3d1b61142ea538db4877e5"
|
checksum = "bb927a8f1c27c34ee3759b6b0ffa528d2330405d5cc4511f0cab33fe2279f4b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen-shared",
|
"cranelift-codegen-shared",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-codegen-shared"
|
name = "cranelift-codegen-shared"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2855c24219e2f08827f3f4ffb2da92e134ae8d8ecc185b11ec8f9878cf5f588e"
|
checksum = "43dfa417b884a9ab488d95fd6b93b25e959321fe7bfd7a0a960ba5d7fb7ab927"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cranelift-egraph"
|
||||||
|
version = "0.90.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0a66b39785efd8513d2cca967ede56d6cc57c8d7986a595c7c47d0c78de8dce"
|
||||||
|
dependencies = [
|
||||||
|
"cranelift-entity",
|
||||||
|
"fxhash",
|
||||||
|
"hashbrown",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-entity"
|
name = "cranelift-entity"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b65673279d75d34bf11af9660ae2dbd1c22e6d28f163f5c72f4e1dc56d56103"
|
checksum = "0637ffde963cb5d759bc4d454cfa364b6509e6c74cdaa21298add0ed9276f346"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-frontend"
|
name = "cranelift-frontend"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ed2b3d7a4751163f6c4a349205ab1b7d9c00eecf19dcea48592ef1f7688eefc"
|
checksum = "fb72b8342685e850cb037350418f62cc4fc55d6c2eb9c7ca01b82f9f1a6f3d56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"log",
|
"log",
|
||||||
|
@ -119,15 +134,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-isle"
|
name = "cranelift-isle"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3be64cecea9d90105fc6a2ba2d003e98c867c1d6c4c86cc878f97ad9fb916293"
|
checksum = "850579cb9e4b448f7c301f1e6e6cbad99abe3f1f1d878a4994cb66e33c6db8cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-jit"
|
name = "cranelift-jit"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f98ed42a70a0c9c388e34ec9477f57fc7300f541b1e5136a0e2ea02b1fac6015"
|
checksum = "9add822ad66dcbe152b5ab57de10240a2df4505099f2f6c27159acb711890bd4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -138,14 +153,15 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"region",
|
"region",
|
||||||
"target-lexicon",
|
"target-lexicon",
|
||||||
|
"wasmtime-jit-icache-coherence",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-module"
|
name = "cranelift-module"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d658ac7f156708bfccb647216cc8b9387469f50d352ba4ad80150541e4ae2d49"
|
checksum = "406b772626fc2664864cf947f3895a23b619895c7fff635f3622e2d857f4492f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -153,9 +169,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-native"
|
name = "cranelift-native"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c4a03a6ac1b063e416ca4b93f6247978c991475e8271465340caa6f92f3c16a4"
|
checksum = "2d0a279e5bcba3e0466c734d8d8eb6bfc1ad29e95c37f3e4955b492b5616335e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -164,9 +180,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cranelift-object"
|
name = "cranelift-object"
|
||||||
version = "0.88.1"
|
version = "0.90.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eef0b4119b645b870a43a036d76c0ada3a076b1f82e8b8487659304c8b09049b"
|
checksum = "39793c550f0c1d7db96c2fc1324583670c8143befe6edbfbaf1c68aba53be983"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
|
@ -185,6 +201,12 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fallible-iterator"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fxhash"
|
name = "fxhash"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -196,9 +218,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.7"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -211,7 +233,9 @@ version = "0.26.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"fallible-iterator",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
|
"stable_deref_trait",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -225,9 +249,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.9.1"
|
version = "1.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
@ -235,15 +259,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.127"
|
version = "0.2.138"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "505e71a4706fa491e9b1b55f51b95d4037d0821ee40131190475f692b35b009b"
|
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
version = "0.7.3"
|
version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
|
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -287,15 +311,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.13.0"
|
version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
|
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regalloc2"
|
name = "regalloc2"
|
||||||
version = "0.3.2"
|
version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d43a209257d978ef079f3d446331d0f1794f5e0fc19b306a199983857833a779"
|
checksum = "91b2eab54204ea0117fe9a060537e0b07a4e72f7c7d182361ecc346cab2240e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"log",
|
"log",
|
||||||
|
@ -342,15 +366,21 @@ checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "smallvec"
|
name = "smallvec"
|
||||||
version = "1.9.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "target-lexicon"
|
name = "target-lexicon"
|
||||||
version = "0.12.4"
|
version = "0.12.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1"
|
checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
|
@ -364,6 +394,17 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasmtime-jit-icache-coherence"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6bbabb309c06cc238ee91b1455b748c45f0bdcab0dda2c2db85b0a1e69fcb66"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
|
20
Cargo.toml
20
Cargo.toml
|
@ -3,17 +3,24 @@ name = "rustc_codegen_cranelift"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
# This is used just to teach rust-analyzer how to check the build system. required-features is used
|
||||||
|
# to disable it for regular builds.
|
||||||
|
name = "y"
|
||||||
|
path = "./y.rs"
|
||||||
|
required-features = ["__check_build_system_using_ra"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["dylib"]
|
crate-type = ["dylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# These have to be in sync with each other
|
# These have to be in sync with each other
|
||||||
cranelift-codegen = { version = "0.88.1", features = ["unwind", "all-arch"] }
|
cranelift-codegen = { version = "0.90.1", features = ["unwind", "all-arch"] }
|
||||||
cranelift-frontend = "0.88.1"
|
cranelift-frontend = "0.90.1"
|
||||||
cranelift-module = "0.88.1"
|
cranelift-module = "0.90.1"
|
||||||
cranelift-native = "0.88.1"
|
cranelift-native = "0.90.1"
|
||||||
cranelift-jit = { version = "0.88.1", optional = true }
|
cranelift-jit = { version = "0.90.1", optional = true }
|
||||||
cranelift-object = "0.88.1"
|
cranelift-object = "0.90.1"
|
||||||
target-lexicon = "0.12.0"
|
target-lexicon = "0.12.0"
|
||||||
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
|
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
|
||||||
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||||
|
@ -39,6 +46,7 @@ smallvec = "1.8.1"
|
||||||
unstable-features = ["jit", "inline_asm"]
|
unstable-features = ["jit", "inline_asm"]
|
||||||
jit = ["cranelift-jit", "libloading"]
|
jit = ["cranelift-jit", "libloading"]
|
||||||
inline_asm = []
|
inline_asm = []
|
||||||
|
__check_build_system_using_ra = []
|
||||||
|
|
||||||
[package.metadata.rust-analyzer]
|
[package.metadata.rust-analyzer]
|
||||||
rustc_private = true
|
rustc_private = true
|
||||||
|
|
|
@ -37,7 +37,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
|
||||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/cargo-clif build
|
$ $cg_clif_dir/dist/cargo-clif build
|
||||||
```
|
```
|
||||||
|
|
||||||
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||||
|
|
|
@ -4,9 +4,9 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
version = "0.16.0"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd"
|
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"gimli",
|
"gimli",
|
||||||
|
@ -32,27 +32,11 @@ dependencies = [
|
||||||
"core",
|
"core",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.73"
|
version = "1.0.77"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg-if"
|
|
||||||
version = "0.1.10"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
|
||||||
dependencies = [
|
|
||||||
"compiler_builtins",
|
|
||||||
"rustc-std-workspace-core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -66,9 +50,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compiler_builtins"
|
name = "compiler_builtins"
|
||||||
version = "0.1.82"
|
version = "0.1.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "18cd7635fea7bb481ea543b392789844c1ad581299da70184c7175ce3af76603"
|
checksum = "13e81c6cd7ab79f51a0c927d22858d61ad12bd0b3865f0b13ece02a4486aeabb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
@ -111,9 +95,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gimli"
|
name = "gimli"
|
||||||
version = "0.25.0"
|
version = "0.26.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7"
|
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
|
@ -145,9 +129,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.135"
|
version = "0.2.138"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
|
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
]
|
]
|
||||||
|
@ -164,12 +148,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.4.4"
|
version = "0.5.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"adler",
|
"adler",
|
||||||
"autocfg",
|
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
"rustc-std-workspace-core",
|
"rustc-std-workspace-core",
|
||||||
|
@ -177,9 +160,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.26.2"
|
version = "0.29.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39f37e50073ccad23b6d09bcb5b263f4e76d3bb6038e4a3c08e52162ffa8abc2"
|
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -192,7 +175,7 @@ name = "panic_abort"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc",
|
"alloc",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"core",
|
"core",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -203,7 +186,7 @@ name = "panic_unwind"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"alloc",
|
"alloc",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"core",
|
"core",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -255,7 +238,7 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"addr2line",
|
"addr2line",
|
||||||
"alloc",
|
"alloc",
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"core",
|
"core",
|
||||||
"dlmalloc",
|
"dlmalloc",
|
||||||
|
@ -277,7 +260,7 @@ dependencies = [
|
||||||
name = "std_detect"
|
name = "std_detect"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"libc",
|
"libc",
|
||||||
"rustc-std-workspace-alloc",
|
"rustc-std-workspace-alloc",
|
||||||
|
@ -299,7 +282,7 @@ dependencies = [
|
||||||
name = "test"
|
name = "test"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if",
|
||||||
"core",
|
"core",
|
||||||
"getopts",
|
"getopts",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -325,7 +308,7 @@ name = "unwind"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if",
|
||||||
"compiler_builtins",
|
"compiler_builtins",
|
||||||
"core",
|
"core",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
|
@ -1,16 +1,21 @@
|
||||||
use std::env;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use super::build_sysroot;
|
use super::build_sysroot;
|
||||||
use super::config;
|
use super::config;
|
||||||
use super::prepare;
|
use super::path::Dirs;
|
||||||
use super::utils::{cargo_command, spawn_and_wait};
|
use super::prepare::GitRepo;
|
||||||
|
use super::utils::{spawn_and_wait, CargoProject, Compiler};
|
||||||
use super::SysrootKind;
|
use super::SysrootKind;
|
||||||
|
|
||||||
|
pub(crate) static ABI_CAFE_REPO: GitRepo =
|
||||||
|
GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
|
||||||
|
|
||||||
|
static ABI_CAFE: CargoProject = CargoProject::new(&ABI_CAFE_REPO.source_dir(), "abi_cafe");
|
||||||
|
|
||||||
pub(crate) fn run(
|
pub(crate) fn run(
|
||||||
channel: &str,
|
channel: &str,
|
||||||
sysroot_kind: SysrootKind,
|
sysroot_kind: SysrootKind,
|
||||||
target_dir: &Path,
|
dirs: &Dirs,
|
||||||
cg_clif_dylib: &Path,
|
cg_clif_dylib: &Path,
|
||||||
host_triple: &str,
|
host_triple: &str,
|
||||||
target_triple: &str,
|
target_triple: &str,
|
||||||
|
@ -27,26 +32,25 @@ pub(crate) fn run(
|
||||||
|
|
||||||
eprintln!("Building sysroot for abi-cafe");
|
eprintln!("Building sysroot for abi-cafe");
|
||||||
build_sysroot::build_sysroot(
|
build_sysroot::build_sysroot(
|
||||||
|
dirs,
|
||||||
channel,
|
channel,
|
||||||
sysroot_kind,
|
sysroot_kind,
|
||||||
target_dir,
|
|
||||||
cg_clif_dylib,
|
cg_clif_dylib,
|
||||||
host_triple,
|
host_triple,
|
||||||
target_triple,
|
target_triple,
|
||||||
);
|
);
|
||||||
|
|
||||||
eprintln!("Running abi-cafe");
|
eprintln!("Running abi-cafe");
|
||||||
let abi_cafe_path = prepare::ABI_CAFE.source_dir();
|
|
||||||
env::set_current_dir(abi_cafe_path.clone()).unwrap();
|
|
||||||
|
|
||||||
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
|
let pairs = ["rustc_calls_cgclif", "cgclif_calls_rustc", "cgclif_calls_cc", "cc_calls_cgclif"];
|
||||||
|
|
||||||
let mut cmd = cargo_command("cargo", "run", Some(target_triple), &abi_cafe_path);
|
let mut cmd = ABI_CAFE.run(&Compiler::host(), dirs);
|
||||||
cmd.arg("--");
|
cmd.arg("--");
|
||||||
cmd.arg("--pairs");
|
cmd.arg("--pairs");
|
||||||
cmd.args(pairs);
|
cmd.args(pairs);
|
||||||
cmd.arg("--add-rustc-codegen-backend");
|
cmd.arg("--add-rustc-codegen-backend");
|
||||||
cmd.arg(format!("cgclif:{}", cg_clif_dylib.display()));
|
cmd.arg(format!("cgclif:{}", cg_clif_dylib.display()));
|
||||||
|
cmd.current_dir(ABI_CAFE.source_dir(dirs));
|
||||||
|
|
||||||
spawn_and_wait(cmd);
|
spawn_and_wait(cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use super::path::{Dirs, RelPath};
|
||||||
use super::rustc_info::get_file_name;
|
use super::rustc_info::get_file_name;
|
||||||
use super::utils::{cargo_command, is_ci};
|
use super::utils::{is_ci, CargoProject, Compiler};
|
||||||
|
|
||||||
|
static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
|
||||||
|
|
||||||
pub(crate) fn build_backend(
|
pub(crate) fn build_backend(
|
||||||
|
dirs: &Dirs,
|
||||||
channel: &str,
|
channel: &str,
|
||||||
host_triple: &str,
|
host_triple: &str,
|
||||||
use_unstable_features: bool,
|
use_unstable_features: bool,
|
||||||
) -> PathBuf {
|
) -> PathBuf {
|
||||||
let source_dir = std::env::current_dir().unwrap();
|
let mut cmd = CG_CLIF.build(&Compiler::host(), dirs);
|
||||||
let mut cmd = cargo_command("cargo", "build", Some(host_triple), &source_dir);
|
|
||||||
|
|
||||||
cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode
|
cmd.env("CARGO_BUILD_INCREMENTAL", "true"); // Force incr comp even in release mode
|
||||||
|
|
||||||
|
@ -41,8 +44,8 @@ pub(crate) fn build_backend(
|
||||||
eprintln!("[BUILD] rustc_codegen_cranelift");
|
eprintln!("[BUILD] rustc_codegen_cranelift");
|
||||||
super::utils::spawn_and_wait(cmd);
|
super::utils::spawn_and_wait(cmd);
|
||||||
|
|
||||||
source_dir
|
CG_CLIF
|
||||||
.join("target")
|
.target_dir(dirs)
|
||||||
.join(host_triple)
|
.join(host_triple)
|
||||||
.join(channel)
|
.join(channel)
|
||||||
.join(get_file_name("rustc_codegen_cranelift", "dylib"))
|
.join(get_file_name("rustc_codegen_cranelift", "dylib"))
|
||||||
|
|
|
@ -1,57 +1,60 @@
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::process::{self, Command};
|
use std::process::{self, Command};
|
||||||
|
|
||||||
|
use super::path::{Dirs, RelPath};
|
||||||
use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
|
use super::rustc_info::{get_file_name, get_rustc_version, get_wrapper_file_name};
|
||||||
use super::utils::{cargo_command, spawn_and_wait, try_hard_link};
|
use super::utils::{spawn_and_wait, try_hard_link, CargoProject, Compiler};
|
||||||
use super::SysrootKind;
|
use super::SysrootKind;
|
||||||
|
|
||||||
|
static DIST_DIR: RelPath = RelPath::DIST;
|
||||||
|
static BIN_DIR: RelPath = RelPath::DIST.join("bin");
|
||||||
|
static LIB_DIR: RelPath = RelPath::DIST.join("lib");
|
||||||
|
static RUSTLIB_DIR: RelPath = LIB_DIR.join("rustlib");
|
||||||
|
|
||||||
pub(crate) fn build_sysroot(
|
pub(crate) fn build_sysroot(
|
||||||
|
dirs: &Dirs,
|
||||||
channel: &str,
|
channel: &str,
|
||||||
sysroot_kind: SysrootKind,
|
sysroot_kind: SysrootKind,
|
||||||
target_dir: &Path,
|
|
||||||
cg_clif_dylib_src: &Path,
|
cg_clif_dylib_src: &Path,
|
||||||
host_triple: &str,
|
host_triple: &str,
|
||||||
target_triple: &str,
|
target_triple: &str,
|
||||||
) {
|
) {
|
||||||
eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
|
eprintln!("[BUILD] sysroot {:?}", sysroot_kind);
|
||||||
|
|
||||||
if target_dir.exists() {
|
DIST_DIR.ensure_fresh(dirs);
|
||||||
fs::remove_dir_all(target_dir).unwrap();
|
BIN_DIR.ensure_exists(dirs);
|
||||||
}
|
LIB_DIR.ensure_exists(dirs);
|
||||||
fs::create_dir_all(target_dir.join("bin")).unwrap();
|
|
||||||
fs::create_dir_all(target_dir.join("lib")).unwrap();
|
|
||||||
|
|
||||||
// Copy the backend
|
// Copy the backend
|
||||||
let cg_clif_dylib_path = target_dir
|
let cg_clif_dylib_path = if cfg!(windows) {
|
||||||
.join(if cfg!(windows) {
|
// Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
|
||||||
// Windows doesn't have rpath support, so the cg_clif dylib needs to be next to the
|
// binaries.
|
||||||
// binaries.
|
BIN_DIR
|
||||||
"bin"
|
} else {
|
||||||
} else {
|
LIB_DIR
|
||||||
"lib"
|
}
|
||||||
})
|
.to_path(dirs)
|
||||||
.join(get_file_name("rustc_codegen_cranelift", "dylib"));
|
.join(get_file_name("rustc_codegen_cranelift", "dylib"));
|
||||||
try_hard_link(cg_clif_dylib_src, &cg_clif_dylib_path);
|
try_hard_link(cg_clif_dylib_src, &cg_clif_dylib_path);
|
||||||
|
|
||||||
// Build and copy rustc and cargo wrappers
|
// Build and copy rustc and cargo wrappers
|
||||||
for wrapper in ["rustc-clif", "cargo-clif"] {
|
for wrapper in ["rustc-clif", "rustdoc-clif", "cargo-clif"] {
|
||||||
let wrapper_name = get_wrapper_file_name(wrapper, "bin");
|
let wrapper_name = get_wrapper_file_name(wrapper, "bin");
|
||||||
|
|
||||||
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
let mut build_cargo_wrapper_cmd = Command::new("rustc");
|
||||||
build_cargo_wrapper_cmd
|
build_cargo_wrapper_cmd
|
||||||
.arg(PathBuf::from("scripts").join(format!("{wrapper}.rs")))
|
.arg(RelPath::SCRIPTS.to_path(dirs).join(&format!("{wrapper}.rs")))
|
||||||
.arg("-o")
|
.arg("-o")
|
||||||
.arg(target_dir.join(wrapper_name))
|
.arg(DIST_DIR.to_path(dirs).join(wrapper_name))
|
||||||
.arg("-g");
|
.arg("-g");
|
||||||
spawn_and_wait(build_cargo_wrapper_cmd);
|
spawn_and_wait(build_cargo_wrapper_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
let default_sysroot = super::rustc_info::get_default_sysroot();
|
let default_sysroot = super::rustc_info::get_default_sysroot();
|
||||||
|
|
||||||
let rustlib = target_dir.join("lib").join("rustlib");
|
let host_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(host_triple).join("lib");
|
||||||
let host_rustlib_lib = rustlib.join(host_triple).join("lib");
|
let target_rustlib_lib = RUSTLIB_DIR.to_path(dirs).join(target_triple).join("lib");
|
||||||
let target_rustlib_lib = rustlib.join(target_triple).join("lib");
|
|
||||||
fs::create_dir_all(&host_rustlib_lib).unwrap();
|
fs::create_dir_all(&host_rustlib_lib).unwrap();
|
||||||
fs::create_dir_all(&target_rustlib_lib).unwrap();
|
fs::create_dir_all(&target_rustlib_lib).unwrap();
|
||||||
|
|
||||||
|
@ -112,24 +115,18 @@ pub(crate) fn build_sysroot(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SysrootKind::Clif => {
|
SysrootKind::Clif => {
|
||||||
build_clif_sysroot_for_triple(
|
build_clif_sysroot_for_triple(dirs, channel, host_triple, &cg_clif_dylib_path, None);
|
||||||
channel,
|
|
||||||
target_dir,
|
|
||||||
host_triple,
|
|
||||||
&cg_clif_dylib_path,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
if host_triple != target_triple {
|
if host_triple != target_triple {
|
||||||
// When cross-compiling it is often necessary to manually pick the right linker
|
// When cross-compiling it is often necessary to manually pick the right linker
|
||||||
let linker = if target_triple == "aarch64-unknown-linux-gnu" {
|
let linker = match target_triple {
|
||||||
Some("aarch64-linux-gnu-gcc")
|
"aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu-gcc"),
|
||||||
} else {
|
"s390x-unknown-linux-gnu" => Some("s390x-linux-gnu-gcc"),
|
||||||
None
|
_ => None,
|
||||||
};
|
};
|
||||||
build_clif_sysroot_for_triple(
|
build_clif_sysroot_for_triple(
|
||||||
|
dirs,
|
||||||
channel,
|
channel,
|
||||||
target_dir,
|
|
||||||
target_triple,
|
target_triple,
|
||||||
&cg_clif_dylib_path,
|
&cg_clif_dylib_path,
|
||||||
linker,
|
linker,
|
||||||
|
@ -142,21 +139,26 @@ pub(crate) fn build_sysroot(
|
||||||
let file = file.unwrap().path();
|
let file = file.unwrap().path();
|
||||||
let filename = file.file_name().unwrap().to_str().unwrap();
|
let filename = file.file_name().unwrap().to_str().unwrap();
|
||||||
if filename.contains("std-") && !filename.contains(".rlib") {
|
if filename.contains("std-") && !filename.contains(".rlib") {
|
||||||
try_hard_link(&file, target_dir.join("lib").join(file.file_name().unwrap()));
|
try_hard_link(&file, LIB_DIR.to_path(dirs).join(file.file_name().unwrap()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME move to download/ or dist/
|
||||||
|
pub(crate) static SYSROOT_RUSTC_VERSION: RelPath = RelPath::BUILD_SYSROOT.join("rustc_version");
|
||||||
|
pub(crate) static SYSROOT_SRC: RelPath = RelPath::BUILD_SYSROOT.join("sysroot_src");
|
||||||
|
static STANDARD_LIBRARY: CargoProject = CargoProject::new(&RelPath::BUILD_SYSROOT, "build_sysroot");
|
||||||
|
|
||||||
fn build_clif_sysroot_for_triple(
|
fn build_clif_sysroot_for_triple(
|
||||||
|
dirs: &Dirs,
|
||||||
channel: &str,
|
channel: &str,
|
||||||
target_dir: &Path,
|
|
||||||
triple: &str,
|
triple: &str,
|
||||||
cg_clif_dylib_path: &Path,
|
cg_clif_dylib_path: &Path,
|
||||||
linker: Option<&str>,
|
linker: Option<&str>,
|
||||||
) {
|
) {
|
||||||
match fs::read_to_string(Path::new("build_sysroot").join("rustc_version")) {
|
match fs::read_to_string(SYSROOT_RUSTC_VERSION.to_path(dirs)) {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
|
eprintln!("Failed to get rustc version for patched sysroot source: {}", e);
|
||||||
eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
|
eprintln!("Hint: Try `./y.rs prepare` to patch the sysroot source");
|
||||||
|
@ -174,7 +176,7 @@ fn build_clif_sysroot_for_triple(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let build_dir = Path::new("build_sysroot").join("target").join(triple).join(channel);
|
let build_dir = STANDARD_LIBRARY.target_dir(dirs).join(triple).join(channel);
|
||||||
|
|
||||||
if !super::config::get_bool("keep_sysroot") {
|
if !super::config::get_bool("keep_sysroot") {
|
||||||
// Cleanup the deps dir, but keep build scripts and the incremental cache for faster
|
// Cleanup the deps dir, but keep build scripts and the incremental cache for faster
|
||||||
|
@ -185,27 +187,27 @@ fn build_clif_sysroot_for_triple(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build sysroot
|
// Build sysroot
|
||||||
let mut build_cmd = cargo_command("cargo", "build", Some(triple), Path::new("build_sysroot"));
|
|
||||||
let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
|
let mut rustflags = "-Zforce-unstable-if-unmarked -Cpanic=abort".to_string();
|
||||||
rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
|
rustflags.push_str(&format!(" -Zcodegen-backend={}", cg_clif_dylib_path.to_str().unwrap()));
|
||||||
rustflags.push_str(&format!(" --sysroot={}", target_dir.to_str().unwrap()));
|
rustflags.push_str(&format!(" --sysroot={}", DIST_DIR.to_path(dirs).to_str().unwrap()));
|
||||||
if channel == "release" {
|
if channel == "release" {
|
||||||
build_cmd.arg("--release");
|
|
||||||
rustflags.push_str(" -Zmir-opt-level=3");
|
rustflags.push_str(" -Zmir-opt-level=3");
|
||||||
}
|
}
|
||||||
if let Some(linker) = linker {
|
if let Some(linker) = linker {
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
write!(rustflags, " -Clinker={}", linker).unwrap();
|
write!(rustflags, " -Clinker={}", linker).unwrap();
|
||||||
}
|
}
|
||||||
build_cmd.env("RUSTFLAGS", rustflags);
|
let mut compiler = Compiler::with_triple(triple.to_owned());
|
||||||
|
compiler.rustflags = rustflags;
|
||||||
|
let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs);
|
||||||
|
if channel == "release" {
|
||||||
|
build_cmd.arg("--release");
|
||||||
|
}
|
||||||
build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
|
build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
|
||||||
spawn_and_wait(build_cmd);
|
spawn_and_wait(build_cmd);
|
||||||
|
|
||||||
// Copy all relevant files to the sysroot
|
// Copy all relevant files to the sysroot
|
||||||
for entry in
|
for entry in fs::read_dir(build_dir.join("deps")).unwrap() {
|
||||||
fs::read_dir(Path::new("build_sysroot/target").join(triple).join(channel).join("deps"))
|
|
||||||
.unwrap()
|
|
||||||
{
|
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
if let Some(ext) = entry.path().extension() {
|
if let Some(ext) = entry.path().extension() {
|
||||||
if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
|
if ext == "rmeta" || ext == "d" || ext == "dSYM" || ext == "clif" {
|
||||||
|
@ -216,7 +218,7 @@ fn build_clif_sysroot_for_triple(
|
||||||
};
|
};
|
||||||
try_hard_link(
|
try_hard_link(
|
||||||
entry.path(),
|
entry.path(),
|
||||||
target_dir.join("lib").join("rustlib").join(triple).join("lib").join(entry.file_name()),
|
RUSTLIB_DIR.to_path(dirs).join(triple).join("lib").join(entry.file_name()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,20 +8,37 @@ mod abi_cafe;
|
||||||
mod build_backend;
|
mod build_backend;
|
||||||
mod build_sysroot;
|
mod build_sysroot;
|
||||||
mod config;
|
mod config;
|
||||||
|
mod path;
|
||||||
mod prepare;
|
mod prepare;
|
||||||
mod rustc_info;
|
mod rustc_info;
|
||||||
mod tests;
|
mod tests;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
const USAGE: &str = r#"The build system of cg_clif.
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
./y.rs prepare [--out-dir DIR]
|
||||||
|
./y.rs build [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
|
||||||
|
./y.rs test [--debug] [--sysroot none|clif|llvm] [--out-dir DIR] [--no-unstable-features]
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--sysroot none|clif|llvm
|
||||||
|
Which sysroot libraries to use:
|
||||||
|
`none` will not include any standard library in the sysroot.
|
||||||
|
`clif` will build the standard library using Cranelift.
|
||||||
|
`llvm` will use the pre-compiled standard library of rustc which is compiled with LLVM.
|
||||||
|
|
||||||
|
--out-dir DIR
|
||||||
|
Specify the directory in which the download, build and dist directories are stored.
|
||||||
|
By default this is the working directory.
|
||||||
|
|
||||||
|
--no-unstable-features
|
||||||
|
fSome features are not yet ready for production usage. This option will disable these
|
||||||
|
features. This includes the JIT mode and inline assembly support.
|
||||||
|
"#;
|
||||||
|
|
||||||
fn usage() {
|
fn usage() {
|
||||||
eprintln!("Usage:");
|
eprintln!("{USAGE}");
|
||||||
eprintln!(" ./y.rs prepare");
|
|
||||||
eprintln!(
|
|
||||||
" ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
|
|
||||||
);
|
|
||||||
eprintln!(
|
|
||||||
" ./y.rs test [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! arg_error {
|
macro_rules! arg_error {
|
||||||
|
@ -34,6 +51,7 @@ macro_rules! arg_error {
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
enum Command {
|
enum Command {
|
||||||
|
Prepare,
|
||||||
Build,
|
Build,
|
||||||
Test,
|
Test,
|
||||||
}
|
}
|
||||||
|
@ -48,8 +66,6 @@ pub(crate) enum SysrootKind {
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
env::set_var("CG_CLIF_DISPLAY_CG_TIME", "1");
|
env::set_var("CG_CLIF_DISPLAY_CG_TIME", "1");
|
||||||
env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
|
env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
|
||||||
// The target dir is expected in the default location. Guard against the user changing it.
|
|
||||||
env::set_var("CARGO_TARGET_DIR", "target");
|
|
||||||
|
|
||||||
if is_ci() {
|
if is_ci() {
|
||||||
// Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
|
// Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
|
||||||
|
@ -58,13 +74,7 @@ pub fn main() {
|
||||||
|
|
||||||
let mut args = env::args().skip(1);
|
let mut args = env::args().skip(1);
|
||||||
let command = match args.next().as_deref() {
|
let command = match args.next().as_deref() {
|
||||||
Some("prepare") => {
|
Some("prepare") => Command::Prepare,
|
||||||
if args.next().is_some() {
|
|
||||||
arg_error!("./y.rs prepare doesn't expect arguments");
|
|
||||||
}
|
|
||||||
prepare::prepare();
|
|
||||||
process::exit(0);
|
|
||||||
}
|
|
||||||
Some("build") => Command::Build,
|
Some("build") => Command::Build,
|
||||||
Some("test") => Command::Test,
|
Some("test") => Command::Test,
|
||||||
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
|
Some(flag) if flag.starts_with('-') => arg_error!("Expected command found flag {}", flag),
|
||||||
|
@ -75,15 +85,15 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut target_dir = PathBuf::from("build");
|
let mut out_dir = PathBuf::from(".");
|
||||||
let mut channel = "release";
|
let mut channel = "release";
|
||||||
let mut sysroot_kind = SysrootKind::Clif;
|
let mut sysroot_kind = SysrootKind::Clif;
|
||||||
let mut use_unstable_features = true;
|
let mut use_unstable_features = true;
|
||||||
while let Some(arg) = args.next().as_deref() {
|
while let Some(arg) = args.next().as_deref() {
|
||||||
match arg {
|
match arg {
|
||||||
"--target-dir" => {
|
"--out-dir" => {
|
||||||
target_dir = PathBuf::from(args.next().unwrap_or_else(|| {
|
out_dir = PathBuf::from(args.next().unwrap_or_else(|| {
|
||||||
arg_error!("--target-dir requires argument");
|
arg_error!("--out-dir requires argument");
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
"--debug" => channel = "debug",
|
"--debug" => channel = "debug",
|
||||||
|
@ -101,7 +111,6 @@ pub fn main() {
|
||||||
arg => arg_error!("Unexpected argument {}", arg),
|
arg => arg_error!("Unexpected argument {}", arg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
target_dir = std::env::current_dir().unwrap().join(target_dir);
|
|
||||||
|
|
||||||
let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
|
let host_triple = if let Ok(host_triple) = std::env::var("HOST_TRIPLE") {
|
||||||
host_triple
|
host_triple
|
||||||
|
@ -122,13 +131,43 @@ pub fn main() {
|
||||||
host_triple.clone()
|
host_triple.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
let cg_clif_dylib = build_backend::build_backend(channel, &host_triple, use_unstable_features);
|
// FIXME allow changing the location of these dirs using cli arguments
|
||||||
|
let current_dir = std::env::current_dir().unwrap();
|
||||||
|
out_dir = current_dir.join(out_dir);
|
||||||
|
let dirs = path::Dirs {
|
||||||
|
source_dir: current_dir.clone(),
|
||||||
|
download_dir: out_dir.join("download"),
|
||||||
|
build_dir: out_dir.join("build"),
|
||||||
|
dist_dir: out_dir.join("dist"),
|
||||||
|
};
|
||||||
|
|
||||||
|
path::RelPath::BUILD.ensure_exists(&dirs);
|
||||||
|
|
||||||
|
{
|
||||||
|
// Make sure we always explicitly specify the target dir
|
||||||
|
let target =
|
||||||
|
path::RelPath::BUILD.join("target_dir_should_be_set_explicitly").to_path(&dirs);
|
||||||
|
env::set_var("CARGO_TARGET_DIR", &target);
|
||||||
|
let _ = std::fs::remove_file(&target);
|
||||||
|
std::fs::File::create(target).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
if command == Command::Prepare {
|
||||||
|
prepare::prepare(&dirs);
|
||||||
|
process::exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let cg_clif_dylib =
|
||||||
|
build_backend::build_backend(&dirs, channel, &host_triple, use_unstable_features);
|
||||||
match command {
|
match command {
|
||||||
|
Command::Prepare => {
|
||||||
|
// Handled above
|
||||||
|
}
|
||||||
Command::Test => {
|
Command::Test => {
|
||||||
tests::run_tests(
|
tests::run_tests(
|
||||||
|
&dirs,
|
||||||
channel,
|
channel,
|
||||||
sysroot_kind,
|
sysroot_kind,
|
||||||
&target_dir,
|
|
||||||
&cg_clif_dylib,
|
&cg_clif_dylib,
|
||||||
&host_triple,
|
&host_triple,
|
||||||
&target_triple,
|
&target_triple,
|
||||||
|
@ -137,7 +176,7 @@ pub fn main() {
|
||||||
abi_cafe::run(
|
abi_cafe::run(
|
||||||
channel,
|
channel,
|
||||||
sysroot_kind,
|
sysroot_kind,
|
||||||
&target_dir,
|
&dirs,
|
||||||
&cg_clif_dylib,
|
&cg_clif_dylib,
|
||||||
&host_triple,
|
&host_triple,
|
||||||
&target_triple,
|
&target_triple,
|
||||||
|
@ -145,9 +184,9 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
Command::Build => {
|
Command::Build => {
|
||||||
build_sysroot::build_sysroot(
|
build_sysroot::build_sysroot(
|
||||||
|
&dirs,
|
||||||
channel,
|
channel,
|
||||||
sysroot_kind,
|
sysroot_kind,
|
||||||
&target_dir,
|
|
||||||
&cg_clif_dylib,
|
&cg_clif_dylib,
|
||||||
&host_triple,
|
&host_triple,
|
||||||
&target_triple,
|
&target_triple,
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub(crate) struct Dirs {
|
||||||
|
pub(crate) source_dir: PathBuf,
|
||||||
|
pub(crate) download_dir: PathBuf,
|
||||||
|
pub(crate) build_dir: PathBuf,
|
||||||
|
pub(crate) dist_dir: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) enum PathBase {
|
||||||
|
Source,
|
||||||
|
Download,
|
||||||
|
Build,
|
||||||
|
Dist,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PathBase {
|
||||||
|
fn to_path(self, dirs: &Dirs) -> PathBuf {
|
||||||
|
match self {
|
||||||
|
PathBase::Source => dirs.source_dir.clone(),
|
||||||
|
PathBase::Download => dirs.download_dir.clone(),
|
||||||
|
PathBase::Build => dirs.build_dir.clone(),
|
||||||
|
PathBase::Dist => dirs.dist_dir.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub(crate) enum RelPath {
|
||||||
|
Base(PathBase),
|
||||||
|
Join(&'static RelPath, &'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RelPath {
|
||||||
|
pub(crate) const SOURCE: RelPath = RelPath::Base(PathBase::Source);
|
||||||
|
pub(crate) const DOWNLOAD: RelPath = RelPath::Base(PathBase::Download);
|
||||||
|
pub(crate) const BUILD: RelPath = RelPath::Base(PathBase::Build);
|
||||||
|
pub(crate) const DIST: RelPath = RelPath::Base(PathBase::Dist);
|
||||||
|
|
||||||
|
pub(crate) const SCRIPTS: RelPath = RelPath::SOURCE.join("scripts");
|
||||||
|
pub(crate) const BUILD_SYSROOT: RelPath = RelPath::SOURCE.join("build_sysroot");
|
||||||
|
pub(crate) const PATCHES: RelPath = RelPath::SOURCE.join("patches");
|
||||||
|
|
||||||
|
pub(crate) const fn join(&'static self, suffix: &'static str) -> RelPath {
|
||||||
|
RelPath::Join(self, suffix)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn to_path(&self, dirs: &Dirs) -> PathBuf {
|
||||||
|
match self {
|
||||||
|
RelPath::Base(base) => base.to_path(dirs),
|
||||||
|
RelPath::Join(base, suffix) => base.to_path(dirs).join(suffix),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ensure_exists(&self, dirs: &Dirs) {
|
||||||
|
fs::create_dir_all(self.to_path(dirs)).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ensure_fresh(&self, dirs: &Dirs) {
|
||||||
|
let path = self.to_path(dirs);
|
||||||
|
if path.exists() {
|
||||||
|
fs::remove_dir_all(&path).unwrap();
|
||||||
|
}
|
||||||
|
fs::create_dir_all(path).unwrap();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,92 +1,75 @@
|
||||||
use std::env;
|
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
use super::build_sysroot::{SYSROOT_RUSTC_VERSION, SYSROOT_SRC};
|
||||||
|
use super::path::{Dirs, RelPath};
|
||||||
use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
|
use super::rustc_info::{get_file_name, get_rustc_path, get_rustc_version};
|
||||||
use super::utils::{cargo_command, copy_dir_recursively, spawn_and_wait};
|
use super::utils::{copy_dir_recursively, spawn_and_wait, Compiler};
|
||||||
|
|
||||||
pub(crate) const ABI_CAFE: GitRepo =
|
pub(crate) fn prepare(dirs: &Dirs) {
|
||||||
GitRepo::github("Gankra", "abi-cafe", "4c6dc8c9c687e2b3a760ff2176ce236872b37212", "abi-cafe");
|
if RelPath::DOWNLOAD.to_path(dirs).exists() {
|
||||||
|
std::fs::remove_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
|
||||||
pub(crate) const RAND: GitRepo =
|
|
||||||
GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
|
|
||||||
|
|
||||||
pub(crate) const REGEX: GitRepo =
|
|
||||||
GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex");
|
|
||||||
|
|
||||||
pub(crate) const PORTABLE_SIMD: GitRepo = GitRepo::github(
|
|
||||||
"rust-lang",
|
|
||||||
"portable-simd",
|
|
||||||
"d5cd4a8112d958bd3a252327e0d069a6363249bd",
|
|
||||||
"portable-simd",
|
|
||||||
);
|
|
||||||
|
|
||||||
pub(crate) const SIMPLE_RAYTRACER: GitRepo = GitRepo::github(
|
|
||||||
"ebobby",
|
|
||||||
"simple-raytracer",
|
|
||||||
"804a7a21b9e673a482797aa289a18ed480e4d813",
|
|
||||||
"<none>",
|
|
||||||
);
|
|
||||||
|
|
||||||
pub(crate) fn prepare() {
|
|
||||||
if Path::new("download").exists() {
|
|
||||||
std::fs::remove_dir_all(Path::new("download")).unwrap();
|
|
||||||
}
|
}
|
||||||
std::fs::create_dir_all(Path::new("download")).unwrap();
|
std::fs::create_dir_all(RelPath::DOWNLOAD.to_path(dirs)).unwrap();
|
||||||
|
|
||||||
prepare_sysroot();
|
prepare_sysroot(dirs);
|
||||||
|
|
||||||
// FIXME maybe install this only locally?
|
// FIXME maybe install this only locally?
|
||||||
eprintln!("[INSTALL] hyperfine");
|
eprintln!("[INSTALL] hyperfine");
|
||||||
Command::new("cargo").arg("install").arg("hyperfine").spawn().unwrap().wait().unwrap();
|
Command::new("cargo")
|
||||||
|
.arg("install")
|
||||||
|
.arg("hyperfine")
|
||||||
|
.env_remove("CARGO_TARGET_DIR")
|
||||||
|
.spawn()
|
||||||
|
.unwrap()
|
||||||
|
.wait()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
ABI_CAFE.fetch();
|
super::abi_cafe::ABI_CAFE_REPO.fetch(dirs);
|
||||||
RAND.fetch();
|
super::tests::RAND_REPO.fetch(dirs);
|
||||||
REGEX.fetch();
|
super::tests::REGEX_REPO.fetch(dirs);
|
||||||
PORTABLE_SIMD.fetch();
|
super::tests::PORTABLE_SIMD_REPO.fetch(dirs);
|
||||||
SIMPLE_RAYTRACER.fetch();
|
super::tests::SIMPLE_RAYTRACER_REPO.fetch(dirs);
|
||||||
|
|
||||||
eprintln!("[LLVM BUILD] simple-raytracer");
|
eprintln!("[LLVM BUILD] simple-raytracer");
|
||||||
let build_cmd = cargo_command("cargo", "build", None, &SIMPLE_RAYTRACER.source_dir());
|
let host_compiler = Compiler::host();
|
||||||
|
let build_cmd = super::tests::SIMPLE_RAYTRACER.build(&host_compiler, dirs);
|
||||||
spawn_and_wait(build_cmd);
|
spawn_and_wait(build_cmd);
|
||||||
fs::copy(
|
fs::copy(
|
||||||
SIMPLE_RAYTRACER
|
super::tests::SIMPLE_RAYTRACER
|
||||||
.source_dir()
|
.target_dir(dirs)
|
||||||
.join("target")
|
.join(&host_compiler.triple)
|
||||||
.join("debug")
|
.join("debug")
|
||||||
.join(get_file_name("main", "bin")),
|
.join(get_file_name("main", "bin")),
|
||||||
SIMPLE_RAYTRACER.source_dir().join(get_file_name("raytracer_cg_llvm", "bin")),
|
RelPath::BUILD.to_path(dirs).join(get_file_name("raytracer_cg_llvm", "bin")),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_sysroot() {
|
fn prepare_sysroot(dirs: &Dirs) {
|
||||||
let rustc_path = get_rustc_path();
|
let rustc_path = get_rustc_path();
|
||||||
let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
|
let sysroot_src_orig = rustc_path.parent().unwrap().join("../lib/rustlib/src/rust");
|
||||||
let sysroot_src = env::current_dir().unwrap().join("build_sysroot").join("sysroot_src");
|
let sysroot_src = SYSROOT_SRC;
|
||||||
|
|
||||||
assert!(sysroot_src_orig.exists());
|
assert!(sysroot_src_orig.exists());
|
||||||
|
|
||||||
if sysroot_src.exists() {
|
sysroot_src.ensure_fresh(dirs);
|
||||||
fs::remove_dir_all(&sysroot_src).unwrap();
|
fs::create_dir_all(sysroot_src.to_path(dirs).join("library")).unwrap();
|
||||||
}
|
|
||||||
fs::create_dir_all(sysroot_src.join("library")).unwrap();
|
|
||||||
eprintln!("[COPY] sysroot src");
|
eprintln!("[COPY] sysroot src");
|
||||||
copy_dir_recursively(&sysroot_src_orig.join("library"), &sysroot_src.join("library"));
|
copy_dir_recursively(
|
||||||
|
&sysroot_src_orig.join("library"),
|
||||||
|
&sysroot_src.to_path(dirs).join("library"),
|
||||||
|
);
|
||||||
|
|
||||||
let rustc_version = get_rustc_version();
|
let rustc_version = get_rustc_version();
|
||||||
fs::write(Path::new("build_sysroot").join("rustc_version"), &rustc_version).unwrap();
|
fs::write(SYSROOT_RUSTC_VERSION.to_path(dirs), &rustc_version).unwrap();
|
||||||
|
|
||||||
eprintln!("[GIT] init");
|
eprintln!("[GIT] init");
|
||||||
let mut git_init_cmd = Command::new("git");
|
init_git_repo(&sysroot_src.to_path(dirs));
|
||||||
git_init_cmd.arg("init").arg("-q").current_dir(&sysroot_src);
|
|
||||||
spawn_and_wait(git_init_cmd);
|
|
||||||
|
|
||||||
init_git_repo(&sysroot_src);
|
apply_patches(dirs, "sysroot", &sysroot_src.to_path(dirs));
|
||||||
|
|
||||||
apply_patches("sysroot", &sysroot_src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct GitRepo {
|
pub(crate) struct GitRepo {
|
||||||
|
@ -100,7 +83,7 @@ enum GitRepoUrl {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GitRepo {
|
impl GitRepo {
|
||||||
const fn github(
|
pub(crate) const fn github(
|
||||||
user: &'static str,
|
user: &'static str,
|
||||||
repo: &'static str,
|
repo: &'static str,
|
||||||
rev: &'static str,
|
rev: &'static str,
|
||||||
|
@ -109,21 +92,25 @@ impl GitRepo {
|
||||||
GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
|
GitRepo { url: GitRepoUrl::Github { user, repo }, rev, patch_name }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn source_dir(&self) -> PathBuf {
|
pub(crate) const fn source_dir(&self) -> RelPath {
|
||||||
match self.url {
|
match self.url {
|
||||||
GitRepoUrl::Github { user: _, repo } => {
|
GitRepoUrl::Github { user: _, repo } => RelPath::DOWNLOAD.join(repo),
|
||||||
std::env::current_dir().unwrap().join("download").join(repo)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch(&self) {
|
fn fetch(&self, dirs: &Dirs) {
|
||||||
match self.url {
|
match self.url {
|
||||||
GitRepoUrl::Github { user, repo } => {
|
GitRepoUrl::Github { user, repo } => {
|
||||||
clone_repo_shallow_github(&self.source_dir(), user, repo, self.rev);
|
clone_repo_shallow_github(
|
||||||
|
dirs,
|
||||||
|
&self.source_dir().to_path(dirs),
|
||||||
|
user,
|
||||||
|
repo,
|
||||||
|
self.rev,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apply_patches(self.patch_name, &self.source_dir());
|
apply_patches(dirs, self.patch_name, &self.source_dir().to_path(dirs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,18 +129,16 @@ fn clone_repo(download_dir: &Path, repo: &str, rev: &str) {
|
||||||
spawn_and_wait(checkout_cmd);
|
spawn_and_wait(checkout_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &str) {
|
fn clone_repo_shallow_github(dirs: &Dirs, download_dir: &Path, user: &str, repo: &str, rev: &str) {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
// Older windows doesn't have tar or curl by default. Fall back to using git.
|
// Older windows doesn't have tar or curl by default. Fall back to using git.
|
||||||
clone_repo(download_dir, &format!("https://github.com/{}/{}.git", user, repo), rev);
|
clone_repo(download_dir, &format!("https://github.com/{}/{}.git", user, repo), rev);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let downloads_dir = std::env::current_dir().unwrap().join("download");
|
|
||||||
|
|
||||||
let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", user, repo, rev);
|
let archive_url = format!("https://github.com/{}/{}/archive/{}.tar.gz", user, repo, rev);
|
||||||
let archive_file = downloads_dir.join(format!("{}.tar.gz", rev));
|
let archive_file = RelPath::DOWNLOAD.to_path(dirs).join(format!("{}.tar.gz", rev));
|
||||||
let archive_dir = downloads_dir.join(format!("{}-{}", repo, rev));
|
let archive_dir = RelPath::DOWNLOAD.to_path(dirs).join(format!("{}-{}", repo, rev));
|
||||||
|
|
||||||
eprintln!("[DOWNLOAD] {}/{} from {}", user, repo, archive_url);
|
eprintln!("[DOWNLOAD] {}/{} from {}", user, repo, archive_url);
|
||||||
|
|
||||||
|
@ -169,7 +154,7 @@ fn clone_repo_shallow_github(download_dir: &Path, user: &str, repo: &str, rev: &
|
||||||
|
|
||||||
// Unpack tar archive
|
// Unpack tar archive
|
||||||
let mut unpack_cmd = Command::new("tar");
|
let mut unpack_cmd = Command::new("tar");
|
||||||
unpack_cmd.arg("xf").arg(&archive_file).current_dir(downloads_dir);
|
unpack_cmd.arg("xf").arg(&archive_file).current_dir(RelPath::DOWNLOAD.to_path(dirs));
|
||||||
spawn_and_wait(unpack_cmd);
|
spawn_and_wait(unpack_cmd);
|
||||||
|
|
||||||
// Rename unpacked dir to the expected name
|
// Rename unpacked dir to the expected name
|
||||||
|
@ -191,12 +176,21 @@ fn init_git_repo(repo_dir: &Path) {
|
||||||
spawn_and_wait(git_add_cmd);
|
spawn_and_wait(git_add_cmd);
|
||||||
|
|
||||||
let mut git_commit_cmd = Command::new("git");
|
let mut git_commit_cmd = Command::new("git");
|
||||||
git_commit_cmd.arg("commit").arg("-m").arg("Initial commit").arg("-q").current_dir(repo_dir);
|
git_commit_cmd
|
||||||
|
.arg("-c")
|
||||||
|
.arg("user.name=Dummy")
|
||||||
|
.arg("-c")
|
||||||
|
.arg("user.email=dummy@example.com")
|
||||||
|
.arg("commit")
|
||||||
|
.arg("-m")
|
||||||
|
.arg("Initial commit")
|
||||||
|
.arg("-q")
|
||||||
|
.current_dir(repo_dir);
|
||||||
spawn_and_wait(git_commit_cmd);
|
spawn_and_wait(git_commit_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_patches(source_dir: &Path, crate_name: &str) -> Vec<PathBuf> {
|
fn get_patches(dirs: &Dirs, crate_name: &str) -> Vec<PathBuf> {
|
||||||
let mut patches: Vec<_> = fs::read_dir(source_dir.join("patches"))
|
let mut patches: Vec<_> = fs::read_dir(RelPath::PATCHES.to_path(dirs))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.map(|entry| entry.unwrap().path())
|
.map(|entry| entry.unwrap().path())
|
||||||
.filter(|path| path.extension() == Some(OsStr::new("patch")))
|
.filter(|path| path.extension() == Some(OsStr::new("patch")))
|
||||||
|
@ -215,19 +209,27 @@ fn get_patches(source_dir: &Path, crate_name: &str) -> Vec<PathBuf> {
|
||||||
patches
|
patches
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_patches(crate_name: &str, target_dir: &Path) {
|
fn apply_patches(dirs: &Dirs, crate_name: &str, target_dir: &Path) {
|
||||||
if crate_name == "<none>" {
|
if crate_name == "<none>" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for patch in get_patches(&std::env::current_dir().unwrap(), crate_name) {
|
for patch in get_patches(dirs, crate_name) {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"[PATCH] {:?} <- {:?}",
|
"[PATCH] {:?} <- {:?}",
|
||||||
target_dir.file_name().unwrap(),
|
target_dir.file_name().unwrap(),
|
||||||
patch.file_name().unwrap()
|
patch.file_name().unwrap()
|
||||||
);
|
);
|
||||||
let mut apply_patch_cmd = Command::new("git");
|
let mut apply_patch_cmd = Command::new("git");
|
||||||
apply_patch_cmd.arg("am").arg(patch).arg("-q").current_dir(target_dir);
|
apply_patch_cmd
|
||||||
|
.arg("-c")
|
||||||
|
.arg("user.name=Dummy")
|
||||||
|
.arg("-c")
|
||||||
|
.arg("user.email=dummy@example.com")
|
||||||
|
.arg("am")
|
||||||
|
.arg(patch)
|
||||||
|
.arg("-q")
|
||||||
|
.current_dir(target_dir);
|
||||||
spawn_and_wait(apply_patch_cmd);
|
spawn_and_wait(apply_patch_cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,16 @@ pub(crate) fn get_host_triple() -> String {
|
||||||
.to_owned()
|
.to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_cargo_path() -> PathBuf {
|
||||||
|
let cargo_path = Command::new("rustup")
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.args(&["which", "cargo"])
|
||||||
|
.output()
|
||||||
|
.unwrap()
|
||||||
|
.stdout;
|
||||||
|
Path::new(String::from_utf8(cargo_path).unwrap().trim()).to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_rustc_path() -> PathBuf {
|
pub(crate) fn get_rustc_path() -> PathBuf {
|
||||||
let rustc_path = Command::new("rustup")
|
let rustc_path = Command::new("rustup")
|
||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
|
@ -33,6 +43,16 @@ pub(crate) fn get_rustc_path() -> PathBuf {
|
||||||
Path::new(String::from_utf8(rustc_path).unwrap().trim()).to_owned()
|
Path::new(String::from_utf8(rustc_path).unwrap().trim()).to_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_rustdoc_path() -> PathBuf {
|
||||||
|
let rustc_path = Command::new("rustup")
|
||||||
|
.stderr(Stdio::inherit())
|
||||||
|
.args(&["which", "rustdoc"])
|
||||||
|
.output()
|
||||||
|
.unwrap()
|
||||||
|
.stdout;
|
||||||
|
Path::new(String::from_utf8(rustc_path).unwrap().trim()).to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_default_sysroot() -> PathBuf {
|
pub(crate) fn get_default_sysroot() -> PathBuf {
|
||||||
let default_sysroot = Command::new("rustc")
|
let default_sysroot = Command::new("rustc")
|
||||||
.stderr(Stdio::inherit())
|
.stderr(Stdio::inherit())
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
use super::build_sysroot;
|
use super::build_sysroot;
|
||||||
use super::config;
|
use super::config;
|
||||||
use super::prepare;
|
use super::path::{Dirs, RelPath};
|
||||||
use super::rustc_info::get_wrapper_file_name;
|
use super::prepare::GitRepo;
|
||||||
use super::utils::{cargo_command, hyperfine_command, spawn_and_wait, spawn_and_wait_with_input};
|
use super::rustc_info::{get_cargo_path, get_wrapper_file_name};
|
||||||
use build_system::SysrootKind;
|
use super::utils::{
|
||||||
|
hyperfine_command, spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler,
|
||||||
|
};
|
||||||
|
use super::SysrootKind;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
|
static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example");
|
||||||
|
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
config: &'static str,
|
config: &'static str,
|
||||||
func: &'static dyn Fn(&TestRunner),
|
func: &'static dyn Fn(&TestRunner),
|
||||||
|
@ -30,7 +35,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"lib,dylib",
|
"lib,dylib",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
TestCase::new("build.example", &|runner| {
|
TestCase::new("build.example", &|runner| {
|
||||||
|
@ -39,7 +44,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"lib",
|
"lib",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
TestCase::new("jit.mini_core_hello_world", &|runner| {
|
TestCase::new("jit.mini_core_hello_world", &|runner| {
|
||||||
|
@ -51,7 +56,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--cfg",
|
"--cfg",
|
||||||
"jit",
|
"jit",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.host_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
|
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
|
||||||
spawn_and_wait(jit_cmd);
|
spawn_and_wait(jit_cmd);
|
||||||
|
@ -65,7 +70,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--cfg",
|
"--cfg",
|
||||||
"jit",
|
"jit",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.host_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
|
jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd");
|
||||||
spawn_and_wait(jit_cmd);
|
spawn_and_wait(jit_cmd);
|
||||||
|
@ -79,7 +84,7 @@ const NO_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"bin",
|
"bin",
|
||||||
"-g",
|
"-g",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]);
|
runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]);
|
||||||
}),
|
}),
|
||||||
|
@ -94,7 +99,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"bin",
|
"bin",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []);
|
runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []);
|
||||||
}),
|
}),
|
||||||
|
@ -106,7 +111,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"bin",
|
"bin",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("issue_91827_extern_types", []);
|
runner.run_out_command("issue_91827_extern_types", []);
|
||||||
}),
|
}),
|
||||||
|
@ -116,7 +121,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"lib",
|
"lib",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
TestCase::new("aot.alloc_example", &|runner| {
|
TestCase::new("aot.alloc_example", &|runner| {
|
||||||
|
@ -125,7 +130,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"bin",
|
"bin",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("alloc_example", []);
|
runner.run_out_command("alloc_example", []);
|
||||||
}),
|
}),
|
||||||
|
@ -136,7 +141,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"-Cprefer-dynamic",
|
"-Cprefer-dynamic",
|
||||||
"example/std_example.rs",
|
"example/std_example.rs",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.host_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
eprintln!("[JIT-lazy] std_example");
|
eprintln!("[JIT-lazy] std_example");
|
||||||
|
@ -146,7 +151,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"-Cprefer-dynamic",
|
"-Cprefer-dynamic",
|
||||||
"example/std_example.rs",
|
"example/std_example.rs",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.host_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
}),
|
}),
|
||||||
TestCase::new("aot.std_example", &|runner| {
|
TestCase::new("aot.std_example", &|runner| {
|
||||||
|
@ -155,7 +160,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"bin",
|
"bin",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("std_example", ["arg"]);
|
runner.run_out_command("std_example", ["arg"]);
|
||||||
}),
|
}),
|
||||||
|
@ -167,7 +172,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"bin",
|
"bin",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("dst_field_align", []);
|
runner.run_out_command("dst_field_align", []);
|
||||||
}),
|
}),
|
||||||
|
@ -178,7 +183,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"bin",
|
"bin",
|
||||||
"-Cpanic=abort",
|
"-Cpanic=abort",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("subslice-patterns-const-eval", []);
|
runner.run_out_command("subslice-patterns-const-eval", []);
|
||||||
}),
|
}),
|
||||||
|
@ -189,7 +194,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"bin",
|
"bin",
|
||||||
"-Cpanic=abort",
|
"-Cpanic=abort",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("track-caller-attribute", []);
|
runner.run_out_command("track-caller-attribute", []);
|
||||||
}),
|
}),
|
||||||
|
@ -200,7 +205,7 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"bin",
|
"bin",
|
||||||
"-Cpanic=abort",
|
"-Cpanic=abort",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("float-minmax-pass", []);
|
runner.run_out_command("float-minmax-pass", []);
|
||||||
}),
|
}),
|
||||||
|
@ -210,205 +215,252 @@ const BASE_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
"--crate-type",
|
"--crate-type",
|
||||||
"bin",
|
"bin",
|
||||||
"--target",
|
"--target",
|
||||||
&runner.target_triple,
|
&runner.target_compiler.triple,
|
||||||
]);
|
]);
|
||||||
runner.run_out_command("mod_bench", []);
|
runner.run_out_command("mod_bench", []);
|
||||||
}),
|
}),
|
||||||
|
TestCase::new("aot.issue-72793", &|runner| {
|
||||||
|
runner.run_rustc([
|
||||||
|
"example/issue-72793.rs",
|
||||||
|
"--crate-type",
|
||||||
|
"bin",
|
||||||
|
"--target",
|
||||||
|
&runner.target_compiler.triple,
|
||||||
|
]);
|
||||||
|
runner.run_out_command("issue-72793", []);
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
pub(crate) static RAND_REPO: GitRepo =
|
||||||
|
GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand");
|
||||||
|
|
||||||
|
static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand");
|
||||||
|
|
||||||
|
pub(crate) static REGEX_REPO: GitRepo =
|
||||||
|
GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex");
|
||||||
|
|
||||||
|
static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex");
|
||||||
|
|
||||||
|
pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
|
||||||
|
"rust-lang",
|
||||||
|
"portable-simd",
|
||||||
|
"d5cd4a8112d958bd3a252327e0d069a6363249bd",
|
||||||
|
"portable-simd",
|
||||||
|
);
|
||||||
|
|
||||||
|
static PORTABLE_SIMD: CargoProject =
|
||||||
|
CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable_simd");
|
||||||
|
|
||||||
|
pub(crate) static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github(
|
||||||
|
"ebobby",
|
||||||
|
"simple-raytracer",
|
||||||
|
"804a7a21b9e673a482797aa289a18ed480e4d813",
|
||||||
|
"<none>",
|
||||||
|
);
|
||||||
|
|
||||||
|
pub(crate) static SIMPLE_RAYTRACER: CargoProject =
|
||||||
|
CargoProject::new(&SIMPLE_RAYTRACER_REPO.source_dir(), "simple_raytracer");
|
||||||
|
|
||||||
|
static LIBCORE_TESTS: CargoProject =
|
||||||
|
CargoProject::new(&RelPath::BUILD_SYSROOT.join("sysroot_src/library/core/tests"), "core_tests");
|
||||||
|
|
||||||
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
|
const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
|
||||||
TestCase::new("test.rust-random/rand", &|runner| {
|
TestCase::new("test.rust-random/rand", &|runner| {
|
||||||
runner.in_dir(prepare::RAND.source_dir(), |runner| {
|
spawn_and_wait(RAND.clean(&runner.target_compiler.cargo, &runner.dirs));
|
||||||
runner.run_cargo("clean", []);
|
|
||||||
|
|
||||||
if runner.host_triple == runner.target_triple {
|
if runner.is_native {
|
||||||
eprintln!("[TEST] rust-random/rand");
|
eprintln!("[TEST] rust-random/rand");
|
||||||
runner.run_cargo("test", ["--workspace"]);
|
let mut test_cmd = RAND.test(&runner.target_compiler, &runner.dirs);
|
||||||
} else {
|
test_cmd.arg("--workspace");
|
||||||
eprintln!("[AOT] rust-random/rand");
|
spawn_and_wait(test_cmd);
|
||||||
runner.run_cargo("build", ["--workspace", "--tests"]);
|
} else {
|
||||||
}
|
eprintln!("[AOT] rust-random/rand");
|
||||||
});
|
let mut build_cmd = RAND.build(&runner.target_compiler, &runner.dirs);
|
||||||
|
build_cmd.arg("--workspace").arg("--tests");
|
||||||
|
spawn_and_wait(build_cmd);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
TestCase::new("bench.simple-raytracer", &|runner| {
|
TestCase::new("bench.simple-raytracer", &|runner| {
|
||||||
runner.in_dir(prepare::SIMPLE_RAYTRACER.source_dir(), |runner| {
|
let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()).parse().unwrap();
|
||||||
let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()).parse().unwrap();
|
|
||||||
|
|
||||||
if runner.host_triple == runner.target_triple {
|
if runner.is_native {
|
||||||
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
|
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer");
|
||||||
let prepare = runner.cargo_command("clean", []);
|
let cargo_clif = RelPath::DIST
|
||||||
|
.to_path(&runner.dirs)
|
||||||
|
.join(get_wrapper_file_name("cargo-clif", "bin"));
|
||||||
|
let manifest_path = SIMPLE_RAYTRACER.manifest_path(&runner.dirs);
|
||||||
|
let target_dir = SIMPLE_RAYTRACER.target_dir(&runner.dirs);
|
||||||
|
|
||||||
let llvm_build_cmd = cargo_command("cargo", "build", None, Path::new("."));
|
let clean_cmd = format!(
|
||||||
|
"cargo clean --manifest-path {manifest_path} --target-dir {target_dir}",
|
||||||
|
manifest_path = manifest_path.display(),
|
||||||
|
target_dir = target_dir.display(),
|
||||||
|
);
|
||||||
|
let llvm_build_cmd = format!(
|
||||||
|
"cargo build --manifest-path {manifest_path} --target-dir {target_dir}",
|
||||||
|
manifest_path = manifest_path.display(),
|
||||||
|
target_dir = target_dir.display(),
|
||||||
|
);
|
||||||
|
let clif_build_cmd = format!(
|
||||||
|
"{cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir}",
|
||||||
|
cargo_clif = cargo_clif.display(),
|
||||||
|
manifest_path = manifest_path.display(),
|
||||||
|
target_dir = target_dir.display(),
|
||||||
|
);
|
||||||
|
|
||||||
let cargo_clif = runner
|
let bench_compile =
|
||||||
.root_dir
|
hyperfine_command(1, run_runs, Some(&clean_cmd), &llvm_build_cmd, &clif_build_cmd);
|
||||||
.clone()
|
|
||||||
.join("build")
|
|
||||||
.join(get_wrapper_file_name("cargo-clif", "bin"));
|
|
||||||
let clif_build_cmd = cargo_command(cargo_clif, "build", None, Path::new("."));
|
|
||||||
|
|
||||||
let bench_compile =
|
spawn_and_wait(bench_compile);
|
||||||
hyperfine_command(1, run_runs, Some(prepare), llvm_build_cmd, clif_build_cmd);
|
|
||||||
|
|
||||||
spawn_and_wait(bench_compile);
|
eprintln!("[BENCH RUN] ebobby/simple-raytracer");
|
||||||
|
fs::copy(
|
||||||
|
target_dir.join("debug").join("main"),
|
||||||
|
RelPath::BUILD.to_path(&runner.dirs).join("raytracer_cg_clif"),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
eprintln!("[BENCH RUN] ebobby/simple-raytracer");
|
let mut bench_run =
|
||||||
fs::copy(PathBuf::from("./target/debug/main"), PathBuf::from("raytracer_cg_clif"))
|
hyperfine_command(0, run_runs, None, "./raytracer_cg_llvm", "./raytracer_cg_clif");
|
||||||
.unwrap();
|
bench_run.current_dir(RelPath::BUILD.to_path(&runner.dirs));
|
||||||
|
spawn_and_wait(bench_run);
|
||||||
let bench_run = hyperfine_command(
|
} else {
|
||||||
0,
|
spawn_and_wait(SIMPLE_RAYTRACER.clean(&runner.target_compiler.cargo, &runner.dirs));
|
||||||
run_runs,
|
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
|
||||||
None,
|
eprintln!("[COMPILE] ebobby/simple-raytracer");
|
||||||
Command::new("./raytracer_cg_llvm"),
|
spawn_and_wait(SIMPLE_RAYTRACER.build(&runner.target_compiler, &runner.dirs));
|
||||||
Command::new("./raytracer_cg_clif"),
|
eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
|
||||||
);
|
}
|
||||||
spawn_and_wait(bench_run);
|
|
||||||
} else {
|
|
||||||
runner.run_cargo("clean", []);
|
|
||||||
eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)");
|
|
||||||
eprintln!("[COMPILE] ebobby/simple-raytracer");
|
|
||||||
runner.run_cargo("build", []);
|
|
||||||
eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
TestCase::new("test.libcore", &|runner| {
|
TestCase::new("test.libcore", &|runner| {
|
||||||
runner.in_dir(
|
spawn_and_wait(LIBCORE_TESTS.clean(&runner.host_compiler.cargo, &runner.dirs));
|
||||||
std::env::current_dir()
|
|
||||||
.unwrap()
|
|
||||||
.join("build_sysroot")
|
|
||||||
.join("sysroot_src")
|
|
||||||
.join("library")
|
|
||||||
.join("core")
|
|
||||||
.join("tests"),
|
|
||||||
|runner| {
|
|
||||||
runner.run_cargo("clean", []);
|
|
||||||
|
|
||||||
if runner.host_triple == runner.target_triple {
|
if runner.is_native {
|
||||||
runner.run_cargo("test", []);
|
spawn_and_wait(LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs));
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Cross-Compiling: Not running tests");
|
eprintln!("Cross-Compiling: Not running tests");
|
||||||
runner.run_cargo("build", ["--tests"]);
|
let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs);
|
||||||
}
|
build_cmd.arg("--tests");
|
||||||
},
|
spawn_and_wait(build_cmd);
|
||||||
);
|
}
|
||||||
}),
|
}),
|
||||||
TestCase::new("test.regex-shootout-regex-dna", &|runner| {
|
TestCase::new("test.regex-shootout-regex-dna", &|runner| {
|
||||||
runner.in_dir(prepare::REGEX.source_dir(), |runner| {
|
spawn_and_wait(REGEX.clean(&runner.target_compiler.cargo, &runner.dirs));
|
||||||
runner.run_cargo("clean", []);
|
|
||||||
|
|
||||||
// newer aho_corasick versions throw a deprecation warning
|
// newer aho_corasick versions throw a deprecation warning
|
||||||
let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
|
let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags);
|
||||||
|
|
||||||
let mut build_cmd = runner.cargo_command("build", ["--example", "shootout-regex-dna"]);
|
let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs);
|
||||||
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
|
build_cmd.arg("--example").arg("shootout-regex-dna");
|
||||||
spawn_and_wait(build_cmd);
|
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
|
||||||
|
spawn_and_wait(build_cmd);
|
||||||
|
|
||||||
if runner.host_triple == runner.target_triple {
|
if runner.is_native {
|
||||||
let mut run_cmd = runner.cargo_command("run", ["--example", "shootout-regex-dna"]);
|
let mut run_cmd = REGEX.run(&runner.target_compiler, &runner.dirs);
|
||||||
run_cmd.env("RUSTFLAGS", lint_rust_flags);
|
run_cmd.arg("--example").arg("shootout-regex-dna");
|
||||||
|
run_cmd.env("RUSTFLAGS", lint_rust_flags);
|
||||||
|
|
||||||
let input =
|
let input = fs::read_to_string(
|
||||||
fs::read_to_string(PathBuf::from("examples/regexdna-input.txt")).unwrap();
|
REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-input.txt"),
|
||||||
let expected_path = PathBuf::from("examples/regexdna-output.txt");
|
)
|
||||||
let expected = fs::read_to_string(&expected_path).unwrap();
|
.unwrap();
|
||||||
|
let expected_path =
|
||||||
|
REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-output.txt");
|
||||||
|
let expected = fs::read_to_string(&expected_path).unwrap();
|
||||||
|
|
||||||
let output = spawn_and_wait_with_input(run_cmd, input);
|
let output = spawn_and_wait_with_input(run_cmd, input);
|
||||||
// Make sure `[codegen mono items] start` doesn't poison the diff
|
// Make sure `[codegen mono items] start` doesn't poison the diff
|
||||||
let output = output
|
let output = output
|
||||||
.lines()
|
.lines()
|
||||||
.filter(|line| !line.contains("codegen mono items"))
|
.filter(|line| !line.contains("codegen mono items"))
|
||||||
.chain(Some("")) // This just adds the trailing newline
|
.chain(Some("")) // This just adds the trailing newline
|
||||||
.collect::<Vec<&str>>()
|
.collect::<Vec<&str>>()
|
||||||
.join("\r\n");
|
.join("\r\n");
|
||||||
|
|
||||||
let output_matches = expected.lines().eq(output.lines());
|
let output_matches = expected.lines().eq(output.lines());
|
||||||
if !output_matches {
|
if !output_matches {
|
||||||
let res_path = PathBuf::from("res.txt");
|
let res_path = REGEX.source_dir(&runner.dirs).join("res.txt");
|
||||||
fs::write(&res_path, &output).unwrap();
|
fs::write(&res_path, &output).unwrap();
|
||||||
|
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
println!("Output files don't match!");
|
println!("Output files don't match!");
|
||||||
println!("Expected Output:\n{}", expected);
|
println!("Expected Output:\n{}", expected);
|
||||||
println!("Actual Output:\n{}", output);
|
println!("Actual Output:\n{}", output);
|
||||||
} else {
|
} else {
|
||||||
let mut diff = Command::new("diff");
|
let mut diff = Command::new("diff");
|
||||||
diff.arg("-u");
|
diff.arg("-u");
|
||||||
diff.arg(res_path);
|
diff.arg(res_path);
|
||||||
diff.arg(expected_path);
|
diff.arg(expected_path);
|
||||||
spawn_and_wait(diff);
|
spawn_and_wait(diff);
|
||||||
}
|
|
||||||
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}),
|
}),
|
||||||
TestCase::new("test.regex", &|runner| {
|
TestCase::new("test.regex", &|runner| {
|
||||||
runner.in_dir(prepare::REGEX.source_dir(), |runner| {
|
spawn_and_wait(REGEX.clean(&runner.host_compiler.cargo, &runner.dirs));
|
||||||
runner.run_cargo("clean", []);
|
|
||||||
|
|
||||||
// newer aho_corasick versions throw a deprecation warning
|
// newer aho_corasick versions throw a deprecation warning
|
||||||
let lint_rust_flags = format!("{} --cap-lints warn", runner.rust_flags);
|
let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags);
|
||||||
|
|
||||||
if runner.host_triple == runner.target_triple {
|
if runner.is_native {
|
||||||
let mut run_cmd = runner.cargo_command(
|
let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs);
|
||||||
"test",
|
run_cmd.args([
|
||||||
[
|
"--tests",
|
||||||
"--tests",
|
"--",
|
||||||
"--",
|
"--exclude-should-panic",
|
||||||
"--exclude-should-panic",
|
"--test-threads",
|
||||||
"--test-threads",
|
"1",
|
||||||
"1",
|
"-Zunstable-options",
|
||||||
"-Zunstable-options",
|
"-q",
|
||||||
"-q",
|
]);
|
||||||
],
|
run_cmd.env("RUSTFLAGS", lint_rust_flags);
|
||||||
);
|
spawn_and_wait(run_cmd);
|
||||||
run_cmd.env("RUSTFLAGS", lint_rust_flags);
|
} else {
|
||||||
spawn_and_wait(run_cmd);
|
eprintln!("Cross-Compiling: Not running tests");
|
||||||
} else {
|
let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs);
|
||||||
eprintln!("Cross-Compiling: Not running tests");
|
build_cmd.arg("--tests");
|
||||||
let mut build_cmd =
|
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
|
||||||
runner.cargo_command("build", ["--tests", "--target", &runner.target_triple]);
|
spawn_and_wait(build_cmd);
|
||||||
build_cmd.env("RUSTFLAGS", lint_rust_flags.clone());
|
}
|
||||||
spawn_and_wait(build_cmd);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}),
|
}),
|
||||||
TestCase::new("test.portable-simd", &|runner| {
|
TestCase::new("test.portable-simd", &|runner| {
|
||||||
runner.in_dir(prepare::PORTABLE_SIMD.source_dir(), |runner| {
|
spawn_and_wait(PORTABLE_SIMD.clean(&runner.host_compiler.cargo, &runner.dirs));
|
||||||
runner.run_cargo("clean", []);
|
|
||||||
runner.run_cargo("build", ["--all-targets", "--target", &runner.target_triple]);
|
|
||||||
|
|
||||||
if runner.host_triple == runner.target_triple {
|
let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs);
|
||||||
runner.run_cargo("test", ["-q"]);
|
build_cmd.arg("--all-targets");
|
||||||
}
|
spawn_and_wait(build_cmd);
|
||||||
});
|
|
||||||
|
if runner.is_native {
|
||||||
|
let mut test_cmd = PORTABLE_SIMD.test(&runner.target_compiler, &runner.dirs);
|
||||||
|
test_cmd.arg("-q");
|
||||||
|
spawn_and_wait(test_cmd);
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
pub(crate) fn run_tests(
|
pub(crate) fn run_tests(
|
||||||
|
dirs: &Dirs,
|
||||||
channel: &str,
|
channel: &str,
|
||||||
sysroot_kind: SysrootKind,
|
sysroot_kind: SysrootKind,
|
||||||
target_dir: &Path,
|
|
||||||
cg_clif_dylib: &Path,
|
cg_clif_dylib: &Path,
|
||||||
host_triple: &str,
|
host_triple: &str,
|
||||||
target_triple: &str,
|
target_triple: &str,
|
||||||
) {
|
) {
|
||||||
let runner = TestRunner::new(host_triple.to_string(), target_triple.to_string());
|
let runner = TestRunner::new(dirs.clone(), host_triple.to_string(), target_triple.to_string());
|
||||||
|
|
||||||
if config::get_bool("testsuite.no_sysroot") {
|
if config::get_bool("testsuite.no_sysroot") {
|
||||||
build_sysroot::build_sysroot(
|
build_sysroot::build_sysroot(
|
||||||
|
dirs,
|
||||||
channel,
|
channel,
|
||||||
SysrootKind::None,
|
SysrootKind::None,
|
||||||
&target_dir,
|
|
||||||
cg_clif_dylib,
|
cg_clif_dylib,
|
||||||
&host_triple,
|
&host_triple,
|
||||||
&target_triple,
|
&target_triple,
|
||||||
);
|
);
|
||||||
|
|
||||||
let _ = fs::remove_dir_all(Path::new("target").join("out"));
|
BUILD_EXAMPLE_OUT_DIR.ensure_fresh(dirs);
|
||||||
runner.run_testsuite(NO_SYSROOT_SUITE);
|
runner.run_testsuite(NO_SYSROOT_SUITE);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("[SKIP] no_sysroot tests");
|
eprintln!("[SKIP] no_sysroot tests");
|
||||||
|
@ -419,9 +471,9 @@ pub(crate) fn run_tests(
|
||||||
|
|
||||||
if run_base_sysroot || run_extended_sysroot {
|
if run_base_sysroot || run_extended_sysroot {
|
||||||
build_sysroot::build_sysroot(
|
build_sysroot::build_sysroot(
|
||||||
|
dirs,
|
||||||
channel,
|
channel,
|
||||||
sysroot_kind,
|
sysroot_kind,
|
||||||
&target_dir,
|
|
||||||
cg_clif_dylib,
|
cg_clif_dylib,
|
||||||
&host_triple,
|
&host_triple,
|
||||||
&target_triple,
|
&target_triple,
|
||||||
|
@ -442,40 +494,50 @@ pub(crate) fn run_tests(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TestRunner {
|
struct TestRunner {
|
||||||
root_dir: PathBuf,
|
is_native: bool,
|
||||||
out_dir: PathBuf,
|
|
||||||
jit_supported: bool,
|
jit_supported: bool,
|
||||||
rust_flags: String,
|
dirs: Dirs,
|
||||||
run_wrapper: Vec<String>,
|
host_compiler: Compiler,
|
||||||
host_triple: String,
|
target_compiler: Compiler,
|
||||||
target_triple: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestRunner {
|
impl TestRunner {
|
||||||
pub fn new(host_triple: String, target_triple: String) -> Self {
|
pub fn new(dirs: Dirs, host_triple: String, target_triple: String) -> Self {
|
||||||
let root_dir = env::current_dir().unwrap();
|
|
||||||
|
|
||||||
let mut out_dir = root_dir.clone();
|
|
||||||
out_dir.push("target");
|
|
||||||
out_dir.push("out");
|
|
||||||
|
|
||||||
let is_native = host_triple == target_triple;
|
let is_native = host_triple == target_triple;
|
||||||
let jit_supported =
|
let jit_supported =
|
||||||
target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
|
target_triple.contains("x86_64") && is_native && !host_triple.contains("windows");
|
||||||
|
|
||||||
let mut rust_flags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
|
let rustc_clif =
|
||||||
let mut run_wrapper = Vec::new();
|
RelPath::DIST.to_path(&dirs).join(get_wrapper_file_name("rustc-clif", "bin"));
|
||||||
|
let rustdoc_clif =
|
||||||
|
RelPath::DIST.to_path(&dirs).join(get_wrapper_file_name("rustdoc-clif", "bin"));
|
||||||
|
|
||||||
|
let mut rustflags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string());
|
||||||
|
let mut runner = vec![];
|
||||||
|
|
||||||
if !is_native {
|
if !is_native {
|
||||||
match target_triple.as_str() {
|
match target_triple.as_str() {
|
||||||
"aarch64-unknown-linux-gnu" => {
|
"aarch64-unknown-linux-gnu" => {
|
||||||
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
|
// We are cross-compiling for aarch64. Use the correct linker and run tests in qemu.
|
||||||
rust_flags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rust_flags);
|
rustflags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rustflags);
|
||||||
run_wrapper = vec!["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu"];
|
runner = vec![
|
||||||
|
"qemu-aarch64".to_owned(),
|
||||||
|
"-L".to_owned(),
|
||||||
|
"/usr/aarch64-linux-gnu".to_owned(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
"s390x-unknown-linux-gnu" => {
|
||||||
|
// We are cross-compiling for s390x. Use the correct linker and run tests in qemu.
|
||||||
|
rustflags = format!("-Clinker=s390x-linux-gnu-gcc{}", rustflags);
|
||||||
|
runner = vec![
|
||||||
|
"qemu-s390x".to_owned(),
|
||||||
|
"-L".to_owned(),
|
||||||
|
"/usr/s390x-linux-gnu".to_owned(),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
"x86_64-pc-windows-gnu" => {
|
"x86_64-pc-windows-gnu" => {
|
||||||
// We are cross-compiling for Windows. Run tests in wine.
|
// We are cross-compiling for Windows. Run tests in wine.
|
||||||
run_wrapper = vec!["wine"];
|
runner = vec!["wine".to_owned()];
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown non-native platform");
|
println!("Unknown non-native platform");
|
||||||
|
@ -484,19 +546,31 @@ impl TestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME fix `#[linkage = "extern_weak"]` without this
|
// FIXME fix `#[linkage = "extern_weak"]` without this
|
||||||
if host_triple.contains("darwin") {
|
if target_triple.contains("darwin") {
|
||||||
rust_flags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rust_flags);
|
rustflags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rustflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
let host_compiler = Compiler {
|
||||||
root_dir,
|
cargo: get_cargo_path(),
|
||||||
out_dir,
|
rustc: rustc_clif.clone(),
|
||||||
jit_supported,
|
rustdoc: rustdoc_clif.clone(),
|
||||||
rust_flags,
|
rustflags: String::new(),
|
||||||
run_wrapper: run_wrapper.iter().map(|s| s.to_string()).collect(),
|
rustdocflags: String::new(),
|
||||||
host_triple,
|
triple: host_triple,
|
||||||
target_triple,
|
runner: vec![],
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let target_compiler = Compiler {
|
||||||
|
cargo: get_cargo_path(),
|
||||||
|
rustc: rustc_clif,
|
||||||
|
rustdoc: rustdoc_clif,
|
||||||
|
rustflags: rustflags.clone(),
|
||||||
|
rustdocflags: rustflags,
|
||||||
|
triple: target_triple,
|
||||||
|
runner,
|
||||||
|
};
|
||||||
|
|
||||||
|
Self { is_native, jit_supported, dirs, host_compiler, target_compiler }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_testsuite(&self, tests: &[TestCase]) {
|
pub fn run_testsuite(&self, tests: &[TestCase]) {
|
||||||
|
@ -516,29 +590,18 @@ impl TestRunner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_dir(&self, new: impl AsRef<Path>, callback: impl FnOnce(&TestRunner)) {
|
#[must_use]
|
||||||
let current = env::current_dir().unwrap();
|
|
||||||
|
|
||||||
env::set_current_dir(new).unwrap();
|
|
||||||
callback(self);
|
|
||||||
env::set_current_dir(current).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn rustc_command<I, S>(&self, args: I) -> Command
|
fn rustc_command<I, S>(&self, args: I) -> Command
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = S>,
|
I: IntoIterator<Item = S>,
|
||||||
S: AsRef<OsStr>,
|
S: AsRef<OsStr>,
|
||||||
{
|
{
|
||||||
let mut rustc_clif = self.root_dir.clone();
|
let mut cmd = Command::new(&self.target_compiler.rustc);
|
||||||
rustc_clif.push("build");
|
cmd.args(self.target_compiler.rustflags.split_whitespace());
|
||||||
rustc_clif.push(get_wrapper_file_name("rustc-clif", "bin"));
|
|
||||||
|
|
||||||
let mut cmd = Command::new(rustc_clif);
|
|
||||||
cmd.args(self.rust_flags.split_whitespace());
|
|
||||||
cmd.arg("-L");
|
cmd.arg("-L");
|
||||||
cmd.arg(format!("crate={}", self.out_dir.display()));
|
cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
|
||||||
cmd.arg("--out-dir");
|
cmd.arg("--out-dir");
|
||||||
cmd.arg(format!("{}", self.out_dir.display()));
|
cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display()));
|
||||||
cmd.arg("-Cdebuginfo=2");
|
cmd.arg("-Cdebuginfo=2");
|
||||||
cmd.args(args);
|
cmd.args(args);
|
||||||
cmd
|
cmd
|
||||||
|
@ -559,15 +622,13 @@ impl TestRunner {
|
||||||
let mut full_cmd = vec![];
|
let mut full_cmd = vec![];
|
||||||
|
|
||||||
// Prepend the RUN_WRAPPER's
|
// Prepend the RUN_WRAPPER's
|
||||||
if !self.run_wrapper.is_empty() {
|
if !self.target_compiler.runner.is_empty() {
|
||||||
full_cmd.extend(self.run_wrapper.iter().cloned());
|
full_cmd.extend(self.target_compiler.runner.iter().cloned());
|
||||||
}
|
}
|
||||||
|
|
||||||
full_cmd.push({
|
full_cmd.push(
|
||||||
let mut out_path = self.out_dir.clone();
|
BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).join(name).to_str().unwrap().to_string(),
|
||||||
out_path.push(name);
|
);
|
||||||
out_path.to_str().unwrap().to_string()
|
|
||||||
});
|
|
||||||
|
|
||||||
for arg in args.into_iter() {
|
for arg in args.into_iter() {
|
||||||
full_cmd.push(arg.to_string());
|
full_cmd.push(arg.to_string());
|
||||||
|
@ -581,30 +642,4 @@ impl TestRunner {
|
||||||
|
|
||||||
spawn_and_wait(cmd);
|
spawn_and_wait(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cargo_command<'a, I>(&self, subcommand: &str, args: I) -> Command
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = &'a str>,
|
|
||||||
{
|
|
||||||
let mut cargo_clif = self.root_dir.clone();
|
|
||||||
cargo_clif.push("build");
|
|
||||||
cargo_clif.push(get_wrapper_file_name("cargo-clif", "bin"));
|
|
||||||
|
|
||||||
let mut cmd = cargo_command(
|
|
||||||
cargo_clif,
|
|
||||||
subcommand,
|
|
||||||
if subcommand == "clean" { None } else { Some(&self.target_triple) },
|
|
||||||
Path::new("."),
|
|
||||||
);
|
|
||||||
cmd.args(args);
|
|
||||||
cmd.env("RUSTFLAGS", &self.rust_flags);
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run_cargo<'a, I>(&self, subcommand: &str, args: I)
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = &'a str>,
|
|
||||||
{
|
|
||||||
spawn_and_wait(self.cargo_command(subcommand, args));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,138 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::{self, Command, Stdio};
|
use std::process::{self, Command, Stdio};
|
||||||
|
|
||||||
pub(crate) fn cargo_command(
|
use super::path::{Dirs, RelPath};
|
||||||
cargo: impl AsRef<Path>,
|
use super::rustc_info::{get_cargo_path, get_host_triple, get_rustc_path, get_rustdoc_path};
|
||||||
subcommand: &str,
|
|
||||||
triple: Option<&str>,
|
|
||||||
source_dir: &Path,
|
|
||||||
) -> Command {
|
|
||||||
let mut cmd = Command::new(cargo.as_ref());
|
|
||||||
cmd.arg(subcommand)
|
|
||||||
.arg("--manifest-path")
|
|
||||||
.arg(source_dir.join("Cargo.toml"))
|
|
||||||
.arg("--target-dir")
|
|
||||||
.arg(source_dir.join("target"));
|
|
||||||
|
|
||||||
if let Some(triple) = triple {
|
pub(crate) struct Compiler {
|
||||||
cmd.arg("--target").arg(triple);
|
pub(crate) cargo: PathBuf,
|
||||||
}
|
pub(crate) rustc: PathBuf,
|
||||||
|
pub(crate) rustdoc: PathBuf,
|
||||||
cmd
|
pub(crate) rustflags: String,
|
||||||
|
pub(crate) rustdocflags: String,
|
||||||
|
pub(crate) triple: String,
|
||||||
|
pub(crate) runner: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Compiler {
|
||||||
|
pub(crate) fn host() -> Compiler {
|
||||||
|
Compiler {
|
||||||
|
cargo: get_cargo_path(),
|
||||||
|
rustc: get_rustc_path(),
|
||||||
|
rustdoc: get_rustdoc_path(),
|
||||||
|
rustflags: String::new(),
|
||||||
|
rustdocflags: String::new(),
|
||||||
|
triple: get_host_triple(),
|
||||||
|
runner: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_triple(triple: String) -> Compiler {
|
||||||
|
Compiler {
|
||||||
|
cargo: get_cargo_path(),
|
||||||
|
rustc: get_rustc_path(),
|
||||||
|
rustdoc: get_rustdoc_path(),
|
||||||
|
rustflags: String::new(),
|
||||||
|
rustdocflags: String::new(),
|
||||||
|
triple,
|
||||||
|
runner: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct CargoProject {
|
||||||
|
source: &'static RelPath,
|
||||||
|
target: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CargoProject {
|
||||||
|
pub(crate) const fn new(path: &'static RelPath, target: &'static str) -> CargoProject {
|
||||||
|
CargoProject { source: path, target }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn source_dir(&self, dirs: &Dirs) -> PathBuf {
|
||||||
|
self.source.to_path(dirs)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn manifest_path(&self, dirs: &Dirs) -> PathBuf {
|
||||||
|
self.source_dir(dirs).join("Cargo.toml")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn target_dir(&self, dirs: &Dirs) -> PathBuf {
|
||||||
|
RelPath::BUILD.join(self.target).to_path(dirs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn base_cmd(&self, command: &str, cargo: &Path, dirs: &Dirs) -> Command {
|
||||||
|
let mut cmd = Command::new(cargo);
|
||||||
|
|
||||||
|
cmd.arg(command)
|
||||||
|
.arg("--manifest-path")
|
||||||
|
.arg(self.manifest_path(dirs))
|
||||||
|
.arg("--target-dir")
|
||||||
|
.arg(self.target_dir(dirs));
|
||||||
|
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_cmd(&self, command: &str, compiler: &Compiler, dirs: &Dirs) -> Command {
|
||||||
|
let mut cmd = self.base_cmd(command, &compiler.cargo, dirs);
|
||||||
|
|
||||||
|
cmd.arg("--target").arg(&compiler.triple);
|
||||||
|
|
||||||
|
cmd.env("RUSTC", &compiler.rustc);
|
||||||
|
cmd.env("RUSTDOC", &compiler.rustdoc);
|
||||||
|
cmd.env("RUSTFLAGS", &compiler.rustflags);
|
||||||
|
cmd.env("RUSTDOCFLAGS", &compiler.rustdocflags);
|
||||||
|
if !compiler.runner.is_empty() {
|
||||||
|
cmd.env(
|
||||||
|
format!("CARGO_TARGET_{}_RUNNER", compiler.triple.to_uppercase().replace('-', "_")),
|
||||||
|
compiler.runner.join(" "),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn fetch(&self, cargo: impl AsRef<Path>, dirs: &Dirs) -> Command {
|
||||||
|
let mut cmd = Command::new(cargo.as_ref());
|
||||||
|
|
||||||
|
cmd.arg("fetch").arg("--manifest-path").arg(self.manifest_path(dirs));
|
||||||
|
|
||||||
|
cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn clean(&self, cargo: &Path, dirs: &Dirs) -> Command {
|
||||||
|
self.base_cmd("clean", cargo, dirs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn build(&self, compiler: &Compiler, dirs: &Dirs) -> Command {
|
||||||
|
self.build_cmd("build", compiler, dirs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn test(&self, compiler: &Compiler, dirs: &Dirs) -> Command {
|
||||||
|
self.build_cmd("test", compiler, dirs)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub(crate) fn run(&self, compiler: &Compiler, dirs: &Dirs) -> Command {
|
||||||
|
self.build_cmd("run", compiler, dirs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
pub(crate) fn hyperfine_command(
|
pub(crate) fn hyperfine_command(
|
||||||
warmup: u64,
|
warmup: u64,
|
||||||
runs: u64,
|
runs: u64,
|
||||||
prepare: Option<Command>,
|
prepare: Option<&str>,
|
||||||
a: Command,
|
a: &str,
|
||||||
b: Command,
|
b: &str,
|
||||||
) -> Command {
|
) -> Command {
|
||||||
let mut bench = Command::new("hyperfine");
|
let mut bench = Command::new("hyperfine");
|
||||||
|
|
||||||
|
@ -42,10 +145,10 @@ pub(crate) fn hyperfine_command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(prepare) = prepare {
|
if let Some(prepare) = prepare {
|
||||||
bench.arg("--prepare").arg(format!("{:?}", prepare));
|
bench.arg("--prepare").arg(prepare);
|
||||||
}
|
}
|
||||||
|
|
||||||
bench.arg(format!("{:?}", a)).arg(format!("{:?}", b));
|
bench.arg(a).arg(b);
|
||||||
|
|
||||||
bench
|
bench
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
|
rm -rf build_sysroot/{sysroot_src/,target/,compiler-builtins/,rustc_version}
|
||||||
rm -rf target/ build/ perf.data{,.old} y.bin
|
rm -rf target/ build/ dist/ perf.data{,.old} y.bin
|
||||||
rm -rf download/
|
rm -rf download/
|
||||||
|
|
||||||
# Kept for now in case someone updates their checkout of cg_clif before running clean_all.sh
|
# Kept for now in case someone updates their checkout of cg_clif before running clean_all.sh
|
||||||
|
|
|
@ -40,6 +40,7 @@ aot.subslice-patterns-const-eval
|
||||||
aot.track-caller-attribute
|
aot.track-caller-attribute
|
||||||
aot.float-minmax-pass
|
aot.float-minmax-pass
|
||||||
aot.mod_bench
|
aot.mod_bench
|
||||||
|
aot.issue-72793
|
||||||
|
|
||||||
testsuite.extended_sysroot
|
testsuite.extended_sysroot
|
||||||
test.rust-random/rand
|
test.rust-random/rand
|
||||||
|
|
|
@ -9,7 +9,7 @@ Assuming `$cg_clif_dir` is the directory you cloned this repo into and you follo
|
||||||
In the directory with your project (where you can do the usual `cargo build`), run:
|
In the directory with your project (where you can do the usual `cargo build`), run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/cargo-clif build
|
$ $cg_clif_dir/dist/cargo-clif build
|
||||||
```
|
```
|
||||||
|
|
||||||
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
This will build your project with rustc_codegen_cranelift instead of the usual LLVM backend.
|
||||||
|
@ -19,7 +19,7 @@ This will build your project with rustc_codegen_cranelift instead of the usual L
|
||||||
> You should prefer using the Cargo method.
|
> You should prefer using the Cargo method.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/rustc-clif my_crate.rs
|
$ $cg_clif_dir/dist/rustc-clif my_crate.rs
|
||||||
```
|
```
|
||||||
|
|
||||||
## Jit mode
|
## Jit mode
|
||||||
|
@ -32,20 +32,20 @@ In jit mode cg_clif will immediately execute your code without creating an execu
|
||||||
> The jit mode will probably need cargo integration to make this possible.
|
> The jit mode will probably need cargo integration to make this possible.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/cargo-clif jit
|
$ $cg_clif_dir/dist/cargo-clif jit
|
||||||
```
|
```
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/rustc-clif -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic my_crate.rs
|
$ $cg_clif_dir/dist/rustc-clif -Zunstable-features -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
|
There is also an experimental lazy jit mode. In this mode functions are only compiled once they are
|
||||||
first called.
|
first called.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ $cg_clif_dir/build/cargo-clif lazy-jit
|
$ $cg_clif_dir/dist/cargo-clif lazy-jit
|
||||||
```
|
```
|
||||||
|
|
||||||
## Shell
|
## Shell
|
||||||
|
@ -54,7 +54,7 @@ These are a few functions that allow you to easily run rust code from the shell
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
function jit_naked() {
|
function jit_naked() {
|
||||||
echo "$@" | $cg_clif_dir/build/rustc-clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic
|
echo "$@" | $cg_clif_dir/dist/rustc-clif - -Zunstable-features -Cllvm-args=mode=jit -Cprefer-dynamic
|
||||||
}
|
}
|
||||||
|
|
||||||
function jit() {
|
function jit() {
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Adapted from rustc ui test suite (ui/type-alias-impl-trait/issue-72793.rs)
|
||||||
|
|
||||||
|
#![feature(type_alias_impl_trait)]
|
||||||
|
|
||||||
|
trait T { type Item; }
|
||||||
|
|
||||||
|
type Alias<'a> = impl T<Item = &'a ()>;
|
||||||
|
|
||||||
|
struct S;
|
||||||
|
impl<'a> T for &'a S {
|
||||||
|
type Item = &'a ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn filter_positive<'a>() -> Alias<'a> {
|
||||||
|
&S
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_positive(fun: impl Fn(Alias<'_>)) {
|
||||||
|
fun(filter_positive());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
with_positive(|_| ());
|
||||||
|
}
|
|
@ -19,6 +19,9 @@ pub trait Sized {}
|
||||||
#[lang = "destruct"]
|
#[lang = "destruct"]
|
||||||
pub trait Destruct {}
|
pub trait Destruct {}
|
||||||
|
|
||||||
|
#[lang = "tuple_trait"]
|
||||||
|
pub trait Tuple {}
|
||||||
|
|
||||||
#[lang = "unsize"]
|
#[lang = "unsize"]
|
||||||
pub trait Unsize<T: ?Sized> {}
|
pub trait Unsize<T: ?Sized> {}
|
||||||
|
|
||||||
|
@ -443,7 +446,7 @@ pub struct PhantomData<T: ?Sized>;
|
||||||
|
|
||||||
#[lang = "fn_once"]
|
#[lang = "fn_once"]
|
||||||
#[rustc_paren_sugar]
|
#[rustc_paren_sugar]
|
||||||
pub trait FnOnce<Args> {
|
pub trait FnOnce<Args: Tuple> {
|
||||||
#[lang = "fn_once_output"]
|
#[lang = "fn_once_output"]
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
|
@ -452,7 +455,7 @@ pub trait FnOnce<Args> {
|
||||||
|
|
||||||
#[lang = "fn_mut"]
|
#[lang = "fn_mut"]
|
||||||
#[rustc_paren_sugar]
|
#[rustc_paren_sugar]
|
||||||
pub trait FnMut<Args>: FnOnce<Args> {
|
pub trait FnMut<Args: Tuple>: FnOnce<Args> {
|
||||||
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,8 +171,6 @@ fn main() {
|
||||||
|
|
||||||
assert_eq!(slice_ptr as usize % 4, 0);
|
assert_eq!(slice_ptr as usize % 4, 0);
|
||||||
|
|
||||||
//return;
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
|
printf("Hello %s\n\0" as *const str as *const i8, "printf\0" as *const str as *const i8);
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,8 @@ unsafe fn test_simd() {
|
||||||
let cmp_eq = _mm_cmpeq_epi8(y, y);
|
let cmp_eq = _mm_cmpeq_epi8(y, y);
|
||||||
let cmp_lt = _mm_cmplt_epi8(y, y);
|
let cmp_lt = _mm_cmplt_epi8(y, y);
|
||||||
|
|
||||||
|
let (zero0, zero1) = std::mem::transmute::<_, (u64, u64)>(x);
|
||||||
|
assert_eq!((zero0, zero1), (0, 0));
|
||||||
assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]);
|
assert_eq!(std::mem::transmute::<_, [u16; 8]>(or), [7, 7, 7, 7, 7, 7, 7, 7]);
|
||||||
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_eq), [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff]);
|
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_eq), [0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff]);
|
||||||
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]);
|
assert_eq!(std::mem::transmute::<_, [u16; 8]>(cmp_lt), [0, 0, 0, 0, 0, 0, 0, 0]);
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2022-10-23"
|
channel = "nightly-2022-12-13"
|
||||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
ignore = ["y.rs"]
|
||||||
|
|
||||||
# Matches rustfmt.toml of rustc
|
# Matches rustfmt.toml of rustc
|
||||||
version = "Two"
|
version = "Two"
|
||||||
use_small_heuristics = "Max"
|
use_small_heuristics = "Max"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#![forbid(unsafe_code)]/* This line is ignored by bash
|
#![forbid(unsafe_code)]/* This line is ignored by bash
|
||||||
# This block is ignored by rustc
|
# This block is ignored by rustc
|
||||||
pushd $(dirname "$0")/../
|
pushd $(dirname "$0")/../
|
||||||
RUSTC="$(pwd)/build/rustc-clif"
|
RUSTC="$(pwd)/dist/rustc-clif"
|
||||||
popd
|
popd
|
||||||
PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic $0
|
PROFILE=$1 OUTPUT=$2 exec $RUSTC -Zunstable-options -Cllvm-args=mode=jit -Cprefer-dynamic $0
|
||||||
#*/
|
#*/
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
|
#[cfg(unix)]
|
||||||
|
use std::os::unix::process::CommandExt;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let sysroot = PathBuf::from(env::current_exe().unwrap().parent().unwrap());
|
||||||
|
|
||||||
|
let cg_clif_dylib_path = sysroot.join(if cfg!(windows) { "bin" } else { "lib" }).join(
|
||||||
|
env::consts::DLL_PREFIX.to_string() + "rustc_codegen_cranelift" + env::consts::DLL_SUFFIX,
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut args = std::env::args_os().skip(1).collect::<Vec<_>>();
|
||||||
|
args.push(OsString::from("-Cpanic=abort"));
|
||||||
|
args.push(OsString::from("-Zpanic-abort-tests"));
|
||||||
|
let mut codegen_backend_arg = OsString::from("-Zcodegen-backend=");
|
||||||
|
codegen_backend_arg.push(cg_clif_dylib_path);
|
||||||
|
args.push(codegen_backend_arg);
|
||||||
|
if !args.contains(&OsString::from("--sysroot")) {
|
||||||
|
args.push(OsString::from("--sysroot"));
|
||||||
|
args.push(OsString::from(sysroot.to_str().unwrap()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the right toolchain is used
|
||||||
|
env::set_var("RUSTUP_TOOLCHAIN", env!("RUSTUP_TOOLCHAIN"));
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
Command::new("rustdoc").args(args).exec();
|
||||||
|
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
std::process::exit(
|
||||||
|
Command::new("rustdoc").args(args).spawn().unwrap().wait().unwrap().code().unwrap_or(1),
|
||||||
|
);
|
||||||
|
}
|
|
@ -27,24 +27,6 @@ index d95b5b7f17f..00b6f0e3635 100644
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
rand_xorshift = "0.2"
|
rand_xorshift = "0.2"
|
||||||
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
|
|
||||||
index 8431aa7b818..a3ff7e68ce5 100644
|
|
||||||
--- a/src/tools/compiletest/src/runtest.rs
|
|
||||||
+++ b/src/tools/compiletest/src/runtest.rs
|
|
||||||
@@ -3489,12 +3489,7 @@ fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> S
|
|
||||||
let compiler_src_dir = base_dir.join("compiler");
|
|
||||||
normalize_path(&compiler_src_dir, "$(echo '$COMPILER_DIR')");
|
|
||||||
|
|
||||||
- if let Some(virtual_rust_source_base_dir) =
|
|
||||||
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(PathBuf::from)
|
|
||||||
- {
|
|
||||||
- normalize_path(&virtual_rust_source_base_dir.join("library"), "$(echo '$SRC_DIR')");
|
|
||||||
- normalize_path(&virtual_rust_source_base_dir.join("compiler"), "$(echo '$COMPILER_DIR')");
|
|
||||||
- }
|
|
||||||
+ normalize_path(&Path::new("$(cd ../build_sysroot/sysroot_src/library; pwd)"), "$(echo '$SRC_DIR')");
|
|
||||||
|
|
||||||
// Paths into the build directory
|
|
||||||
let test_build_dir = &self.config.build_base;
|
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat > config.toml <<EOF
|
cat > config.toml <<EOF
|
||||||
|
@ -54,7 +36,7 @@ changelog-seen = 2
|
||||||
ninja = false
|
ninja = false
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
rustc = "$(pwd)/../build/rustc-clif"
|
rustc = "$(pwd)/../dist/rustc-clif"
|
||||||
cargo = "$(rustup which cargo)"
|
cargo = "$(rustup which cargo)"
|
||||||
full-bootstrap = true
|
full-bootstrap = true
|
||||||
local-rebuild = true
|
local-rebuild = true
|
||||||
|
@ -69,6 +51,8 @@ popd
|
||||||
# FIXME remove once inline asm is fully supported
|
# FIXME remove once inline asm is fully supported
|
||||||
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
|
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
|
||||||
|
|
||||||
|
export CFG_VIRTUAL_RUST_SOURCE_BASE_DIR="$(cd build_sysroot/sysroot_src; pwd)"
|
||||||
|
|
||||||
# Allow the testsuite to use llvm tools
|
# Allow the testsuite to use llvm tools
|
||||||
host_triple=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ")
|
host_triple=$(rustc -vV | grep host | cut -d: -f2 | tr -d " ")
|
||||||
export LLVM_BIN_DIR="$(rustc --print sysroot)/lib/rustlib/$host_triple/bin"
|
export LLVM_BIN_DIR="$(rustc --print sysroot)/lib/rustlib/$host_triple/bin"
|
||||||
|
|
|
@ -20,6 +20,7 @@ for test in $(rg -i --files-with-matches "//(\[\w+\])?~[^\|]*\s*ERR|// error-pat
|
||||||
done
|
done
|
||||||
|
|
||||||
git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
git checkout -- src/test/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
||||||
|
git checkout -- src/test/ui/proc-macro/pretty-print-hack/
|
||||||
|
|
||||||
# missing features
|
# missing features
|
||||||
# ================
|
# ================
|
||||||
|
@ -30,6 +31,7 @@ rm src/test/incremental/issue-80691-bad-eval-cache.rs # -Cpanic=abort causes abo
|
||||||
|
|
||||||
# requires compiling with -Cpanic=unwind
|
# requires compiling with -Cpanic=unwind
|
||||||
rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/
|
rm -r src/test/ui/macros/rfc-2011-nicer-assert-messages/
|
||||||
|
rm -r src/test/run-make/test-benches
|
||||||
|
|
||||||
# vendor intrinsics
|
# vendor intrinsics
|
||||||
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
|
||||||
|
@ -64,6 +66,8 @@ rm src/test/ui/fn/dyn-fn-alignment.rs # wants a 256 byte alignment
|
||||||
rm -r src/test/run-make/emit-named-files # requires full --emit support
|
rm -r src/test/run-make/emit-named-files # requires full --emit support
|
||||||
rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented
|
rm src/test/ui/abi/stack-probes.rs # stack probes not yet implemented
|
||||||
rm src/test/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
|
rm src/test/ui/simd/intrinsic/ptr-cast.rs # simd_expose_addr intrinsic unimplemented
|
||||||
|
rm -r src/test/run-make/repr128-dwarf # debuginfo test
|
||||||
|
rm src/test/codegen-units/item-collection/asm-sym.rs # requires support for sym in asm!()
|
||||||
|
|
||||||
# optimization tests
|
# optimization tests
|
||||||
# ==================
|
# ==================
|
||||||
|
@ -82,20 +86,20 @@ rm src/test/ui/abi/stack-protector.rs # requires stack protector support
|
||||||
rm src/test/ui/mir/mir_misc_casts.rs # depends on deduplication of constants
|
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/mir/mir_raw_fat_ptr.rs # same
|
||||||
rm src/test/ui/consts/issue-33537.rs # same
|
rm src/test/ui/consts/issue-33537.rs # same
|
||||||
|
rm src/test/ui/layout/valid_range_oob.rs # different ICE message
|
||||||
|
|
||||||
# doesn't work due to the way the rustc test suite is invoked.
|
# doesn't work due to the way the rustc test suite is invoked.
|
||||||
# should work when using ./x.py test the way it is intended
|
# should work when using ./x.py test the way it is intended
|
||||||
# ============================================================
|
# ============================================================
|
||||||
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
|
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in dist/bin/
|
||||||
rm -r src/test/run-make/unstable-flag-required # same
|
rm -r src/test/run-make/unstable-flag-required # same
|
||||||
rm -r src/test/run-make/rustdoc-* # same
|
rm -r src/test/run-make/rustdoc-* # same
|
||||||
rm -r src/test/run-make/issue-88756-default-output # same
|
rm -r src/test/run-make/issue-88756-default-output # same
|
||||||
rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
|
rm -r src/test/run-make/remap-path-prefix-dwarf # requires llvm-dwarfdump
|
||||||
|
rm -r src/test/ui/consts/missing_span_in_backtrace.rs # expects sysroot source to be elsewhere
|
||||||
|
|
||||||
# genuine bugs
|
# genuine bugs
|
||||||
# ============
|
# ============
|
||||||
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
|
|
||||||
|
|
||||||
rm src/test/incremental/spike-neg1.rs # errors out for some reason
|
rm src/test/incremental/spike-neg1.rs # errors out for some reason
|
||||||
rm src/test/incremental/spike-neg2.rs # same
|
rm src/test/incremental/spike-neg2.rs # same
|
||||||
rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
|
rm src/test/ui/issues/issue-74564-if-expr-stack-overflow.rs # gives a stackoverflow before the backend runs
|
||||||
|
@ -104,6 +108,8 @@ rm src/test/ui/type-alias-impl-trait/assoc-projection-ice.rs # produces ICE
|
||||||
|
|
||||||
rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
|
rm src/test/ui/simd/intrinsic/generic-reduction-pass.rs # simd_reduce_add_unordered doesn't accept an accumulator for integer vectors
|
||||||
|
|
||||||
|
rm src/test/ui/runtime/out-of-stack.rs # SIGSEGV instead of SIGABRT for some reason (#1301)
|
||||||
|
|
||||||
# bugs in the test suite
|
# bugs in the test suite
|
||||||
# ======================
|
# ======================
|
||||||
rm src/test/ui/backtrace.rs # TODO warning
|
rm src/test/ui/backtrace.rs # TODO warning
|
||||||
|
@ -111,6 +117,8 @@ rm src/test/ui/simple_global_asm.rs # TODO add needs-asm-support
|
||||||
rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
|
rm src/test/ui/test-attrs/test-type.rs # TODO panic message on stderr. correct stdout
|
||||||
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
|
# not sure if this is actually a bug in the test suite, but the symbol list shows the function without leading _ for some reason
|
||||||
rm -r src/test/run-make/native-link-modifier-bundle
|
rm -r src/test/run-make/native-link-modifier-bundle
|
||||||
|
rm src/test/ui/process/nofile-limit.rs # TODO some AArch64 linking issue
|
||||||
|
rm src/test/ui/dyn-star/dispatch-on-pin-mut.rs # TODO failed assertion in vtable::get_ptr_and_method_ref
|
||||||
|
|
||||||
rm src/test/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
|
rm src/test/ui/stdio-is-blocking.rs # really slow with unoptimized libstd
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,13 @@ pub(crate) fn conv_to_call_conv(c: Conv, default_call_conv: CallConv) -> CallCon
|
||||||
|
|
||||||
pub(crate) fn get_function_sig<'tcx>(
|
pub(crate) fn get_function_sig<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
triple: &target_lexicon::Triple,
|
default_call_conv: CallConv,
|
||||||
inst: Instance<'tcx>,
|
inst: Instance<'tcx>,
|
||||||
) -> Signature {
|
) -> Signature {
|
||||||
assert!(!inst.substs.needs_infer());
|
assert!(!inst.substs.needs_infer());
|
||||||
clif_sig_from_fn_abi(
|
clif_sig_from_fn_abi(
|
||||||
tcx,
|
tcx,
|
||||||
CallConv::triple_default(triple),
|
default_call_conv,
|
||||||
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
|
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ pub(crate) fn import_function<'tcx>(
|
||||||
inst: Instance<'tcx>,
|
inst: Instance<'tcx>,
|
||||||
) -> FuncId {
|
) -> FuncId {
|
||||||
let name = tcx.symbol_name(inst).name;
|
let name = tcx.symbol_name(inst).name;
|
||||||
let sig = get_function_sig(tcx, module.isa().triple(), inst);
|
let sig = get_function_sig(tcx, module.target_config().default_call_conv, inst);
|
||||||
match module.declare_function(name, Linkage::Import, &sig) {
|
match module.declare_function(name, Linkage::Import, &sig) {
|
||||||
Ok(func_id) => func_id,
|
Ok(func_id) => func_id,
|
||||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||||
|
@ -341,14 +341,13 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
destination: Place<'tcx>,
|
destination: Place<'tcx>,
|
||||||
target: Option<BasicBlock>,
|
target: Option<BasicBlock>,
|
||||||
) {
|
) {
|
||||||
let fn_ty = fx.monomorphize(func.ty(fx.mir, fx.tcx));
|
let func = codegen_operand(fx, func);
|
||||||
let fn_sig =
|
let fn_sig = func.layout().ty.fn_sig(fx.tcx);
|
||||||
fx.tcx.normalize_erasing_late_bound_regions(ParamEnv::reveal_all(), fn_ty.fn_sig(fx.tcx));
|
|
||||||
|
|
||||||
let ret_place = codegen_place(fx, destination);
|
let ret_place = codegen_place(fx, destination);
|
||||||
|
|
||||||
// Handle special calls like intrinsics and empty drop glue.
|
// Handle special calls like intrinsics and empty drop glue.
|
||||||
let instance = if let ty::FnDef(def_id, substs) = *fn_ty.kind() {
|
let instance = if let ty::FnDef(def_id, substs) = *func.layout().ty.kind() {
|
||||||
let instance =
|
let instance =
|
||||||
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
|
ty::Instance::expect_resolve(fx.tcx, ty::ParamEnv::reveal_all(), def_id, substs)
|
||||||
.polymorphize(fx.tcx);
|
.polymorphize(fx.tcx);
|
||||||
|
@ -390,17 +389,17 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let extra_args = &args[fn_sig.inputs().len()..];
|
let extra_args = &args[fn_sig.inputs().skip_binder().len()..];
|
||||||
let extra_args = fx
|
let extra_args = fx
|
||||||
.tcx
|
.tcx
|
||||||
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
|
.mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))));
|
||||||
let fn_abi = if let Some(instance) = instance {
|
let fn_abi = if let Some(instance) = instance {
|
||||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
|
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args)
|
||||||
} else {
|
} else {
|
||||||
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_ty.fn_sig(fx.tcx), extra_args)
|
RevealAllLayoutCx(fx.tcx).fn_abi_of_fn_ptr(fn_sig, extra_args)
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_cold = if fn_sig.abi == Abi::RustCold {
|
let is_cold = if fn_sig.abi() == Abi::RustCold {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
instance
|
instance
|
||||||
|
@ -417,7 +416,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpack arguments tuple for closures
|
// Unpack arguments tuple for closures
|
||||||
let mut args = if fn_sig.abi == Abi::RustCall {
|
let mut args = if fn_sig.abi() == Abi::RustCall {
|
||||||
assert_eq!(args.len(), 2, "rust-call abi requires two arguments");
|
assert_eq!(args.len(), 2, "rust-call abi requires two arguments");
|
||||||
let self_arg = codegen_call_argument_operand(fx, &args[0]);
|
let self_arg = codegen_call_argument_operand(fx, &args[0]);
|
||||||
let pack_arg = codegen_call_argument_operand(fx, &args[1]);
|
let pack_arg = codegen_call_argument_operand(fx, &args[1]);
|
||||||
|
@ -485,7 +484,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
fx.add_comment(nop_inst, "indirect call");
|
fx.add_comment(nop_inst, "indirect call");
|
||||||
}
|
}
|
||||||
|
|
||||||
let func = codegen_operand(fx, func).load_scalar(fx);
|
let func = func.load_scalar(fx);
|
||||||
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
|
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
|
||||||
let sig = fx.bcx.import_signature(sig);
|
let sig = fx.bcx.import_signature(sig);
|
||||||
|
|
||||||
|
@ -516,11 +515,11 @@ pub(crate) fn codegen_terminator_call<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME find a cleaner way to support varargs
|
// FIXME find a cleaner way to support varargs
|
||||||
if fn_sig.c_variadic {
|
if fn_sig.c_variadic() {
|
||||||
if !matches!(fn_sig.abi, Abi::C { .. }) {
|
if !matches!(fn_sig.abi(), Abi::C { .. }) {
|
||||||
fx.tcx.sess.span_fatal(
|
fx.tcx.sess.span_fatal(
|
||||||
source_info.span,
|
source_info.span,
|
||||||
&format!("Variadic call for non-C abi {:?}", fn_sig.abi),
|
&format!("Variadic call for non-C abi {:?}", fn_sig.abi()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
let sig_ref = fx.bcx.func.dfg.call_signature(call_inst).unwrap();
|
||||||
|
|
|
@ -66,7 +66,7 @@ fn codegen_inner(
|
||||||
};
|
};
|
||||||
|
|
||||||
let sig = Signature {
|
let sig = Signature {
|
||||||
call_conv: CallConv::triple_default(module.isa().triple()),
|
call_conv: module.target_config().default_call_conv,
|
||||||
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
|
params: arg_tys.iter().cloned().map(AbiParam::new).collect(),
|
||||||
returns: output.into_iter().map(AbiParam::new).collect(),
|
returns: output.into_iter().map(AbiParam::new).collect(),
|
||||||
};
|
};
|
||||||
|
@ -104,7 +104,7 @@ fn codegen_inner(
|
||||||
}
|
}
|
||||||
|
|
||||||
let sig = Signature {
|
let sig = Signature {
|
||||||
call_conv: CallConv::triple_default(module.isa().triple()),
|
call_conv: module.target_config().default_call_conv,
|
||||||
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
|
params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)],
|
||||||
returns: vec![],
|
returns: vec![],
|
||||||
};
|
};
|
||||||
|
|
12
src/base.rs
12
src/base.rs
|
@ -59,7 +59,7 @@ pub(crate) fn codegen_fn<'tcx>(
|
||||||
|
|
||||||
// Declare function
|
// Declare function
|
||||||
let symbol_name = tcx.symbol_name(instance).name.to_string();
|
let symbol_name = tcx.symbol_name(instance).name.to_string();
|
||||||
let sig = get_function_sig(tcx, module.isa().triple(), instance);
|
let sig = get_function_sig(tcx, module.target_config().default_call_conv, instance);
|
||||||
let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap();
|
let func_id = module.declare_function(&symbol_name, Linkage::Local, &sig).unwrap();
|
||||||
|
|
||||||
// Make the FunctionBuilder
|
// Make the FunctionBuilder
|
||||||
|
@ -390,11 +390,9 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
||||||
_ => unreachable!("{:?}", targets),
|
_ => unreachable!("{:?}", targets),
|
||||||
};
|
};
|
||||||
|
|
||||||
let discr = crate::optimize::peephole::maybe_unwrap_bint(&mut fx.bcx, discr);
|
|
||||||
let (discr, is_inverted) =
|
let (discr, is_inverted) =
|
||||||
crate::optimize::peephole::maybe_unwrap_bool_not(&mut fx.bcx, discr);
|
crate::optimize::peephole::maybe_unwrap_bool_not(&mut fx.bcx, discr);
|
||||||
let test_zero = if is_inverted { !test_zero } else { test_zero };
|
let test_zero = if is_inverted { !test_zero } else { test_zero };
|
||||||
let discr = crate::optimize::peephole::maybe_unwrap_bint(&mut fx.bcx, discr);
|
|
||||||
if let Some(taken) = crate::optimize::peephole::maybe_known_branch_taken(
|
if let Some(taken) = crate::optimize::peephole::maybe_known_branch_taken(
|
||||||
&fx.bcx, discr, test_zero,
|
&fx.bcx, discr, test_zero,
|
||||||
) {
|
) {
|
||||||
|
@ -571,7 +569,7 @@ fn codegen_stmt<'tcx>(
|
||||||
UnOp::Not => match layout.ty.kind() {
|
UnOp::Not => match layout.ty.kind() {
|
||||||
ty::Bool => {
|
ty::Bool => {
|
||||||
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
|
let res = fx.bcx.ins().icmp_imm(IntCC::Equal, val, 0);
|
||||||
CValue::by_val(fx.bcx.ins().bint(types::I8, res), layout)
|
CValue::by_val(res, layout)
|
||||||
}
|
}
|
||||||
ty::Uint(_) | ty::Int(_) => {
|
ty::Uint(_) | ty::Int(_) => {
|
||||||
CValue::by_val(fx.bcx.ins().bnot(val), layout)
|
CValue::by_val(fx.bcx.ins().bnot(val), layout)
|
||||||
|
@ -579,12 +577,6 @@ fn codegen_stmt<'tcx>(
|
||||||
_ => unreachable!("un op Not for {:?}", layout.ty),
|
_ => unreachable!("un op Not for {:?}", layout.ty),
|
||||||
},
|
},
|
||||||
UnOp::Neg => match layout.ty.kind() {
|
UnOp::Neg => match layout.ty.kind() {
|
||||||
ty::Int(IntTy::I128) => {
|
|
||||||
// FIXME remove this case once ineg.i128 works
|
|
||||||
let zero =
|
|
||||||
CValue::const_val(fx, layout, ty::ScalarInt::null(layout.size));
|
|
||||||
crate::num::codegen_int_binop(fx, BinOp::Sub, zero, operand)
|
|
||||||
}
|
|
||||||
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
|
ty::Int(_) => CValue::by_val(fx.bcx.ins().ineg(val), layout),
|
||||||
ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
|
ty::Float(_) => CValue::by_val(fx.bcx.ins().fneg(val), layout),
|
||||||
_ => unreachable!("un op Neg for {:?}", layout.ty),
|
_ => unreachable!("un op Neg for {:?}", layout.ty),
|
||||||
|
|
|
@ -149,7 +149,7 @@ pub(crate) fn clif_int_or_float_cast(
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_not_nan = fx.bcx.ins().fcmp(FloatCC::Equal, from, from);
|
let is_not_nan = fx.bcx.ins().fcmp(FloatCC::Equal, from, from);
|
||||||
let zero = fx.bcx.ins().iconst(to_ty, 0);
|
let zero = type_zero_value(&mut fx.bcx, to_ty);
|
||||||
fx.bcx.ins().select(is_not_nan, val, zero)
|
fx.bcx.ins().select(is_not_nan, val, zero)
|
||||||
} else if from_ty.is_float() && to_ty.is_float() {
|
} else if from_ty.is_float() && to_ty.is_float() {
|
||||||
// float -> float
|
// float -> float
|
||||||
|
|
|
@ -162,11 +162,20 @@ pub(crate) fn codegen_icmp_imm(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let rhs = i64::try_from(rhs).expect("codegen_icmp_imm rhs out of range for <128bit int");
|
let rhs = rhs as i64; // Truncates on purpose in case rhs is actually an unsigned value
|
||||||
fx.bcx.ins().icmp_imm(intcc, lhs, rhs)
|
fx.bcx.ins().icmp_imm(intcc, lhs, rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn type_zero_value(bcx: &mut FunctionBuilder<'_>, ty: Type) -> Value {
|
||||||
|
if ty == types::I128 {
|
||||||
|
let zero = bcx.ins().iconst(types::I64, 0);
|
||||||
|
bcx.ins().iconcat(zero, zero)
|
||||||
|
} else {
|
||||||
|
bcx.ins().iconst(ty, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn type_min_max_value(
|
pub(crate) fn type_min_max_value(
|
||||||
bcx: &mut FunctionBuilder<'_>,
|
bcx: &mut FunctionBuilder<'_>,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
|
|
|
@ -28,9 +28,7 @@ impl ConstantCx {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) {
|
pub(crate) fn finalize(mut self, tcx: TyCtxt<'_>, module: &mut dyn Module) {
|
||||||
//println!("todo {:?}", self.todo);
|
|
||||||
define_all_allocs(tcx, module, &mut self);
|
define_all_allocs(tcx, module, &mut self);
|
||||||
//println!("done {:?}", self.done);
|
|
||||||
self.done.clear();
|
self.done.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,16 +266,7 @@ fn data_id_for_static(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
definition: bool,
|
definition: bool,
|
||||||
) -> DataId {
|
) -> DataId {
|
||||||
let rlinkage = tcx.codegen_fn_attrs(def_id).linkage;
|
let attrs = tcx.codegen_fn_attrs(def_id);
|
||||||
let linkage = if definition {
|
|
||||||
crate::linkage::get_static_linkage(tcx, def_id)
|
|
||||||
} else if rlinkage == Some(rustc_middle::mir::mono::Linkage::ExternalWeak)
|
|
||||||
|| rlinkage == Some(rustc_middle::mir::mono::Linkage::WeakAny)
|
|
||||||
{
|
|
||||||
Linkage::Preemptible
|
|
||||||
} else {
|
|
||||||
Linkage::Import
|
|
||||||
};
|
|
||||||
|
|
||||||
let instance = Instance::mono(tcx, def_id).polymorphize(tcx);
|
let instance = Instance::mono(tcx, def_id).polymorphize(tcx);
|
||||||
let symbol_name = tcx.symbol_name(instance).name;
|
let symbol_name = tcx.symbol_name(instance).name;
|
||||||
|
@ -289,22 +278,30 @@ fn data_id_for_static(
|
||||||
};
|
};
|
||||||
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);
|
if let Some(import_linkage) = attrs.import_linkage {
|
||||||
|
assert!(!definition);
|
||||||
|
|
||||||
let data_id = match module.declare_data(
|
let linkage = if import_linkage == rustc_middle::mir::mono::Linkage::ExternalWeak
|
||||||
&*symbol_name,
|
|| import_linkage == rustc_middle::mir::mono::Linkage::WeakAny
|
||||||
linkage,
|
{
|
||||||
is_mutable,
|
Linkage::Preemptible
|
||||||
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
} else {
|
||||||
) {
|
Linkage::Import
|
||||||
Ok(data_id) => data_id,
|
};
|
||||||
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
|
||||||
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
|
let data_id = match module.declare_data(
|
||||||
)),
|
&*symbol_name,
|
||||||
Err(err) => Err::<_, _>(err).unwrap(),
|
linkage,
|
||||||
};
|
is_mutable,
|
||||||
|
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||||
|
) {
|
||||||
|
Ok(data_id) => data_id,
|
||||||
|
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||||
|
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
|
||||||
|
)),
|
||||||
|
Err(err) => Err::<_, _>(err).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
if rlinkage.is_some() {
|
|
||||||
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
// Comment copied from https://github.com/rust-lang/rust/blob/45060c2a66dfd667f88bd8b94261b28a58d85bd5/src/librustc_codegen_llvm/consts.rs#L141
|
||||||
// Declare an internal global `extern_with_linkage_foo` which
|
// Declare an internal global `extern_with_linkage_foo` which
|
||||||
// is initialized with the address of `foo`. If `foo` is
|
// is initialized with the address of `foo`. If `foo` is
|
||||||
|
@ -326,10 +323,34 @@ fn data_id_for_static(
|
||||||
Err(ModuleError::DuplicateDefinition(_)) => {}
|
Err(ModuleError::DuplicateDefinition(_)) => {}
|
||||||
res => res.unwrap(),
|
res => res.unwrap(),
|
||||||
}
|
}
|
||||||
ref_data_id
|
|
||||||
} else {
|
return ref_data_id;
|
||||||
data_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let linkage = if definition {
|
||||||
|
crate::linkage::get_static_linkage(tcx, def_id)
|
||||||
|
} else if attrs.linkage == Some(rustc_middle::mir::mono::Linkage::ExternalWeak)
|
||||||
|
|| attrs.linkage == Some(rustc_middle::mir::mono::Linkage::WeakAny)
|
||||||
|
{
|
||||||
|
Linkage::Preemptible
|
||||||
|
} else {
|
||||||
|
Linkage::Import
|
||||||
|
};
|
||||||
|
|
||||||
|
let data_id = match module.declare_data(
|
||||||
|
&*symbol_name,
|
||||||
|
linkage,
|
||||||
|
is_mutable,
|
||||||
|
attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL),
|
||||||
|
) {
|
||||||
|
Ok(data_id) => data_id,
|
||||||
|
Err(ModuleError::IncompatibleDeclaration(_)) => tcx.sess.fatal(&format!(
|
||||||
|
"attempt to declare `{symbol_name}` as static, but it was already declared as function"
|
||||||
|
)),
|
||||||
|
Err(err) => Err::<_, _>(err).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
data_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) {
|
fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut ConstantCx) {
|
||||||
|
@ -348,8 +369,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||||
(data_id, alloc, None)
|
(data_id, alloc, None)
|
||||||
}
|
}
|
||||||
TodoItem::Static(def_id) => {
|
TodoItem::Static(def_id) => {
|
||||||
//println!("static {:?}", def_id);
|
|
||||||
|
|
||||||
let section_name = tcx.codegen_fn_attrs(def_id).link_section;
|
let section_name = tcx.codegen_fn_attrs(def_id).link_section;
|
||||||
|
|
||||||
let alloc = tcx.eval_static_initializer(def_id).unwrap();
|
let alloc = tcx.eval_static_initializer(def_id).unwrap();
|
||||||
|
@ -359,7 +378,6 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//("data_id {}", data_id);
|
|
||||||
if cx.done.contains(&data_id) {
|
if cx.done.contains(&data_id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,9 @@ impl UnwindContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
|
pub(crate) fn add_function(&mut self, func_id: FuncId, context: &Context, isa: &dyn TargetIsa) {
|
||||||
let unwind_info = if let Some(unwind_info) = context.create_unwind_info(isa).unwrap() {
|
let unwind_info = if let Some(unwind_info) =
|
||||||
|
context.compiled_code().unwrap().create_unwind_info(isa).unwrap()
|
||||||
|
{
|
||||||
unwind_info
|
unwind_info
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! Handling of enum discriminants
|
//! Handling of enum discriminants
|
||||||
//!
|
//!
|
||||||
//! Adapted from <https://github.com/rust-lang/rust/blob/d760df5aea483aae041c9a241e7acacf48f75035/src/librustc_codegen_ssa/mir/place.rs>
|
//! Adapted from <https://github.com/rust-lang/rust/blob/31c0645b9d2539f47eecb096142474b29dc542f7/compiler/rustc_codegen_ssa/src/mir/place.rs>
|
||||||
|
//! (<https://github.com/rust-lang/rust/pull/104535>)
|
||||||
|
|
||||||
use rustc_target::abi::{Int, TagEncoding, Variants};
|
use rustc_target::abi::{Int, TagEncoding, Variants};
|
||||||
|
|
||||||
|
@ -47,13 +48,19 @@ pub(crate) fn codegen_set_discriminant<'tcx>(
|
||||||
} => {
|
} => {
|
||||||
if variant_index != untagged_variant {
|
if variant_index != untagged_variant {
|
||||||
let niche = place.place_field(fx, mir::Field::new(tag_field));
|
let niche = place.place_field(fx, mir::Field::new(tag_field));
|
||||||
|
let niche_type = fx.clif_type(niche.layout().ty).unwrap();
|
||||||
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
|
let niche_value = variant_index.as_u32() - niche_variants.start().as_u32();
|
||||||
let niche_value = ty::ScalarInt::try_from_uint(
|
let niche_value = (niche_value as u128).wrapping_add(niche_start);
|
||||||
u128::from(niche_value).wrapping_add(niche_start),
|
let niche_value = match niche_type {
|
||||||
niche.layout().size,
|
types::I128 => {
|
||||||
)
|
let lsb = fx.bcx.ins().iconst(types::I64, niche_value as u64 as i64);
|
||||||
.unwrap();
|
let msb =
|
||||||
let niche_llval = CValue::const_val(fx, niche.layout(), niche_value);
|
fx.bcx.ins().iconst(types::I64, (niche_value >> 64) as u64 as i64);
|
||||||
|
fx.bcx.ins().iconcat(lsb, msb)
|
||||||
|
}
|
||||||
|
ty => fx.bcx.ins().iconst(ty, niche_value as i64),
|
||||||
|
};
|
||||||
|
let niche_llval = CValue::by_val(niche_value, niche.layout());
|
||||||
niche.write_cvalue(fx, niche_llval);
|
niche.write_cvalue(fx, niche_llval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,6 +103,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cast_to_size = dest_layout.layout.size();
|
||||||
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
|
let cast_to = fx.clif_type(dest_layout.ty).unwrap();
|
||||||
|
|
||||||
// Read the tag/niche-encoded discriminant from memory.
|
// Read the tag/niche-encoded discriminant from memory.
|
||||||
|
@ -114,21 +122,128 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||||
dest.write_cvalue(fx, res);
|
dest.write_cvalue(fx, res);
|
||||||
}
|
}
|
||||||
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
|
TagEncoding::Niche { untagged_variant, ref niche_variants, niche_start } => {
|
||||||
// Rebase from niche values to discriminants, and check
|
let tag_size = tag_scalar.size(fx);
|
||||||
// whether the result is in range for the niche variants.
|
let max_unsigned = tag_size.unsigned_int_max();
|
||||||
|
let max_signed = tag_size.signed_int_max() as u128;
|
||||||
|
let min_signed = max_signed + 1;
|
||||||
|
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
|
||||||
|
let niche_end = niche_start.wrapping_add(relative_max as u128) & max_unsigned;
|
||||||
|
let range = tag_scalar.valid_range(fx);
|
||||||
|
|
||||||
// We first compute the "relative discriminant" (wrt `niche_variants`),
|
let sle = |lhs: u128, rhs: u128| -> bool {
|
||||||
// that is, if `n = niche_variants.end() - niche_variants.start()`,
|
// Signed and unsigned comparisons give the same results,
|
||||||
// we remap `niche_start..=niche_start + n` (which may wrap around)
|
// except that in signed comparisons an integer with the
|
||||||
// to (non-wrap-around) `0..=n`, to be able to check whether the
|
// sign bit set is less than one with the sign bit clear.
|
||||||
// discriminant corresponds to a niche variant with one comparison.
|
// Toggle the sign bit to do a signed comparison.
|
||||||
// We also can't go directly to the (variant index) discriminant
|
(lhs ^ min_signed) <= (rhs ^ min_signed)
|
||||||
// and check that it is in the range `niche_variants`, because
|
};
|
||||||
// that might not fit in the same type, on top of needing an extra
|
|
||||||
// comparison (see also the comment on `let niche_discr`).
|
// We have a subrange `niche_start..=niche_end` inside `range`.
|
||||||
let relative_discr = if niche_start == 0 {
|
// If the value of the tag is inside this subrange, it's a
|
||||||
tag
|
// "niche value", an increment of the discriminant. Otherwise it
|
||||||
|
// indicates the untagged variant.
|
||||||
|
// A general algorithm to extract the discriminant from the tag
|
||||||
|
// is:
|
||||||
|
// relative_tag = tag - niche_start
|
||||||
|
// is_niche = relative_tag <= (ule) relative_max
|
||||||
|
// discr = if is_niche {
|
||||||
|
// cast(relative_tag) + niche_variants.start()
|
||||||
|
// } else {
|
||||||
|
// untagged_variant
|
||||||
|
// }
|
||||||
|
// However, we will likely be able to emit simpler code.
|
||||||
|
|
||||||
|
// Find the least and greatest values in `range`, considered
|
||||||
|
// both as signed and unsigned.
|
||||||
|
let (low_unsigned, high_unsigned) =
|
||||||
|
if range.start <= range.end { (range.start, range.end) } else { (0, max_unsigned) };
|
||||||
|
let (low_signed, high_signed) = if sle(range.start, range.end) {
|
||||||
|
(range.start, range.end)
|
||||||
} else {
|
} else {
|
||||||
|
(min_signed, max_signed)
|
||||||
|
};
|
||||||
|
|
||||||
|
let niches_ule = niche_start <= niche_end;
|
||||||
|
let niches_sle = sle(niche_start, niche_end);
|
||||||
|
let cast_smaller = cast_to_size <= tag_size;
|
||||||
|
|
||||||
|
// In the algorithm above, we can change
|
||||||
|
// cast(relative_tag) + niche_variants.start()
|
||||||
|
// into
|
||||||
|
// cast(tag + (niche_variants.start() - niche_start))
|
||||||
|
// if either the casted type is no larger than the original
|
||||||
|
// type, or if the niche values are contiguous (in either the
|
||||||
|
// signed or unsigned sense).
|
||||||
|
let can_incr = cast_smaller || niches_ule || niches_sle;
|
||||||
|
|
||||||
|
let data_for_boundary_niche = || -> Option<(IntCC, u128)> {
|
||||||
|
if !can_incr {
|
||||||
|
None
|
||||||
|
} else if niche_start == low_unsigned {
|
||||||
|
Some((IntCC::UnsignedLessThanOrEqual, niche_end))
|
||||||
|
} else if niche_end == high_unsigned {
|
||||||
|
Some((IntCC::UnsignedGreaterThanOrEqual, niche_start))
|
||||||
|
} else if niche_start == low_signed {
|
||||||
|
Some((IntCC::SignedLessThanOrEqual, niche_end))
|
||||||
|
} else if niche_end == high_signed {
|
||||||
|
Some((IntCC::SignedGreaterThanOrEqual, niche_start))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let (is_niche, tagged_discr, delta) = if relative_max == 0 {
|
||||||
|
// Best case scenario: only one tagged variant. This will
|
||||||
|
// likely become just a comparison and a jump.
|
||||||
|
// The algorithm is:
|
||||||
|
// is_niche = tag == niche_start
|
||||||
|
// discr = if is_niche {
|
||||||
|
// niche_start
|
||||||
|
// } else {
|
||||||
|
// untagged_variant
|
||||||
|
// }
|
||||||
|
let is_niche = codegen_icmp_imm(fx, IntCC::Equal, tag, niche_start as i128);
|
||||||
|
let tagged_discr =
|
||||||
|
fx.bcx.ins().iconst(cast_to, niche_variants.start().as_u32() as i64);
|
||||||
|
(is_niche, tagged_discr, 0)
|
||||||
|
} else if let Some((predicate, constant)) = data_for_boundary_niche() {
|
||||||
|
// The niche values are either the lowest or the highest in
|
||||||
|
// `range`. We can avoid the first subtraction in the
|
||||||
|
// algorithm.
|
||||||
|
// The algorithm is now this:
|
||||||
|
// is_niche = tag <= niche_end
|
||||||
|
// discr = if is_niche {
|
||||||
|
// cast(tag + (niche_variants.start() - niche_start))
|
||||||
|
// } else {
|
||||||
|
// untagged_variant
|
||||||
|
// }
|
||||||
|
// (the first line may instead be tag >= niche_start,
|
||||||
|
// and may be a signed or unsigned comparison)
|
||||||
|
// The arithmetic must be done before the cast, so we can
|
||||||
|
// have the correct wrapping behavior. See issue #104519 for
|
||||||
|
// the consequences of getting this wrong.
|
||||||
|
let is_niche = codegen_icmp_imm(fx, predicate, tag, constant as i128);
|
||||||
|
let delta = (niche_variants.start().as_u32() as u128).wrapping_sub(niche_start);
|
||||||
|
let incr_tag = if delta == 0 {
|
||||||
|
tag
|
||||||
|
} else {
|
||||||
|
let delta = match fx.bcx.func.dfg.value_type(tag) {
|
||||||
|
types::I128 => {
|
||||||
|
let lsb = fx.bcx.ins().iconst(types::I64, delta as u64 as i64);
|
||||||
|
let msb = fx.bcx.ins().iconst(types::I64, (delta >> 64) as u64 as i64);
|
||||||
|
fx.bcx.ins().iconcat(lsb, msb)
|
||||||
|
}
|
||||||
|
ty => fx.bcx.ins().iconst(ty, delta as i64),
|
||||||
|
};
|
||||||
|
fx.bcx.ins().iadd(tag, delta)
|
||||||
|
};
|
||||||
|
|
||||||
|
let cast_tag = clif_intcast(fx, incr_tag, cast_to, !niches_ule);
|
||||||
|
|
||||||
|
(is_niche, cast_tag, 0)
|
||||||
|
} else {
|
||||||
|
// The special cases don't apply, so we'll have to go with
|
||||||
|
// the general algorithm.
|
||||||
let niche_start = match fx.bcx.func.dfg.value_type(tag) {
|
let niche_start = match fx.bcx.func.dfg.value_type(tag) {
|
||||||
types::I128 => {
|
types::I128 => {
|
||||||
let lsb = fx.bcx.ins().iconst(types::I64, niche_start as u64 as i64);
|
let lsb = fx.bcx.ins().iconst(types::I64, niche_start as u64 as i64);
|
||||||
|
@ -138,40 +253,40 @@ pub(crate) fn codegen_get_discriminant<'tcx>(
|
||||||
}
|
}
|
||||||
ty => fx.bcx.ins().iconst(ty, niche_start as i64),
|
ty => fx.bcx.ins().iconst(ty, niche_start as i64),
|
||||||
};
|
};
|
||||||
fx.bcx.ins().isub(tag, niche_start)
|
let relative_discr = fx.bcx.ins().isub(tag, niche_start);
|
||||||
};
|
let cast_tag = clif_intcast(fx, relative_discr, cast_to, false);
|
||||||
let relative_max = niche_variants.end().as_u32() - niche_variants.start().as_u32();
|
let is_niche = crate::common::codegen_icmp_imm(
|
||||||
let is_niche = {
|
|
||||||
codegen_icmp_imm(
|
|
||||||
fx,
|
fx,
|
||||||
IntCC::UnsignedLessThanOrEqual,
|
IntCC::UnsignedLessThanOrEqual,
|
||||||
relative_discr,
|
relative_discr,
|
||||||
i128::from(relative_max),
|
i128::from(relative_max),
|
||||||
)
|
);
|
||||||
|
(is_niche, cast_tag, niche_variants.start().as_u32() as u128)
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE(eddyb) this addition needs to be performed on the final
|
let tagged_discr = if delta == 0 {
|
||||||
// type, in case the niche itself can't represent all variant
|
tagged_discr
|
||||||
// indices (e.g. `u8` niche with more than `256` variants,
|
} else {
|
||||||
// but enough uninhabited variants so that the remaining variants
|
let delta = match cast_to {
|
||||||
// fit in the niche).
|
types::I128 => {
|
||||||
// In other words, `niche_variants.end - niche_variants.start`
|
let lsb = fx.bcx.ins().iconst(types::I64, delta as u64 as i64);
|
||||||
// is representable in the niche, but `niche_variants.end`
|
let msb = fx.bcx.ins().iconst(types::I64, (delta >> 64) as u64 as i64);
|
||||||
// might not be, in extreme cases.
|
fx.bcx.ins().iconcat(lsb, msb)
|
||||||
let niche_discr = {
|
}
|
||||||
let relative_discr = if relative_max == 0 {
|
ty => fx.bcx.ins().iconst(ty, delta as i64),
|
||||||
// HACK(eddyb) since we have only one niche, we know which
|
|
||||||
// one it is, and we can avoid having a dynamic value here.
|
|
||||||
fx.bcx.ins().iconst(cast_to, 0)
|
|
||||||
} 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(tagged_discr, delta)
|
||||||
};
|
};
|
||||||
|
|
||||||
let untagged_variant =
|
let untagged_variant = if cast_to == types::I128 {
|
||||||
fx.bcx.ins().iconst(cast_to, i64::from(untagged_variant.as_u32()));
|
let zero = fx.bcx.ins().iconst(types::I64, 0);
|
||||||
let discr = fx.bcx.ins().select(is_niche, niche_discr, untagged_variant);
|
let untagged_variant =
|
||||||
|
fx.bcx.ins().iconst(types::I64, i64::from(untagged_variant.as_u32()));
|
||||||
|
fx.bcx.ins().iconcat(untagged_variant, zero)
|
||||||
|
} else {
|
||||||
|
fx.bcx.ins().iconst(cast_to, i64::from(untagged_variant.as_u32()))
|
||||||
|
};
|
||||||
|
let discr = fx.bcx.ins().select(is_niche, tagged_discr, untagged_variant);
|
||||||
let res = CValue::by_val(discr, dest_layout);
|
let res = CValue::by_val(discr, dest_layout);
|
||||||
dest.write_cvalue(fx, res);
|
dest.write_cvalue(fx, res);
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ pub(crate) fn run_jit(tcx: TyCtxt<'_>, backend_config: BackendConfig) -> ! {
|
||||||
|
|
||||||
tcx.sess.abort_if_errors();
|
tcx.sess.abort_if_errors();
|
||||||
|
|
||||||
jit_module.finalize_definitions();
|
jit_module.finalize_definitions().unwrap();
|
||||||
unsafe { cx.unwind_context.register_jit(&jit_module) };
|
unsafe { cx.unwind_context.register_jit(&jit_module) };
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
|
@ -245,7 +245,11 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
|
||||||
let backend_config = lazy_jit_state.backend_config.clone();
|
let backend_config = lazy_jit_state.backend_config.clone();
|
||||||
|
|
||||||
let name = tcx.symbol_name(instance).name;
|
let name = tcx.symbol_name(instance).name;
|
||||||
let sig = crate::abi::get_function_sig(tcx, jit_module.isa().triple(), instance);
|
let sig = crate::abi::get_function_sig(
|
||||||
|
tcx,
|
||||||
|
jit_module.target_config().default_call_conv,
|
||||||
|
instance,
|
||||||
|
);
|
||||||
let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap();
|
let func_id = jit_module.declare_function(name, Linkage::Export, &sig).unwrap();
|
||||||
|
|
||||||
let current_ptr = jit_module.read_got_entry(func_id);
|
let current_ptr = jit_module.read_got_entry(func_id);
|
||||||
|
@ -278,7 +282,7 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(cx.global_asm.is_empty());
|
assert!(cx.global_asm.is_empty());
|
||||||
jit_module.finalize_definitions();
|
jit_module.finalize_definitions().unwrap();
|
||||||
unsafe { cx.unwind_context.register_jit(&jit_module) };
|
unsafe { cx.unwind_context.register_jit(&jit_module) };
|
||||||
jit_module.get_finalized_function(func_id)
|
jit_module.get_finalized_function(func_id)
|
||||||
})
|
})
|
||||||
|
@ -344,7 +348,7 @@ fn codegen_shim<'tcx>(
|
||||||
let pointer_type = module.target_config().pointer_type();
|
let pointer_type = module.target_config().pointer_type();
|
||||||
|
|
||||||
let name = tcx.symbol_name(inst).name;
|
let name = tcx.symbol_name(inst).name;
|
||||||
let sig = crate::abi::get_function_sig(tcx, module.isa().triple(), inst);
|
let sig = crate::abi::get_function_sig(tcx, module.target_config().default_call_conv, inst);
|
||||||
let func_id = module.declare_function(name, Linkage::Export, &sig).unwrap();
|
let func_id = module.declare_function(name, Linkage::Export, &sig).unwrap();
|
||||||
|
|
||||||
let instance_ptr = Box::into_raw(Box::new(inst));
|
let instance_ptr = Box::into_raw(Box::new(inst));
|
||||||
|
|
|
@ -24,7 +24,8 @@ fn predefine_mono_items<'tcx>(
|
||||||
MonoItem::Fn(instance) => {
|
MonoItem::Fn(instance) => {
|
||||||
let name = tcx.symbol_name(instance).name;
|
let name = tcx.symbol_name(instance).name;
|
||||||
let _inst_guard = crate::PrintOnPanic(|| format!("{:?} {}", instance, name));
|
let _inst_guard = crate::PrintOnPanic(|| format!("{:?} {}", instance, name));
|
||||||
let sig = get_function_sig(tcx, module.isa().triple(), instance);
|
let sig =
|
||||||
|
get_function_sig(tcx, module.target_config().default_call_conv, instance);
|
||||||
let linkage = crate::linkage::get_clif_linkage(
|
let linkage = crate::linkage::get_clif_linkage(
|
||||||
mono_item,
|
mono_item,
|
||||||
linkage,
|
linkage,
|
||||||
|
|
|
@ -8,135 +8,37 @@ use rustc_middle::ty::subst::SubstsRef;
|
||||||
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
intrinsic: &str,
|
intrinsic: &str,
|
||||||
_substs: SubstsRef<'tcx>,
|
substs: SubstsRef<'tcx>,
|
||||||
args: &[mir::Operand<'tcx>],
|
args: &[mir::Operand<'tcx>],
|
||||||
ret: CPlace<'tcx>,
|
ret: CPlace<'tcx>,
|
||||||
target: Option<BasicBlock>,
|
target: Option<BasicBlock>,
|
||||||
) {
|
) {
|
||||||
match intrinsic {
|
if intrinsic.starts_with("llvm.aarch64") {
|
||||||
"llvm.x86.sse2.pause" | "llvm.aarch64.isb" => {
|
return llvm_aarch64::codegen_aarch64_llvm_intrinsic_call(
|
||||||
// Spin loop hint
|
fx, intrinsic, substs, args, ret, target,
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
if intrinsic.starts_with("llvm.x86") {
|
||||||
|
return llvm_x86::codegen_x86_llvm_intrinsic_call(fx, intrinsic, substs, args, ret, target);
|
||||||
|
}
|
||||||
|
|
||||||
// Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8`
|
match intrinsic {
|
||||||
"llvm.x86.sse2.pmovmskb.128" | "llvm.x86.avx2.pmovmskb" | "llvm.x86.sse2.movmsk.pd" => {
|
_ if intrinsic.starts_with("llvm.ctlz.v") => {
|
||||||
intrinsic_args!(fx, args => (a); intrinsic);
|
intrinsic_args!(fx, args => (a); intrinsic);
|
||||||
|
|
||||||
let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
||||||
let lane_ty = fx.clif_type(lane_ty).unwrap();
|
fx.bcx.ins().clz(lane)
|
||||||
assert!(lane_count <= 32);
|
|
||||||
|
|
||||||
let mut res = fx.bcx.ins().iconst(types::I32, 0);
|
|
||||||
|
|
||||||
for lane in (0..lane_count).rev() {
|
|
||||||
let a_lane = a.value_lane(fx, lane).load_scalar(fx);
|
|
||||||
|
|
||||||
// cast float to int
|
|
||||||
let a_lane = match lane_ty {
|
|
||||||
types::F32 => fx.bcx.ins().bitcast(types::I32, a_lane),
|
|
||||||
types::F64 => fx.bcx.ins().bitcast(types::I64, a_lane),
|
|
||||||
_ => a_lane,
|
|
||||||
};
|
|
||||||
|
|
||||||
// extract sign bit of an int
|
|
||||||
let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_ty.bits() - 1));
|
|
||||||
|
|
||||||
// shift sign bit into result
|
|
||||||
let a_lane_sign = clif_intcast(fx, a_lane_sign, types::I32, false);
|
|
||||||
res = fx.bcx.ins().ishl_imm(res, 1);
|
|
||||||
res = fx.bcx.ins().bor(res, a_lane_sign);
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.i32));
|
|
||||||
ret.write_cvalue(fx, res);
|
|
||||||
}
|
|
||||||
"llvm.x86.sse2.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
|
|
||||||
let (x, y, kind) = match args {
|
|
||||||
[x, y, kind] => (x, y, kind),
|
|
||||||
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
|
||||||
};
|
|
||||||
let x = codegen_operand(fx, x);
|
|
||||||
let y = codegen_operand(fx, y);
|
|
||||||
let kind = crate::constant::mir_operand_get_const_val(fx, kind)
|
|
||||||
.expect("llvm.x86.sse2.cmp.* kind not const");
|
|
||||||
|
|
||||||
let flt_cc = match kind
|
|
||||||
.try_to_bits(Size::from_bytes(1))
|
|
||||||
.unwrap_or_else(|| panic!("kind not scalar: {:?}", kind))
|
|
||||||
{
|
|
||||||
0 => FloatCC::Equal,
|
|
||||||
1 => FloatCC::LessThan,
|
|
||||||
2 => FloatCC::LessThanOrEqual,
|
|
||||||
7 => FloatCC::Ordered,
|
|
||||||
3 => FloatCC::Unordered,
|
|
||||||
4 => FloatCC::NotEqual,
|
|
||||||
5 => FloatCC::UnorderedOrGreaterThanOrEqual,
|
|
||||||
6 => FloatCC::UnorderedOrGreaterThan,
|
|
||||||
kind => unreachable!("kind {:?}", kind),
|
|
||||||
};
|
|
||||||
|
|
||||||
simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, res_lane_ty, x_lane, y_lane| {
|
|
||||||
let res_lane = match lane_ty.kind() {
|
|
||||||
ty::Float(_) => fx.bcx.ins().fcmp(flt_cc, x_lane, y_lane),
|
|
||||||
_ => unreachable!("{:?}", lane_ty),
|
|
||||||
};
|
|
||||||
bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
"llvm.x86.sse2.psrli.d" => {
|
|
||||||
let (a, imm8) = match args {
|
|
||||||
[a, imm8] => (a, imm8),
|
|
||||||
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
|
||||||
};
|
|
||||||
let a = codegen_operand(fx, a);
|
|
||||||
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_ty, _res_lane_ty, lane| match imm8
|
_ if intrinsic.starts_with("llvm.ctpop.v") => {
|
||||||
.try_to_bits(Size::from_bytes(4))
|
intrinsic_args!(fx, args => (a); intrinsic);
|
||||||
.unwrap_or_else(|| panic!("imm8 not scalar: {:?}", imm8))
|
|
||||||
{
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
||||||
imm8 if imm8 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm8 as u8)),
|
fx.bcx.ins().popcnt(lane)
|
||||||
_ => fx.bcx.ins().iconst(types::I32, 0),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
"llvm.x86.sse2.pslli.d" => {
|
|
||||||
let (a, imm8) = match args {
|
|
||||||
[a, imm8] => (a, imm8),
|
|
||||||
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
|
||||||
};
|
|
||||||
let a = codegen_operand(fx, a);
|
|
||||||
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_ty, _res_lane_ty, 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),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
"llvm.x86.sse2.storeu.dq" => {
|
|
||||||
intrinsic_args!(fx, args => (mem_addr, a); intrinsic);
|
|
||||||
let mem_addr = mem_addr.load_scalar(fx);
|
|
||||||
|
|
||||||
// FIXME correctly handle the unalignment
|
|
||||||
let dest = CPlace::for_ptr(Pointer::new(mem_addr), a.layout());
|
|
||||||
dest.write_cvalue(fx, a);
|
|
||||||
}
|
|
||||||
"llvm.x86.addcarry.64" => {
|
|
||||||
intrinsic_args!(fx, args => (c_in, a, b); intrinsic);
|
|
||||||
let c_in = c_in.load_scalar(fx);
|
|
||||||
|
|
||||||
llvm_add_sub(fx, BinOp::Add, ret, c_in, a, b);
|
|
||||||
}
|
|
||||||
"llvm.x86.subborrow.64" => {
|
|
||||||
intrinsic_args!(fx, args => (b_in, a, b); intrinsic);
|
|
||||||
let b_in = b_in.load_scalar(fx);
|
|
||||||
|
|
||||||
llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b);
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
fx.tcx
|
fx.tcx
|
||||||
.sess
|
.sess
|
||||||
|
@ -150,47 +52,3 @@ pub(crate) fn codegen_llvm_intrinsic_call<'tcx>(
|
||||||
let ret_block = fx.get_block(dest);
|
let ret_block = fx.get_block(dest);
|
||||||
fx.bcx.ins().jump(ret_block, &[]);
|
fx.bcx.ins().jump(ret_block, &[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// llvm.x86.avx2.vperm2i128
|
|
||||||
// llvm.x86.ssse3.pshuf.b.128
|
|
||||||
// llvm.x86.avx2.pshuf.b
|
|
||||||
// llvm.x86.avx2.psrli.w
|
|
||||||
// llvm.x86.sse2.psrli.w
|
|
||||||
|
|
||||||
fn llvm_add_sub<'tcx>(
|
|
||||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
|
||||||
bin_op: BinOp,
|
|
||||||
ret: CPlace<'tcx>,
|
|
||||||
cb_in: Value,
|
|
||||||
a: CValue<'tcx>,
|
|
||||||
b: CValue<'tcx>,
|
|
||||||
) {
|
|
||||||
assert_eq!(
|
|
||||||
a.layout().ty,
|
|
||||||
fx.tcx.types.u64,
|
|
||||||
"llvm.x86.addcarry.64/llvm.x86.subborrow.64 second operand must be u64"
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
b.layout().ty,
|
|
||||||
fx.tcx.types.u64,
|
|
||||||
"llvm.x86.addcarry.64/llvm.x86.subborrow.64 third operand must be u64"
|
|
||||||
);
|
|
||||||
|
|
||||||
// c + carry -> c + first intermediate carry or borrow respectively
|
|
||||||
let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
|
|
||||||
let c = int0.value_field(fx, mir::Field::new(0));
|
|
||||||
let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx);
|
|
||||||
|
|
||||||
// c + carry -> c + second intermediate carry or borrow respectively
|
|
||||||
let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in);
|
|
||||||
let cb_in_as_u64 = CValue::by_val(cb_in_as_u64, fx.layout_of(fx.tcx.types.u64));
|
|
||||||
let int1 = crate::num::codegen_checked_int_binop(fx, bin_op, c, cb_in_as_u64);
|
|
||||||
let (c, cb1) = int1.load_scalar_pair(fx);
|
|
||||||
|
|
||||||
// carry0 | carry1 -> carry or borrow respectively
|
|
||||||
let cb_out = fx.bcx.ins().bor(cb0, cb1);
|
|
||||||
|
|
||||||
let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter()));
|
|
||||||
let val = CValue::by_val_pair(cb_out, c, layout);
|
|
||||||
ret.write_cvalue(fx, val);
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,222 @@
|
||||||
|
//! Emulate AArch64 LLVM intrinsics
|
||||||
|
|
||||||
|
use crate::intrinsics::*;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
|
|
||||||
|
pub(crate) fn codegen_aarch64_llvm_intrinsic_call<'tcx>(
|
||||||
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
|
intrinsic: &str,
|
||||||
|
_substs: SubstsRef<'tcx>,
|
||||||
|
args: &[mir::Operand<'tcx>],
|
||||||
|
ret: CPlace<'tcx>,
|
||||||
|
target: Option<BasicBlock>,
|
||||||
|
) {
|
||||||
|
// llvm.aarch64.neon.sqshl.v*i*
|
||||||
|
|
||||||
|
match intrinsic {
|
||||||
|
"llvm.aarch64.isb" => {
|
||||||
|
fx.bcx.ins().fence();
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.abs.v") => {
|
||||||
|
intrinsic_args!(fx, args => (a); intrinsic);
|
||||||
|
|
||||||
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
||||||
|
fx.bcx.ins().iabs(lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.cls.v") => {
|
||||||
|
intrinsic_args!(fx, args => (a); intrinsic);
|
||||||
|
|
||||||
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
||||||
|
fx.bcx.ins().cls(lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.rbit.v") => {
|
||||||
|
intrinsic_args!(fx, args => (a); intrinsic);
|
||||||
|
|
||||||
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| {
|
||||||
|
fx.bcx.ins().bitrev(lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.sqadd.v") => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
|
||||||
|
crate::num::codegen_saturating_int_binop(fx, BinOp::Add, x_lane, y_lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.sqsub.v") => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane_typed(fx, x, y, ret, &|fx, x_lane, y_lane| {
|
||||||
|
crate::num::codegen_saturating_int_binop(fx, BinOp::Sub, x_lane, y_lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.smax.v") => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane(
|
||||||
|
fx,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
ret,
|
||||||
|
&|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, x_lane, y_lane);
|
||||||
|
fx.bcx.ins().select(gt, x_lane, y_lane)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.umax.v") => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane(
|
||||||
|
fx,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
ret,
|
||||||
|
&|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, x_lane, y_lane);
|
||||||
|
fx.bcx.ins().select(gt, x_lane, y_lane)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.smaxv.i") => {
|
||||||
|
intrinsic_args!(fx, args => (v); intrinsic);
|
||||||
|
|
||||||
|
simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::SignedGreaterThan, a, b);
|
||||||
|
fx.bcx.ins().select(gt, a, b)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.umaxv.i") => {
|
||||||
|
intrinsic_args!(fx, args => (v); intrinsic);
|
||||||
|
|
||||||
|
simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, a, b);
|
||||||
|
fx.bcx.ins().select(gt, a, b)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.smin.v") => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane(
|
||||||
|
fx,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
ret,
|
||||||
|
&|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::SignedLessThan, x_lane, y_lane);
|
||||||
|
fx.bcx.ins().select(gt, x_lane, y_lane)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.umin.v") => {
|
||||||
|
intrinsic_args!(fx, args => (x, y); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane(
|
||||||
|
fx,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
ret,
|
||||||
|
&|fx, _lane_ty, _res_lane_ty, x_lane, y_lane| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, x_lane, y_lane);
|
||||||
|
fx.bcx.ins().select(gt, x_lane, y_lane)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.sminv.i") => {
|
||||||
|
intrinsic_args!(fx, args => (v); intrinsic);
|
||||||
|
|
||||||
|
simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::SignedLessThan, a, b);
|
||||||
|
fx.bcx.ins().select(gt, a, b)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.uminv.i") => {
|
||||||
|
intrinsic_args!(fx, args => (v); intrinsic);
|
||||||
|
|
||||||
|
simd_reduce(fx, v, None, ret, &|fx, _ty, a, b| {
|
||||||
|
let gt = fx.bcx.ins().icmp(IntCC::UnsignedLessThan, a, b);
|
||||||
|
fx.bcx.ins().select(gt, a, b)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.sshl.v")
|
||||||
|
|| intrinsic.starts_with("llvm.aarch64.neon.sqshl.v")
|
||||||
|
// FIXME split this one out once saturating is implemented
|
||||||
|
|| intrinsic.starts_with("llvm.aarch64.neon.sqshlu.v") =>
|
||||||
|
{
|
||||||
|
intrinsic_args!(fx, args => (a, b); intrinsic);
|
||||||
|
|
||||||
|
simd_pair_for_each_lane(fx, a, b, ret, &|fx, _lane_ty, _res_lane_ty, a, b| {
|
||||||
|
// FIXME saturate?
|
||||||
|
fx.bcx.ins().ishl(a, b)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.sqshrn.v") => {
|
||||||
|
let (a, imm32) = match args {
|
||||||
|
[a, imm32] => (a, imm32),
|
||||||
|
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
||||||
|
};
|
||||||
|
let a = codegen_operand(fx, a);
|
||||||
|
let imm32 = crate::constant::mir_operand_get_const_val(fx, imm32)
|
||||||
|
.expect("llvm.aarch64.neon.sqshrn.v* imm32 not const");
|
||||||
|
|
||||||
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm32
|
||||||
|
.try_to_bits(Size::from_bytes(4))
|
||||||
|
.unwrap_or_else(|| panic!("imm32 not scalar: {:?}", imm32))
|
||||||
|
{
|
||||||
|
imm32 if imm32 < 32 => fx.bcx.ins().sshr_imm(lane, i64::from(imm32 as u8)),
|
||||||
|
_ => fx.bcx.ins().iconst(types::I32, 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_ if intrinsic.starts_with("llvm.aarch64.neon.sqshrun.v") => {
|
||||||
|
let (a, imm32) = match args {
|
||||||
|
[a, imm32] => (a, imm32),
|
||||||
|
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
||||||
|
};
|
||||||
|
let a = codegen_operand(fx, a);
|
||||||
|
let imm32 = crate::constant::mir_operand_get_const_val(fx, imm32)
|
||||||
|
.expect("llvm.aarch64.neon.sqshrn.v* imm32 not const");
|
||||||
|
|
||||||
|
simd_for_each_lane(fx, a, ret, &|fx, _lane_ty, _res_lane_ty, lane| match imm32
|
||||||
|
.try_to_bits(Size::from_bytes(4))
|
||||||
|
.unwrap_or_else(|| panic!("imm32 not scalar: {:?}", imm32))
|
||||||
|
{
|
||||||
|
imm32 if imm32 < 32 => fx.bcx.ins().ushr_imm(lane, i64::from(imm32 as u8)),
|
||||||
|
_ => fx.bcx.ins().iconst(types::I32, 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
_ => {
|
||||||
|
fx.tcx.sess.warn(&format!(
|
||||||
|
"unsupported AArch64 llvm intrinsic {}; replacing with trap",
|
||||||
|
intrinsic
|
||||||
|
));
|
||||||
|
crate::trap::trap_unimplemented(fx, intrinsic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let dest = target.expect("all llvm intrinsics used by stdlib should return");
|
||||||
|
let ret_block = fx.get_block(dest);
|
||||||
|
fx.bcx.ins().jump(ret_block, &[]);
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
//! Emulate x86 LLVM intrinsics
|
||||||
|
|
||||||
|
use crate::intrinsics::*;
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
|
|
||||||
|
pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
||||||
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
|
intrinsic: &str,
|
||||||
|
_substs: SubstsRef<'tcx>,
|
||||||
|
args: &[mir::Operand<'tcx>],
|
||||||
|
ret: CPlace<'tcx>,
|
||||||
|
target: Option<BasicBlock>,
|
||||||
|
) {
|
||||||
|
match intrinsic {
|
||||||
|
"llvm.x86.sse2.pause" | "llvm.aarch64.isb" => {
|
||||||
|
// Spin loop hint
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by `_mm_movemask_epi8` and `_mm256_movemask_epi8`
|
||||||
|
"llvm.x86.sse2.pmovmskb.128" | "llvm.x86.avx2.pmovmskb" | "llvm.x86.sse2.movmsk.pd" => {
|
||||||
|
intrinsic_args!(fx, args => (a); intrinsic);
|
||||||
|
|
||||||
|
let (lane_count, lane_ty) = a.layout().ty.simd_size_and_type(fx.tcx);
|
||||||
|
let lane_ty = fx.clif_type(lane_ty).unwrap();
|
||||||
|
assert!(lane_count <= 32);
|
||||||
|
|
||||||
|
let mut res = fx.bcx.ins().iconst(types::I32, 0);
|
||||||
|
|
||||||
|
for lane in (0..lane_count).rev() {
|
||||||
|
let a_lane = a.value_lane(fx, lane).load_scalar(fx);
|
||||||
|
|
||||||
|
// cast float to int
|
||||||
|
let a_lane = match lane_ty {
|
||||||
|
types::F32 => fx.bcx.ins().bitcast(types::I32, a_lane),
|
||||||
|
types::F64 => fx.bcx.ins().bitcast(types::I64, a_lane),
|
||||||
|
_ => a_lane,
|
||||||
|
};
|
||||||
|
|
||||||
|
// extract sign bit of an int
|
||||||
|
let a_lane_sign = fx.bcx.ins().ushr_imm(a_lane, i64::from(lane_ty.bits() - 1));
|
||||||
|
|
||||||
|
// shift sign bit into result
|
||||||
|
let a_lane_sign = clif_intcast(fx, a_lane_sign, types::I32, false);
|
||||||
|
res = fx.bcx.ins().ishl_imm(res, 1);
|
||||||
|
res = fx.bcx.ins().bor(res, a_lane_sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = CValue::by_val(res, fx.layout_of(fx.tcx.types.i32));
|
||||||
|
ret.write_cvalue(fx, res);
|
||||||
|
}
|
||||||
|
"llvm.x86.sse2.cmp.ps" | "llvm.x86.sse2.cmp.pd" => {
|
||||||
|
let (x, y, kind) = match args {
|
||||||
|
[x, y, kind] => (x, y, kind),
|
||||||
|
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
||||||
|
};
|
||||||
|
let x = codegen_operand(fx, x);
|
||||||
|
let y = codegen_operand(fx, y);
|
||||||
|
let kind = crate::constant::mir_operand_get_const_val(fx, kind)
|
||||||
|
.expect("llvm.x86.sse2.cmp.* kind not const");
|
||||||
|
|
||||||
|
let flt_cc = match kind
|
||||||
|
.try_to_bits(Size::from_bytes(1))
|
||||||
|
.unwrap_or_else(|| panic!("kind not scalar: {:?}", kind))
|
||||||
|
{
|
||||||
|
0 => FloatCC::Equal,
|
||||||
|
1 => FloatCC::LessThan,
|
||||||
|
2 => FloatCC::LessThanOrEqual,
|
||||||
|
7 => FloatCC::Ordered,
|
||||||
|
3 => FloatCC::Unordered,
|
||||||
|
4 => FloatCC::NotEqual,
|
||||||
|
5 => FloatCC::UnorderedOrGreaterThanOrEqual,
|
||||||
|
6 => FloatCC::UnorderedOrGreaterThan,
|
||||||
|
kind => unreachable!("kind {:?}", kind),
|
||||||
|
};
|
||||||
|
|
||||||
|
simd_pair_for_each_lane(fx, x, y, ret, &|fx, lane_ty, res_lane_ty, x_lane, y_lane| {
|
||||||
|
let res_lane = match lane_ty.kind() {
|
||||||
|
ty::Float(_) => fx.bcx.ins().fcmp(flt_cc, x_lane, y_lane),
|
||||||
|
_ => unreachable!("{:?}", lane_ty),
|
||||||
|
};
|
||||||
|
bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"llvm.x86.sse2.psrli.d" => {
|
||||||
|
let (a, imm8) = match args {
|
||||||
|
[a, imm8] => (a, imm8),
|
||||||
|
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
||||||
|
};
|
||||||
|
let a = codegen_operand(fx, a);
|
||||||
|
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_ty, _res_lane_ty, 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),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"llvm.x86.sse2.pslli.d" => {
|
||||||
|
let (a, imm8) = match args {
|
||||||
|
[a, imm8] => (a, imm8),
|
||||||
|
_ => bug!("wrong number of args for intrinsic {intrinsic}"),
|
||||||
|
};
|
||||||
|
let a = codegen_operand(fx, a);
|
||||||
|
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_ty, _res_lane_ty, 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),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
"llvm.x86.sse2.storeu.dq" => {
|
||||||
|
intrinsic_args!(fx, args => (mem_addr, a); intrinsic);
|
||||||
|
let mem_addr = mem_addr.load_scalar(fx);
|
||||||
|
|
||||||
|
// FIXME correctly handle the unalignment
|
||||||
|
let dest = CPlace::for_ptr(Pointer::new(mem_addr), a.layout());
|
||||||
|
dest.write_cvalue(fx, a);
|
||||||
|
}
|
||||||
|
"llvm.x86.addcarry.64" => {
|
||||||
|
intrinsic_args!(fx, args => (c_in, a, b); intrinsic);
|
||||||
|
let c_in = c_in.load_scalar(fx);
|
||||||
|
|
||||||
|
llvm_add_sub(fx, BinOp::Add, ret, c_in, a, b);
|
||||||
|
}
|
||||||
|
"llvm.x86.subborrow.64" => {
|
||||||
|
intrinsic_args!(fx, args => (b_in, a, b); intrinsic);
|
||||||
|
let b_in = b_in.load_scalar(fx);
|
||||||
|
|
||||||
|
llvm_add_sub(fx, BinOp::Sub, ret, b_in, a, b);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
fx.tcx.sess.warn(&format!(
|
||||||
|
"unsupported x86 llvm intrinsic {}; replacing with trap",
|
||||||
|
intrinsic
|
||||||
|
));
|
||||||
|
crate::trap::trap_unimplemented(fx, intrinsic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let dest = target.expect("all llvm intrinsics used by stdlib should return");
|
||||||
|
let ret_block = fx.get_block(dest);
|
||||||
|
fx.bcx.ins().jump(ret_block, &[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// llvm.x86.avx2.vperm2i128
|
||||||
|
// llvm.x86.ssse3.pshuf.b.128
|
||||||
|
// llvm.x86.avx2.pshuf.b
|
||||||
|
// llvm.x86.avx2.psrli.w
|
||||||
|
// llvm.x86.sse2.psrli.w
|
||||||
|
|
||||||
|
fn llvm_add_sub<'tcx>(
|
||||||
|
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||||
|
bin_op: BinOp,
|
||||||
|
ret: CPlace<'tcx>,
|
||||||
|
cb_in: Value,
|
||||||
|
a: CValue<'tcx>,
|
||||||
|
b: CValue<'tcx>,
|
||||||
|
) {
|
||||||
|
assert_eq!(
|
||||||
|
a.layout().ty,
|
||||||
|
fx.tcx.types.u64,
|
||||||
|
"llvm.x86.addcarry.64/llvm.x86.subborrow.64 second operand must be u64"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
b.layout().ty,
|
||||||
|
fx.tcx.types.u64,
|
||||||
|
"llvm.x86.addcarry.64/llvm.x86.subborrow.64 third operand must be u64"
|
||||||
|
);
|
||||||
|
|
||||||
|
// c + carry -> c + first intermediate carry or borrow respectively
|
||||||
|
let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
|
||||||
|
let c = int0.value_field(fx, mir::Field::new(0));
|
||||||
|
let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx);
|
||||||
|
|
||||||
|
// c + carry -> c + second intermediate carry or borrow respectively
|
||||||
|
let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in);
|
||||||
|
let cb_in_as_u64 = CValue::by_val(cb_in_as_u64, fx.layout_of(fx.tcx.types.u64));
|
||||||
|
let int1 = crate::num::codegen_checked_int_binop(fx, bin_op, c, cb_in_as_u64);
|
||||||
|
let (c, cb1) = int1.load_scalar_pair(fx);
|
||||||
|
|
||||||
|
// carry0 | carry1 -> carry or borrow respectively
|
||||||
|
let cb_out = fx.bcx.ins().bor(cb0, cb1);
|
||||||
|
|
||||||
|
let layout = fx.layout_of(fx.tcx.mk_tup([fx.tcx.types.u8, fx.tcx.types.u64].iter()));
|
||||||
|
let val = CValue::by_val_pair(cb_out, c, layout);
|
||||||
|
ret.write_cvalue(fx, val);
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ macro_rules! intrinsic_args {
|
||||||
|
|
||||||
mod cpuid;
|
mod cpuid;
|
||||||
mod llvm;
|
mod llvm;
|
||||||
|
mod llvm_aarch64;
|
||||||
|
mod llvm_x86;
|
||||||
mod simd;
|
mod simd;
|
||||||
|
|
||||||
pub(crate) use cpuid::codegen_cpuid_call;
|
pub(crate) use cpuid::codegen_cpuid_call;
|
||||||
|
@ -195,8 +197,7 @@ fn bool_to_zero_or_max_uint<'tcx>(
|
||||||
ty => ty,
|
ty => ty,
|
||||||
};
|
};
|
||||||
|
|
||||||
let val = fx.bcx.ins().bint(int_ty, val);
|
let mut res = fx.bcx.ins().bmask(int_ty, val);
|
||||||
let mut res = fx.bcx.ins().ineg(val);
|
|
||||||
|
|
||||||
if ty.is_float() {
|
if ty.is_float() {
|
||||||
res = fx.bcx.ins().bitcast(ty, res);
|
res = fx.bcx.ins().bitcast(ty, res);
|
||||||
|
@ -632,85 +633,15 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
ret.write_cvalue(fx, res);
|
ret.write_cvalue(fx, res);
|
||||||
}
|
}
|
||||||
sym::bswap => {
|
sym::bswap => {
|
||||||
// FIXME(CraneStation/cranelift#794) add bswap instruction to cranelift
|
|
||||||
fn swap(bcx: &mut FunctionBuilder<'_>, v: Value) -> Value {
|
|
||||||
match bcx.func.dfg.value_type(v) {
|
|
||||||
types::I8 => v,
|
|
||||||
|
|
||||||
// https://code.woboq.org/gcc/include/bits/byteswap.h.html
|
|
||||||
types::I16 => {
|
|
||||||
let tmp1 = bcx.ins().ishl_imm(v, 8);
|
|
||||||
let n1 = bcx.ins().band_imm(tmp1, 0xFF00);
|
|
||||||
|
|
||||||
let tmp2 = bcx.ins().ushr_imm(v, 8);
|
|
||||||
let n2 = bcx.ins().band_imm(tmp2, 0x00FF);
|
|
||||||
|
|
||||||
bcx.ins().bor(n1, n2)
|
|
||||||
}
|
|
||||||
types::I32 => {
|
|
||||||
let tmp1 = bcx.ins().ishl_imm(v, 24);
|
|
||||||
let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000);
|
|
||||||
|
|
||||||
let tmp2 = bcx.ins().ishl_imm(v, 8);
|
|
||||||
let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000);
|
|
||||||
|
|
||||||
let tmp3 = bcx.ins().ushr_imm(v, 8);
|
|
||||||
let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00);
|
|
||||||
|
|
||||||
let tmp4 = bcx.ins().ushr_imm(v, 24);
|
|
||||||
let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF);
|
|
||||||
|
|
||||||
let or_tmp1 = bcx.ins().bor(n1, n2);
|
|
||||||
let or_tmp2 = bcx.ins().bor(n3, n4);
|
|
||||||
bcx.ins().bor(or_tmp1, or_tmp2)
|
|
||||||
}
|
|
||||||
types::I64 => {
|
|
||||||
let tmp1 = bcx.ins().ishl_imm(v, 56);
|
|
||||||
let n1 = bcx.ins().band_imm(tmp1, 0xFF00_0000_0000_0000u64 as i64);
|
|
||||||
|
|
||||||
let tmp2 = bcx.ins().ishl_imm(v, 40);
|
|
||||||
let n2 = bcx.ins().band_imm(tmp2, 0x00FF_0000_0000_0000u64 as i64);
|
|
||||||
|
|
||||||
let tmp3 = bcx.ins().ishl_imm(v, 24);
|
|
||||||
let n3 = bcx.ins().band_imm(tmp3, 0x0000_FF00_0000_0000u64 as i64);
|
|
||||||
|
|
||||||
let tmp4 = bcx.ins().ishl_imm(v, 8);
|
|
||||||
let n4 = bcx.ins().band_imm(tmp4, 0x0000_00FF_0000_0000u64 as i64);
|
|
||||||
|
|
||||||
let tmp5 = bcx.ins().ushr_imm(v, 8);
|
|
||||||
let n5 = bcx.ins().band_imm(tmp5, 0x0000_0000_FF00_0000u64 as i64);
|
|
||||||
|
|
||||||
let tmp6 = bcx.ins().ushr_imm(v, 24);
|
|
||||||
let n6 = bcx.ins().band_imm(tmp6, 0x0000_0000_00FF_0000u64 as i64);
|
|
||||||
|
|
||||||
let tmp7 = bcx.ins().ushr_imm(v, 40);
|
|
||||||
let n7 = bcx.ins().band_imm(tmp7, 0x0000_0000_0000_FF00u64 as i64);
|
|
||||||
|
|
||||||
let tmp8 = bcx.ins().ushr_imm(v, 56);
|
|
||||||
let n8 = bcx.ins().band_imm(tmp8, 0x0000_0000_0000_00FFu64 as i64);
|
|
||||||
|
|
||||||
let or_tmp1 = bcx.ins().bor(n1, n2);
|
|
||||||
let or_tmp2 = bcx.ins().bor(n3, n4);
|
|
||||||
let or_tmp3 = bcx.ins().bor(n5, n6);
|
|
||||||
let or_tmp4 = bcx.ins().bor(n7, n8);
|
|
||||||
|
|
||||||
let or_tmp5 = bcx.ins().bor(or_tmp1, or_tmp2);
|
|
||||||
let or_tmp6 = bcx.ins().bor(or_tmp3, or_tmp4);
|
|
||||||
bcx.ins().bor(or_tmp5, or_tmp6)
|
|
||||||
}
|
|
||||||
types::I128 => {
|
|
||||||
let (lo, hi) = bcx.ins().isplit(v);
|
|
||||||
let lo = swap(bcx, lo);
|
|
||||||
let hi = swap(bcx, hi);
|
|
||||||
bcx.ins().iconcat(hi, lo)
|
|
||||||
}
|
|
||||||
ty => unreachable!("bswap {}", ty),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intrinsic_args!(fx, args => (arg); intrinsic);
|
intrinsic_args!(fx, args => (arg); intrinsic);
|
||||||
let val = arg.load_scalar(fx);
|
let val = arg.load_scalar(fx);
|
||||||
|
|
||||||
let res = CValue::by_val(swap(&mut fx.bcx, val), arg.layout());
|
let res = if fx.bcx.func.dfg.value_type(val) == types::I8 {
|
||||||
|
val
|
||||||
|
} else {
|
||||||
|
fx.bcx.ins().bswap(val)
|
||||||
|
};
|
||||||
|
let res = CValue::by_val(res, arg.layout());
|
||||||
ret.write_cvalue(fx, res);
|
ret.write_cvalue(fx, res);
|
||||||
}
|
}
|
||||||
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
|
sym::assert_inhabited | sym::assert_zero_valid | sym::assert_uninit_valid => {
|
||||||
|
@ -936,8 +867,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
let old = fx.bcx.ins().atomic_cas(MemFlags::trusted(), ptr, test_old, new);
|
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 is_eq = fx.bcx.ins().icmp(IntCC::Equal, old, test_old);
|
||||||
|
|
||||||
let ret_val =
|
let ret_val = CValue::by_val_pair(old, is_eq, ret.layout());
|
||||||
CValue::by_val_pair(old, fx.bcx.ins().bint(types::I8, is_eq), ret.layout());
|
|
||||||
ret.write_cvalue(fx, ret_val)
|
ret.write_cvalue(fx, ret_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1259,8 +1189,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
flags.set_notrap();
|
flags.set_notrap();
|
||||||
let lhs_val = fx.bcx.ins().load(clty, flags, lhs_ref, 0);
|
let lhs_val = fx.bcx.ins().load(clty, flags, lhs_ref, 0);
|
||||||
let rhs_val = fx.bcx.ins().load(clty, flags, rhs_ref, 0);
|
let rhs_val = fx.bcx.ins().load(clty, flags, rhs_ref, 0);
|
||||||
let eq = fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val);
|
fx.bcx.ins().icmp(IntCC::Equal, lhs_val, rhs_val)
|
||||||
fx.bcx.ins().bint(types::I8, eq)
|
|
||||||
} else {
|
} else {
|
||||||
// Just call `memcmp` (like slices do in core) when the
|
// Just call `memcmp` (like slices do in core) when the
|
||||||
// size is too large or it's not a power-of-two.
|
// size is too large or it's not a power-of-two.
|
||||||
|
@ -1270,8 +1199,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
||||||
let returns = vec![AbiParam::new(types::I32)];
|
let returns = vec![AbiParam::new(types::I32)];
|
||||||
let args = &[lhs_ref, rhs_ref, bytes_val];
|
let args = &[lhs_ref, rhs_ref, bytes_val];
|
||||||
let cmp = fx.lib_call("memcmp", params, returns, args)[0];
|
let cmp = fx.lib_call("memcmp", params, returns, args)[0];
|
||||||
let eq = fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0);
|
fx.bcx.ins().icmp_imm(IntCC::Equal, cmp, 0)
|
||||||
fx.bcx.ins().bint(types::I8, eq)
|
|
||||||
};
|
};
|
||||||
ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout()));
|
ret.write_cvalue(fx, CValue::by_val(is_eq_value, ret.layout()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,10 +112,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty = fx.clif_type(res_lane_ty).unwrap();
|
bool_to_zero_or_max_uint(fx, res_lane_ty, res_lane)
|
||||||
|
|
||||||
let res_lane = fx.bcx.ins().bint(ty, res_lane);
|
|
||||||
fx.bcx.ins().ineg(res_lane)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,7 +713,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
|
||||||
|
|
||||||
let res_type =
|
let res_type =
|
||||||
Type::int_with_byte_size(u16::try_from(expected_bytes).unwrap()).unwrap();
|
Type::int_with_byte_size(u16::try_from(expected_bytes).unwrap()).unwrap();
|
||||||
let mut res = fx.bcx.ins().iconst(res_type, 0);
|
let mut res = type_zero_value(&mut fx.bcx, res_type);
|
||||||
|
|
||||||
let lanes = match fx.tcx.sess.target.endian {
|
let lanes = match fx.tcx.sess.target.endian {
|
||||||
Endian::Big => Box::new(0..lane_count) as Box<dyn Iterator<Item = u64>>,
|
Endian::Big => Box::new(0..lane_count) as Box<dyn Iterator<Item = u64>>,
|
||||||
|
|
|
@ -65,7 +65,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||||
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
|
returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)],
|
||||||
call_conv: crate::conv_to_call_conv(
|
call_conv: crate::conv_to_call_conv(
|
||||||
tcx.sess.target.options.entry_abi,
|
tcx.sess.target.options.entry_abi,
|
||||||
CallConv::triple_default(m.isa().triple()),
|
m.target_config().default_call_conv,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||||
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
|
let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx);
|
||||||
|
|
||||||
let main_name = tcx.symbol_name(instance).name;
|
let main_name = tcx.symbol_name(instance).name;
|
||||||
let main_sig = get_function_sig(tcx, m.isa().triple(), instance);
|
let main_sig = get_function_sig(tcx, m.target_config().default_call_conv, 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();
|
let mut ctx = Context::new();
|
||||||
|
@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper(
|
||||||
.polymorphize(tcx);
|
.polymorphize(tcx);
|
||||||
|
|
||||||
let report_name = tcx.symbol_name(report).name;
|
let report_name = tcx.symbol_name(report).name;
|
||||||
let report_sig = get_function_sig(tcx, m.isa().triple(), report);
|
let report_sig = get_function_sig(tcx, m.target_config().default_call_conv, report);
|
||||||
let report_func_id =
|
let report_func_id =
|
||||||
m.declare_function(report_name, Linkage::Import, &report_sig).unwrap();
|
m.declare_function(report_name, Linkage::Import, &report_sig).unwrap();
|
||||||
let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func);
|
let report_func_ref = m.declare_func_in_func(report_func_id, &mut bcx.func);
|
||||||
|
|
|
@ -49,7 +49,6 @@ fn codegen_compare_bin_op<'tcx>(
|
||||||
) -> CValue<'tcx> {
|
) -> CValue<'tcx> {
|
||||||
let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap();
|
let intcc = crate::num::bin_op_to_intcc(bin_op, signed).unwrap();
|
||||||
let val = fx.bcx.ins().icmp(intcc, lhs, rhs);
|
let val = fx.bcx.ins().icmp(intcc, lhs, rhs);
|
||||||
let val = fx.bcx.ins().bint(types::I8, val);
|
|
||||||
CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
|
CValue::by_val(val, fx.layout_of(fx.tcx.types.bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +289,6 @@ pub(crate) fn codegen_checked_int_binop<'tcx>(
|
||||||
_ => 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);
|
|
||||||
|
|
||||||
let out_layout = fx.layout_of(fx.tcx.mk_tup([in_lhs.layout().ty, fx.tcx.types.bool].iter()));
|
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)
|
CValue::by_val_pair(res, has_overflow, out_layout)
|
||||||
}
|
}
|
||||||
|
@ -368,7 +365,6 @@ pub(crate) fn codegen_float_binop<'tcx>(
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let val = fx.bcx.ins().fcmp(fltcc, lhs, rhs);
|
let val = fx.bcx.ins().fcmp(fltcc, lhs, rhs);
|
||||||
let val = fx.bcx.ins().bint(types::I8, val);
|
|
||||||
return CValue::by_val(val, fx.layout_of(fx.tcx.types.bool));
|
return CValue::by_val(val, fx.layout_of(fx.tcx.types.bool));
|
||||||
}
|
}
|
||||||
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs),
|
_ => unreachable!("{:?}({:?}, {:?})", bin_op, in_lhs, in_rhs),
|
||||||
|
@ -440,7 +436,7 @@ pub(crate) fn codegen_ptr_binop<'tcx>(
|
||||||
_ => panic!("bin_op {:?} on ptr", bin_op),
|
_ => 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(res, fx.layout_of(fx.tcx.types.bool))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,6 @@
|
||||||
use cranelift_codegen::ir::{condcodes::IntCC, InstructionData, Opcode, Value, ValueDef};
|
use cranelift_codegen::ir::{condcodes::IntCC, InstructionData, Opcode, Value, ValueDef};
|
||||||
use cranelift_frontend::FunctionBuilder;
|
use cranelift_frontend::FunctionBuilder;
|
||||||
|
|
||||||
/// If the given value was produced by a `bint` instruction, return it's input, otherwise return the
|
|
||||||
/// given value.
|
|
||||||
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,
|
|
||||||
_ => arg,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
arg
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If the given value was produced by the lowering of `Rvalue::Not` return the input and true,
|
/// If the given value was produced by the lowering of `Rvalue::Not` return the input and true,
|
||||||
/// otherwise return the given value and false.
|
/// otherwise return the given value and false.
|
||||||
pub(crate) fn maybe_unwrap_bool_not(bcx: &mut FunctionBuilder<'_>, arg: Value) -> (Value, bool) {
|
pub(crate) fn maybe_unwrap_bool_not(bcx: &mut FunctionBuilder<'_>, arg: Value) -> (Value, bool) {
|
||||||
|
@ -48,13 +35,6 @@ pub(crate) fn maybe_known_branch_taken(
|
||||||
};
|
};
|
||||||
|
|
||||||
match bcx.func.dfg[arg_inst] {
|
match bcx.func.dfg[arg_inst] {
|
||||||
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 {
|
if test_zero {
|
||||||
Some(imm.bits() == 0)
|
Some(imm.bits() == 0)
|
||||||
|
|
|
@ -392,7 +392,7 @@ impl<'tcx> CPlace<'tcx> {
|
||||||
local: Local,
|
local: Local,
|
||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'tcx>,
|
||||||
) -> CPlace<'tcx> {
|
) -> CPlace<'tcx> {
|
||||||
let var = Variable::with_u32(fx.next_ssa_var);
|
let var = Variable::from_u32(fx.next_ssa_var);
|
||||||
fx.next_ssa_var += 1;
|
fx.next_ssa_var += 1;
|
||||||
fx.bcx.declare_var(var, fx.clif_type(layout.ty).unwrap());
|
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 }
|
||||||
|
@ -403,9 +403,9 @@ impl<'tcx> CPlace<'tcx> {
|
||||||
local: Local,
|
local: Local,
|
||||||
layout: TyAndLayout<'tcx>,
|
layout: TyAndLayout<'tcx>,
|
||||||
) -> CPlace<'tcx> {
|
) -> CPlace<'tcx> {
|
||||||
let var1 = Variable::with_u32(fx.next_ssa_var);
|
let var1 = Variable::from_u32(fx.next_ssa_var);
|
||||||
fx.next_ssa_var += 1;
|
fx.next_ssa_var += 1;
|
||||||
let var2 = Variable::with_u32(fx.next_ssa_var);
|
let var2 = Variable::from_u32(fx.next_ssa_var);
|
||||||
fx.next_ssa_var += 1;
|
fx.next_ssa_var += 1;
|
||||||
|
|
||||||
let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap();
|
let (ty1, ty2) = fx.clif_pair_type(layout.ty).unwrap();
|
||||||
|
@ -515,9 +515,7 @@ impl<'tcx> CPlace<'tcx> {
|
||||||
| (types::F32, types::I32)
|
| (types::F32, types::I32)
|
||||||
| (types::I64, types::F64)
|
| (types::I64, types::F64)
|
||||||
| (types::F64, types::I64) => fx.bcx.ins().bitcast(dst_ty, data),
|
| (types::F64, types::I64) => fx.bcx.ins().bitcast(dst_ty, data),
|
||||||
_ if src_ty.is_vector() && dst_ty.is_vector() => {
|
_ if src_ty.is_vector() && dst_ty.is_vector() => fx.bcx.ins().bitcast(dst_ty, data),
|
||||||
fx.bcx.ins().raw_bitcast(dst_ty, data)
|
|
||||||
}
|
|
||||||
_ if src_ty.is_vector() || dst_ty.is_vector() => {
|
_ if src_ty.is_vector() || dst_ty.is_vector() => {
|
||||||
// FIXME do something more efficient for transmutes between vectors and integers.
|
// FIXME do something more efficient for transmutes between vectors and integers.
|
||||||
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
|
||||||
|
@ -590,7 +588,10 @@ impl<'tcx> CPlace<'tcx> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CPlaceInner::VarPair(_local, var1, var2) => {
|
CPlaceInner::VarPair(_local, var1, var2) => {
|
||||||
let (data1, data2) = CValue(from.0, dst_layout).load_scalar_pair(fx);
|
let (ptr, meta) = from.force_stack(fx);
|
||||||
|
assert!(meta.is_none());
|
||||||
|
let (data1, data2) =
|
||||||
|
CValue(CValueInner::ByRef(ptr, None), dst_layout).load_scalar_pair(fx);
|
||||||
let (dst_ty1, dst_ty2) = fx.clif_pair_type(self.layout().ty).unwrap();
|
let (dst_ty1, dst_ty2) = fx.clif_pair_type(self.layout().ty).unwrap();
|
||||||
transmute_value(fx, var1, data1, dst_ty1);
|
transmute_value(fx, var1, data1, dst_ty1);
|
||||||
transmute_value(fx, var2, data2, dst_ty2);
|
transmute_value(fx, var2, data2, dst_ty2);
|
||||||
|
|
2
test.sh
2
test.sh
|
@ -1,2 +1,2 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
exec ./y.rs test
|
exec ./y.rs test "$@"
|
||||||
|
|
2
y.rs
2
y.rs
|
@ -3,7 +3,7 @@
|
||||||
# This block is ignored by rustc
|
# This block is ignored by rustc
|
||||||
set -e
|
set -e
|
||||||
echo "[BUILD] y.rs" 1>&2
|
echo "[BUILD] y.rs" 1>&2
|
||||||
rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1
|
rustc $0 -o ${0/.rs/.bin} -Cdebuginfo=1 --edition 2021
|
||||||
exec ${0/.rs/.bin} $@
|
exec ${0/.rs/.bin} $@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue