Rollup merge of #92131 - bjorn3:sync_cg_clif-2021-12-20, r=bjorn3

Sync rustc_codegen_cranelift

The main highlight this sync is improved support for inline assembly. Thanks `@nbdd0121!` Inline assembly is still disabled by default for builds in the main rust repo though. Cranelift will now also be built from the crates.io releases rather than the git repo. Git repos are incompatible with vendoring.

r? `@ghost`

`@rustbot` label +A-codegen +A-cranelift +T-compiler
This commit is contained in:
Matthias Krüger 2021-12-21 08:33:43 +01:00 committed by GitHub
commit ee45a532f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1017 additions and 532 deletions

View File

@ -65,6 +65,12 @@ jobs:
git config --global user.name "User"
./y.rs prepare
- name: Build without unstable features
env:
TARGET_TRIPLE: ${{ matrix.env.TARGET_TRIPLE }}
# This is the config rust-lang/rust uses for builds
run: ./y.rs build --no-unstable-features
- name: Build
run: ./y.rs build --sysroot none
@ -152,11 +158,12 @@ jobs:
./y.exe build
#- name: Package prebuilt cg_clif
# run: tar cvfJ cg_clif.tar.xz build
- name: Package prebuilt cg_clif
# don't use compression as xzip isn't supported by tar on windows and bzip2 hangs
run: tar cvf cg_clif.tar build
#- name: Upload prebuilt cg_clif
# uses: actions/upload-artifact@v2
# with:
# name: cg_clif-${{ runner.os }}
# path: cg_clif.tar.xz
- name: Upload prebuilt cg_clif
uses: actions/upload-artifact@v2
with:
name: cg_clif-${{ runner.os }}
path: cg_clif.tar

View File

@ -0,0 +1,59 @@
name: Test nightly Cranelift
on:
push:
schedule:
- cron: '1 17 * * *' # At 01:17 UTC every day.
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v2
- name: Cache cargo installed crates
uses: actions/cache@v2
with:
path: ~/.cargo/bin
key: ubuntu-latest-cargo-installed-crates
- name: Prepare dependencies
run: |
git config --global user.email "user@example.com"
git config --global user.name "User"
./y.rs prepare
- name: Patch Cranelift
run: |
sed -i 's/cranelift-codegen = { version = "\w*.\w*.\w*", features = \["unwind", "all-arch"\] }/cranelift-codegen = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", features = ["unwind", "all-arch"] }/' Cargo.toml
sed -i 's/cranelift-frontend = "\w*.\w*.\w*"/cranelift-frontend = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
sed -i 's/cranelift-module = "\w*.\w*.\w*"/cranelift-module = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
sed -i 's/cranelift-native = "\w*.\w*.\w*"/cranelift-native = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
sed -i 's/cranelift-jit = { version = "\w*.\w*.\w*", optional = true }/cranelift-jit = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git", optional = true }/' Cargo.toml
sed -i 's/cranelift-object = "\w*.\w*.\w*"/cranelift-object = { git = "https:\/\/github.com\/bytecodealliance\/wasmtime.git" }/' Cargo.toml
sed -i 's/gimli = { version = "0.25.0", default-features = false, features = \["write"\]}/gimli = { version = "0.26.1", default-features = false, features = ["write"] }/' Cargo.toml
cat Cargo.toml
- name: Build without unstable features
# This is the config rust-lang/rust uses for builds
run: ./y.rs build --no-unstable-features
- name: Build
run: ./y.rs build --sysroot none
- name: Test
run: |
# Enable backtraces for easier debugging
export RUST_BACKTRACE=1
# Reduce amount of benchmark runs as they are slow
export COMPILE_RUNS=2
export RUN_RUNS=2
# Enable extra checks
export CG_CLIF_ENABLE_VERIFIER=1
./test.sh

View File

@ -5,6 +5,7 @@
"rust-analyzer.assist.importEnforceGranularity": true,
"rust-analyzer.assist.importPrefix": "crate",
"rust-analyzer.cargo.runBuildScripts": true,
"rust-analyzer.cargo.features": ["unstable-features"]
"rust-analyzer.linkedProjects": [
"./Cargo.toml",
//"./build_sysroot/sysroot_src/src/libstd/Cargo.toml",

View File

@ -4,9 +4,9 @@ version = 3
[[package]]
name = "anyhow"
version = "1.0.42"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
checksum = "8b26702f315f53b6071259e15dd9d64528213b44d61de1ec926eca7715d62203"
[[package]]
name = "ar"
@ -21,9 +21,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
@ -33,16 +33,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cranelift-bforest"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc0cb7df82c8cf8f2e6a8dd394a0932a71369c160cc9b027dca414fced242513"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-codegen"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe4463c15fa42eee909e61e5eac4866b7c6d22d0d8c621e57a0c5380753bfa8c"
dependencies = [
"cranelift-bforest",
"cranelift-codegen-meta",
@ -57,8 +59,9 @@ dependencies = [
[[package]]
name = "cranelift-codegen-meta"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793f6a94a053a55404ea16e1700202a88101672b8cd6b4df63e13cde950852bf"
dependencies = [
"cranelift-codegen-shared",
"cranelift-entity",
@ -66,18 +69,21 @@ dependencies = [
[[package]]
name = "cranelift-codegen-shared"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44aa1846df275bce5eb30379d65964c7afc63c05a117076e62a119c25fe174be"
[[package]]
name = "cranelift-entity"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3a45d8d6318bf8fc518154d9298eab2a8154ec068a8885ff113f6db8d69bb3a"
[[package]]
name = "cranelift-frontend"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e07339bd461766deb7605169de039e01954768ff730fa1254e149001884a8525"
dependencies = [
"cranelift-codegen",
"log",
@ -87,8 +93,9 @@ dependencies = [
[[package]]
name = "cranelift-jit"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e8f0d60fb5d67f7a1e5c49db38ba96d1c846921faef02085fc5590b74781747"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -104,8 +111,9 @@ dependencies = [
[[package]]
name = "cranelift-module"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "825ac7e0959cbe7ddc9cc21209f0319e611a57f9fcb2b723861fe7ef2017e651"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -115,8 +123,9 @@ dependencies = [
[[package]]
name = "cranelift-native"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03e2fca76ff57e0532936a71e3fc267eae6a19a86656716479c66e7f912e3d7b"
dependencies = [
"cranelift-codegen",
"libc",
@ -125,8 +134,9 @@ dependencies = [
[[package]]
name = "cranelift-object"
version = "0.76.0"
source = "git+https://github.com/bytecodealliance/wasmtime.git#9c550fcf41425942ed97c747f0169b2ca81f9c1b"
version = "0.78.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55500d0fc9bb05c0944fc4506649249d28f55bd4fe95b87f0e55bf41058f0e6d"
dependencies = [
"anyhow",
"cranelift-codegen",
@ -138,9 +148,9 @@ dependencies = [
[[package]]
name = "crc32fast"
version = "1.2.1"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
dependencies = [
"cfg-if",
]
@ -172,9 +182,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.98"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
[[package]]
name = "libloading"
@ -206,15 +216,15 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.4.0"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "object"
version = "0.26.0"
version = "0.27.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386"
checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
dependencies = [
"crc32fast",
"indexmap",
@ -223,9 +233,9 @@ dependencies = [
[[package]]
name = "regalloc"
version = "0.0.31"
version = "0.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "571f7f397d61c4755285cd37853fe8e03271c243424a907415909379659381c5"
checksum = "a6304468554ed921da3d32c355ea107b8d13d7b8996c3adfb7aab48d3bc321f4"
dependencies = [
"log",
"rustc-hash",
@ -271,15 +281,15 @@ dependencies = [
[[package]]
name = "smallvec"
version = "1.6.1"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]]
name = "target-lexicon"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0652da4c4121005e9ed22b79f6c5f2d9e2752906b53a33e9490489ba421a6fb"
checksum = "d9bffcddbc2458fa3e6058414599e3c838a022abae82e5c67b4f7f80298d5bff"
[[package]]
name = "winapi"

View File

@ -8,23 +8,23 @@ crate-type = ["dylib"]
[dependencies]
# These have to be in sync with each other
cranelift-codegen = { git = "https://github.com/bytecodealliance/wasmtime.git", features = ["unwind", "all-arch"] }
cranelift-frontend = { git = "https://github.com/bytecodealliance/wasmtime.git" }
cranelift-module = { git = "https://github.com/bytecodealliance/wasmtime.git" }
cranelift-native = { git = "https://github.com/bytecodealliance/wasmtime.git" }
cranelift-jit = { git = "https://github.com/bytecodealliance/wasmtime.git", optional = true }
cranelift-object = { git = "https://github.com/bytecodealliance/wasmtime.git" }
cranelift-codegen = { version = "0.78.0", features = ["unwind", "all-arch"] }
cranelift-frontend = "0.78.0"
cranelift-module = "0.78.0"
cranelift-native = "0.78.0"
cranelift-jit = { version = "0.78.0", optional = true }
cranelift-object = "0.78.0"
target-lexicon = "0.12.0"
gimli = { version = "0.25.0", default-features = false, features = ["write"]}
object = { version = "0.26.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
object = { version = "0.27.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
indexmap = "1.0.2"
libloading = { version = "0.6.0", optional = true }
smallvec = "1.6.1"
[patch.crates-io]
# Uncomment to use local checkout of cranelift
#[patch."https://github.com/bytecodealliance/wasmtime.git"]
#cranelift-codegen = { path = "../wasmtime/cranelift/codegen" }
#cranelift-frontend = { path = "../wasmtime/cranelift/frontend" }
#cranelift-module = { path = "../wasmtime/cranelift/module" }
@ -32,7 +32,6 @@ smallvec = "1.6.1"
#cranelift-jit = { path = "../wasmtime/cranelift/jit" }
#cranelift-object = { path = "../wasmtime/cranelift/object" }
#[patch.crates-io]
#gimli = { path = "../" }
[features]

View File

@ -40,9 +40,9 @@ checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "cc"
version = "1.0.70"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]]
name = "cfg-if"
@ -56,7 +56,7 @@ dependencies = [
[[package]]
name = "compiler_builtins"
version = "0.1.50"
version = "0.1.66"
dependencies = [
"rustc-std-workspace-core",
]
@ -67,9 +67,9 @@ version = "0.0.0"
[[package]]
name = "dlmalloc"
version = "0.2.1"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "332570860c2edf2d57914987bf9e24835425f75825086b6ba7d1e6a3e4f1f254"
checksum = "a6fe28e0bf9357092740362502f5cc7955d8dc125ebda71dec72336c2e15c62e"
dependencies = [
"compiler_builtins",
"libc",
@ -132,9 +132,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.102"
version = "0.2.112"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
dependencies = [
"rustc-std-workspace-core",
]

View File

@ -2,9 +2,17 @@ use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
pub(crate) fn build_backend(channel: &str, host_triple: &str) -> PathBuf {
pub(crate) fn build_backend(
channel: &str,
host_triple: &str,
use_unstable_features: bool,
) -> PathBuf {
let mut cmd = Command::new("cargo");
cmd.arg("build").arg("--target").arg(host_triple).arg("--features").arg("unstable-features");
cmd.arg("build").arg("--target").arg(host_triple);
if use_unstable_features {
cmd.arg("--features").arg("unstable-features");
}
match channel {
"debug" => {}

View File

@ -193,8 +193,7 @@ fn build_clif_sysroot_for_triple(
"RUSTC",
env::current_dir().unwrap().join(target_dir).join("bin").join("cg_clif_build_sysroot"),
);
// FIXME Enable incremental again once rust-lang/rust#74946 is fixed
build_cmd.env("CARGO_INCREMENTAL", "0").env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
build_cmd.env("__CARGO_DEFAULT_LIB_METADATA", "cg_clif");
spawn_and_wait(build_cmd);
// Copy all relevant files to the sysroot

View File

@ -30,7 +30,7 @@ pub(crate) fn prepare() {
clone_repo(
"portable-simd",
"https://github.com/rust-lang/portable-simd",
"8cf7a62e5d2552961df51e5200aaa5b7c890a4bf",
"b8d6b6844602f80af79cd96401339ec594d472d8",
);
apply_patches("portable-simd", Path::new("portable-simd"));
@ -92,7 +92,7 @@ fn prepare_sysroot() {
clone_repo(
"build_sysroot/compiler-builtins",
"https://github.com/rust-lang/compiler-builtins.git",
"0.1.50",
"0.1.66",
);
apply_patches("compiler-builtins", Path::new("build_sysroot/compiler-builtins"));
}

View File

@ -0,0 +1,60 @@
// Copied from rustc ui test suite
// run-pass
//
// Test that we can handle unsized types with an extern type tail part.
// Regression test for issue #91827.
#![feature(const_ptr_offset_from)]
#![feature(const_slice_from_raw_parts)]
#![feature(extern_types)]
use std::ptr::addr_of;
extern "C" {
type Opaque;
}
unsafe impl Sync for Opaque {}
#[repr(C)]
pub struct List<T> {
len: usize,
data: [T; 0],
tail: Opaque,
}
#[repr(C)]
pub struct ListImpl<T, const N: usize> {
len: usize,
data: [T; N],
}
impl<T> List<T> {
const fn as_slice(&self) -> &[T] {
unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
}
}
impl<T, const N: usize> ListImpl<T, N> {
const fn as_list(&self) -> &List<T> {
unsafe { std::mem::transmute(self) }
}
}
pub static A: ListImpl<u128, 3> = ListImpl {
len: 3,
data: [5, 6, 7],
};
pub static A_REF: &'static List<u128> = A.as_list();
pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
const fn tail_offset<T>(list: &List<T>) -> isize {
unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
}
fn main() {
assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
// Check that interpreter and code generation agree about the position of the tail field.
assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
}

View File

@ -1,41 +1,20 @@
From 6bfce5dc2cbf834c74dbccb7538adc08c6eb57e7 Mon Sep 17 00:00:00 2001
From 97c473937382a5b5858d9cce3c947855d23b2dc5 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Sun, 25 Jul 2021 18:39:31 +0200
Date: Thu, 18 Nov 2021 19:28:40 +0100
Subject: [PATCH] Disable unsupported tests
---
crates/core_simd/src/vector.rs | 2 ++
crates/core_simd/src/math.rs | 4 ++++
crates/core_simd/tests/masks.rs | 12 ------------
crates/core_simd/tests/ops_macros.rs | 6 ++++++
crates/core_simd/tests/round.rs | 2 ++
6 files changed, 15 insertions(+), 13 deletions(-)
crates/core_simd/src/math.rs | 6 ++++++
crates/core_simd/src/vector.rs | 2 ++
crates/core_simd/tests/masks.rs | 2 ++
crates/core_simd/tests/ops_macros.rs | 4 ++++
4 files changed, 14 insertions(+)
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index 25c5309..2b3d819 100644
--- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs
@@ -22,6 +22,7 @@ where
self.0
}
+ /*
/// SIMD gather: construct a SIMD vector by reading from a slice, using potentially discontiguous indices.
/// If an index is out of bounds, that lane instead selects the value from the "or" vector.
/// ```
@@ -150,6 +151,7 @@ where
// Cleared ☢️ *mut T Zone
}
}
+ */
}
impl<T, const LANES: usize> Copy for Simd<T, LANES>
diff --git a/crates/core_simd/src/math.rs b/crates/core_simd/src/math.rs
index 7290a28..e394730 100644
index 2bae414..2f87499 100644
--- a/crates/core_simd/src/math.rs
+++ b/crates/core_simd/src/math.rs
@@ -2,6 +2,7 @@ macro_rules! impl_uint_arith {
@@ -5,6 +5,7 @@ macro_rules! impl_uint_arith {
($($ty:ty),+) => {
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
@ -43,15 +22,15 @@ index 7290a28..e394730 100644
/// Lanewise saturating add.
///
/// # Examples
@@ -38,6 +39,7 @@ macro_rules! impl_uint_arith {
@@ -43,6 +44,7 @@ macro_rules! impl_uint_arith {
pub fn saturating_sub(self, second: Self) -> Self {
unsafe { crate::intrinsics::simd_saturating_sub(self, second) }
unsafe { simd_saturating_sub(self, second) }
}
+ */
})+
}
}
@@ -46,6 +48,7 @@ macro_rules! impl_int_arith {
@@ -51,6 +53,7 @@ macro_rules! impl_int_arith {
($($ty:ty),+) => {
$( impl<const LANES: usize> Simd<$ty, LANES> where LaneCount<LANES>: SupportedLaneCount {
@ -59,7 +38,23 @@ index 7290a28..e394730 100644
/// Lanewise saturating add.
///
/// # Examples
@@ -141,6 +144,7 @@ macro_rules! impl_int_arith {
@@ -89,6 +92,7 @@ macro_rules! impl_int_arith {
pub fn saturating_sub(self, second: Self) -> Self {
unsafe { simd_saturating_sub(self, second) }
}
+ */
/// Lanewise absolute value, implemented in Rust.
/// Every lane becomes its absolute value.
@@ -109,6 +113,7 @@ macro_rules! impl_int_arith {
(self^m) - m
}
+ /*
/// Lanewise saturating absolute value, implemented in Rust.
/// As abs(), except the MIN value becomes MAX instead of itself.
///
@@ -151,6 +156,7 @@ macro_rules! impl_int_arith {
pub fn saturating_neg(self) -> Self {
Self::splat(0).saturating_sub(self)
}
@ -67,51 +62,51 @@ index 7290a28..e394730 100644
})+
}
}
diff --git a/crates/core_simd/src/vector.rs b/crates/core_simd/src/vector.rs
index 7c5ec2b..c8631e8 100644
--- a/crates/core_simd/src/vector.rs
+++ b/crates/core_simd/src/vector.rs
@@ -75,6 +75,7 @@ where
Self(array)
}
+ /*
/// Reads from potentially discontiguous indices in `slice` to construct a SIMD vector.
/// If an index is out-of-bounds, the lane is instead selected from the `or` vector.
///
@@ -297,6 +298,7 @@ where
// Cleared ☢️ *mut T Zone
}
}
+ */
}
impl<T, const LANES: usize> Copy for Simd<T, LANES>
diff --git a/crates/core_simd/tests/masks.rs b/crates/core_simd/tests/masks.rs
index 61d8e44..2bccae2 100644
index 6a8ecd3..68fcb49 100644
--- a/crates/core_simd/tests/masks.rs
+++ b/crates/core_simd/tests/masks.rs
@@ -67,19 +67,6 @@ macro_rules! test_mask_api {
assert_eq!(int.to_array(), [-1, 0, 0, -1, 0, 0, -1, 0]);
@@ -68,6 +68,7 @@ macro_rules! test_mask_api {
assert_eq!(core_simd::Mask::<$type, 8>::from_int(int), mask);
}
-
- #[cfg(feature = "generic_const_exprs")]
- #[test]
- fn roundtrip_bitmask_conversion() {
- let values = [
- true, false, false, true, false, false, true, false,
- true, true, false, false, false, false, false, true,
- ];
- let mask = core_simd::Mask::<$type, 16>::from_array(values);
- let bitmask = mask.to_bitmask();
- assert_eq!(bitmask, [0b01001001, 0b10000011]);
- assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
- }
+ /*
#[cfg(feature = "generic_const_exprs")]
#[test]
fn roundtrip_bitmask_conversion() {
@@ -80,6 +81,7 @@ macro_rules! test_mask_api {
assert_eq!(bitmask, [0b01001001, 0b10000011]);
assert_eq!(core_simd::Mask::<$type, 16>::from_bitmask(bitmask), mask);
}
+ */
}
}
}
diff --git a/crates/core_simd/tests/ops_macros.rs b/crates/core_simd/tests/ops_macros.rs
index cb39e73..fc0ebe1 100644
index 31b7ee2..bd04b3c 100644
--- a/crates/core_simd/tests/ops_macros.rs
+++ b/crates/core_simd/tests/ops_macros.rs
@@ -435,6 +435,7 @@ macro_rules! impl_float_tests {
)
}
+ /*
fn mul_add<const LANES: usize>() {
test_helpers::test_ternary_elementwise(
&Vector::<LANES>::mul_add,
@@ -442,6 +443,7 @@ macro_rules! impl_float_tests {
&|_, _, _| true,
)
}
+ */
fn recip<const LANES: usize>() {
test_helpers::test_unary_elementwise(
@@ -581,6 +585,7 @@ macro_rules! impl_float_tests {
@@ -567,6 +567,7 @@ macro_rules! impl_float_tests {
});
}
@ -119,7 +114,7 @@ index cb39e73..fc0ebe1 100644
fn horizontal_max<const LANES: usize>() {
test_helpers::test_1(&|x| {
let vmax = Vector::<LANES>::from_array(x).horizontal_max();
@@ -604,6 +609,7 @@ macro_rules! impl_float_tests {
@@ -590,6 +591,7 @@ macro_rules! impl_float_tests {
Ok(())
});
}
@ -127,26 +122,22 @@ index cb39e73..fc0ebe1 100644
}
#[cfg(feature = "std")]
diff --git a/crates/core_simd/tests/round.rs b/crates/core_simd/tests/round.rs
index 37044a7..4cdc6b7 100644
--- a/crates/core_simd/tests/round.rs
+++ b/crates/core_simd/tests/round.rs
@@ -25,6 +25,7 @@ macro_rules! float_rounding_test {
)
}
@@ -604,6 +606,7 @@ macro_rules! impl_float_tests {
)
}
+ /*
fn round<const LANES: usize>() {
test_helpers::test_unary_elementwise(
&Vector::<LANES>::round,
@@ -32,6 +33,7 @@ macro_rules! float_rounding_test {
&|_| true,
)
+ /*
fn mul_add<const LANES: usize>() {
test_helpers::test_ternary_elementwise(
&Vector::<LANES>::mul_add,
@@ -611,6 +614,7 @@ macro_rules! impl_float_tests {
&|_, _, _| true,
)
}
+ */
}
+ */
fn trunc<const LANES: usize>() {
test_helpers::test_unary_elementwise(
}
}
--
2.26.2.7.g19db9cfb68

View File

@ -107,7 +107,7 @@ index fa96b7a..2854f9c 100644
inner::monotonize(raw)
}
-#[cfg(all(target_has_atomic = "64", not(target_has_atomic = "128")))]
-#[cfg(any(all(target_has_atomic = "64", not(target_has_atomic = "128")), target_arch = "aarch64"))]
+#[cfg(target_has_atomic = "64")]
pub mod inner {
use crate::sync::atomic::AtomicU64;
@ -117,7 +117,7 @@ index fa96b7a..2854f9c 100644
}
+/*
#[cfg(target_has_atomic = "128")]
#[cfg(all(target_has_atomic = "128", not(target_arch = "aarch64")))]
pub mod inner {
use crate::sync::atomic::AtomicU128;
@@ -94,8 +95,9 @@ pub mod inner {

View File

@ -0,0 +1,30 @@
From 0ffdd8eda8df364391c8ac6e1ce92c73ba9254d4 Mon Sep 17 00:00:00 2001
From: bjorn3 <bjorn3@users.noreply.github.com>
Date: Fri, 3 Dec 2021 12:16:30 +0100
Subject: [PATCH] Disable long running tests
---
library/core/tests/slice.rs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 2c8f00a..44847ee 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2332,7 +2332,8 @@ macro_rules! empty_max_mut {
};
}
+/*
#[cfg(not(miri))] // Comparing usize::MAX many elements takes forever in Miri (and in rustc without optimizations)
take_tests! {
slice: &[(); usize::MAX], method: take,
(take_in_bounds_max_range_to, (..usize::MAX), Some(EMPTY_MAX), &[(); 0]),
@@ -2345,3 +2347,4 @@ take_tests! {
(take_mut_oob_max_range_to_inclusive, (..=usize::MAX), None, empty_max_mut!()),
(take_mut_in_bounds_max_range_from, (usize::MAX..), Some(&mut [] as _), empty_max_mut!()),
}
+*/
--
2.26.2.7.g19db9cfb68

View File

@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2021-09-19"
channel = "nightly-2021-12-20"
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]

View File

@ -33,7 +33,7 @@ index d95b5b7f17f..00b6f0e3635 100644
[dependencies]
core = { path = "../core" }
-compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "0.1.46", features = ['rustc-dep-of-std', 'no-asm'] }
+compiler_builtins = { version = "0.1.66", features = ['rustc-dep-of-std', 'no-asm'] }
[dev-dependencies]
rand = "0.7"
@ -53,5 +53,6 @@ local-rebuild = true
[rust]
codegen-backends = ["cranelift"]
deny-warnings = false
verbose-tests = false
EOF
popd

View File

@ -10,7 +10,7 @@ pushd rust
cargo install ripgrep
rm -r src/test/ui/{extern/,panics/,unsized-locals/,thinlto/,simd*,*lto*.rs,linkage*,unwind-*.rs} || true
rm -r src/test/ui/{extern/,panics/,unsized-locals/,lto/,simd*,linkage*,unwind-*.rs} || true
for test in $(rg --files-with-matches "asm!|catch_unwind|should_panic|lto|// needs-asm-support" src/test/ui); do
rm $test
done
@ -30,19 +30,20 @@ rm src/test/ui/cleanup-rvalue-temp-during-incomplete-alloc.rs
rm src/test/ui/issues/issue-26655.rs
rm src/test/ui/issues/issue-29485.rs
rm src/test/ui/issues/issue-30018-panic.rs
rm src/test/ui/multi-panic.rs
rm src/test/ui/process/multi-panic.rs
rm src/test/ui/sepcomp/sepcomp-unwind.rs
rm src/test/ui/structs-enums/unit-like-struct-drop-run.rs
rm src/test/ui/terminate-in-initializer.rs
rm src/test/ui/drop/terminate-in-initializer.rs
rm src/test/ui/threads-sendsync/task-stderr.rs
rm src/test/ui/numbers-arithmetic/int-abs-overflow.rs
rm src/test/ui/drop/drop-trait-enum.rs
rm src/test/ui/numbers-arithmetic/issue-8460.rs
rm src/test/ui/rt-explody-panic-payloads.rs
rm src/test/ui/runtime/rt-explody-panic-payloads.rs
rm src/test/incremental/change_crate_dep_kind.rs
rm src/test/ui/threads-sendsync/unwind-resource.rs
rm src/test/ui/issues/issue-28950.rs # depends on stack size optimizations
rm src/test/ui/init-large-type.rs # same
rm src/test/ui/codegen/init-large-type.rs # same
rm src/test/ui/sse2.rs # cpuid not supported, so sse2 not detected
rm src/test/ui/issues/issue-33992.rs # unsupported linkages
rm src/test/ui/issues/issue-51947.rs # same
@ -65,6 +66,7 @@ rm src/test/incremental/lto.rs # requires lto
rm -r src/test/run-make/emit-shared-files # requires the rustdoc executable in build/bin/
rm -r src/test/run-make/unstable-flag-required # same
rm -r src/test/run-make/rustdoc-* # same
rm -r src/test/run-make/emit-named-files # requires full --emit support
rm src/test/pretty/asm.rs # inline asm
@ -74,7 +76,10 @@ rm -r src/test/run-pass-valgrind/unsized-locals
rm src/test/ui/json-bom-plus-crlf-multifile.rs # differing warning
rm src/test/ui/json-bom-plus-crlf.rs # same
rm src/test/ui/intrinsics/const-eval-select-x86_64.rs # same
rm src/test/ui/match/issue-82392.rs # differing error
rm src/test/ui/consts/min_const_fn/address_of_const.rs # same
rm src/test/ui/consts/issue-miri-1910.rs # same
rm src/test/ui/type-alias-impl-trait/cross_crate_ice*.rs # requires removed aux dep
rm src/test/ui/allocator/no_std-alloc-error-handler-default.rs # missing rust_oom definition
@ -88,6 +93,10 @@ rm -r src/test/run-make/fmt-write-bloat/ # tests an optimization
rm src/test/ui/abi/mir/mir_codegen_calls_variadic.rs # requires float varargs
rm src/test/ui/abi/variadic-ffi.rs # requires callee side vararg support
rm src/test/ui/command/command-current-dir.rs # can't find libstd.so
rm src/test/ui/abi/stack-protector.rs # requires stack protector support
echo "[TEST] rustc test suite"
RUST_TEST_NOCAPTURE=1 COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0 src/test/{codegen-units,run-make,run-pass-valgrind,ui}
popd

View File

@ -35,6 +35,10 @@ function base_sysroot_tests() {
$MY_RUSTC example/arbitrary_self_types_pointers_and_wrappers.rs --crate-name arbitrary_self_types_pointers_and_wrappers --crate-type bin --target "$TARGET_TRIPLE"
$RUN_WRAPPER ./target/out/arbitrary_self_types_pointers_and_wrappers
echo "[AOT] issue_91827_extern_types"
$MY_RUSTC example/issue-91827-extern-types.rs --crate-name issue_91827_extern_types --crate-type bin --target "$TARGET_TRIPLE"
$RUN_WRAPPER ./target/out/issue_91827_extern_types
echo "[AOT] alloc_system"
$MY_RUSTC example/alloc_system.rs --crate-type lib --target "$TARGET_TRIPLE"

View File

@ -18,11 +18,11 @@ pub(crate) use self::returning::codegen_return;
fn clif_sig_from_fn_abi<'tcx>(
tcx: TyCtxt<'tcx>,
triple: &target_lexicon::Triple,
default_call_conv: CallConv,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) -> Signature {
let call_conv = match fn_abi.conv {
Conv::Rust | Conv::C => CallConv::triple_default(triple),
Conv::Rust | Conv::C => default_call_conv,
Conv::X86_64SysV => CallConv::SystemV,
Conv::X86_64Win64 => CallConv::WindowsFastcall,
Conv::ArmAapcs
@ -55,7 +55,7 @@ pub(crate) fn get_function_sig<'tcx>(
assert!(!inst.substs.needs_infer());
clif_sig_from_fn_abi(
tcx,
triple,
CallConv::triple_default(triple),
&RevealAllLayoutCx(tcx).fn_abi_of_instance(inst, ty::List::empty()),
)
}
@ -91,7 +91,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
returns: Vec<AbiParam>,
args: &[Value],
) -> &[Value] {
let sig = Signature { params, returns, call_conv: CallConv::triple_default(self.triple()) };
let sig = Signature { params, returns, call_conv: self.target_config.default_call_conv };
let func_id = self.module.declare_function(name, Linkage::Import, &sig).unwrap();
let func_ref = self.module.declare_func_in_func(func_id, &mut self.bcx.func);
let call_inst = self.bcx.ins().call(func_ref, args);
@ -420,7 +420,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
let (ptr, method) = crate::vtable::get_ptr_and_method_ref(fx, args[0].value, idx);
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig);
(CallTarget::Indirect(sig, method), Some(ptr))
@ -440,7 +440,7 @@ pub(crate) fn codegen_terminator_call<'tcx>(
}
let func = codegen_operand(fx, func).load_scalar(fx);
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &fn_abi);
let sig = clif_sig_from_fn_abi(fx.tcx, fx.target_config.default_call_conv, &fn_abi);
let sig = fx.bcx.import_signature(sig);
(CallTarget::Indirect(sig, func), None)
@ -531,7 +531,7 @@ pub(crate) fn codegen_drop<'tcx>(
let fn_abi =
RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(virtual_drop, ty::List::empty());
let sig = clif_sig_from_fn_abi(fx.tcx, fx.triple(), &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);
fx.bcx.ins().call_indirect(sig, drop_fn, &[ptr]);
}

View File

@ -117,7 +117,9 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
PassMode::Cast(cast) => cast_target_to_abi_params(cast),
PassMode::Indirect { attrs, extra_attrs: None, on_stack } => {
if on_stack {
let size = u32::try_from(self.layout.size.bytes()).unwrap();
// Abi requires aligning struct size to pointer size
let size = self.layout.size.align_to(tcx.data_layout.pointer_align.abi);
let size = u32::try_from(size.bytes()).unwrap();
smallvec![apply_arg_attrs_to_abi_param(
AbiParam::special(pointer_ty(tcx), ArgumentPurpose::StructArgument(size),),
attrs
@ -204,7 +206,6 @@ pub(super) fn from_casted_value<'tcx>(
// It may also be smaller for example when the type is a wrapper around an integer with a
// larger alignment than the integer.
size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16,
offset: None,
});
let ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0));
let mut offset = 0;

View File

@ -1,7 +1,6 @@
//! Creation of ar archives like for the lib and staticlib crate type
use std::collections::BTreeMap;
use std::convert::TryFrom;
use std::fs::File;
use std::io::{self, Read, Seek};
use std::path::{Path, PathBuf};
@ -10,7 +9,7 @@ use rustc_codegen_ssa::back::archive::ArchiveBuilder;
use rustc_session::Session;
use object::read::archive::ArchiveFile;
use object::{Object, ObjectSymbol, ReadCache, SymbolKind};
use object::{Object, ObjectSymbol, ReadCache};
#[derive(Debug)]
enum ArchiveEntry {
@ -150,12 +149,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
object
.symbols()
.filter_map(|symbol| {
if symbol.is_undefined()
|| symbol.is_local()
|| symbol.kind() != SymbolKind::Data
&& symbol.kind() != SymbolKind::Text
&& symbol.kind() != SymbolKind::Tls
{
if symbol.is_undefined() || symbol.is_local() {
None
} else {
symbol.name().map(|name| name.as_bytes().to_vec()).ok()

View File

@ -49,13 +49,15 @@ pub(crate) fn codegen_fn<'tcx>(
(0..mir.basic_blocks().len()).map(|_| bcx.create_block()).collect();
// Make FunctionCx
let pointer_type = module.target_config().pointer_type();
let target_config = module.target_config();
let pointer_type = target_config.pointer_type();
let clif_comments = crate::pretty_clif::CommentWriter::new(tcx, instance);
let mut fx = FunctionCx {
cx,
module,
tcx,
target_config,
pointer_type,
constants_cx: ConstantCx::new(),
@ -72,8 +74,6 @@ pub(crate) fn codegen_fn<'tcx>(
clif_comments,
source_info_set: indexmap::IndexSet::new(),
next_ssa_var: 0,
inline_asm_index: 0,
};
let arg_uninhabited = fx
@ -204,7 +204,6 @@ pub(crate) fn verify_func(
tcx.sess.err(&format!("{:?}", err));
let pretty_error = cranelift_codegen::print_errors::pretty_verifier_error(
&func,
None,
Some(Box::new(writer)),
err,
);
@ -296,9 +295,7 @@ fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
AssertKind::BoundsCheck { ref len, ref index } => {
let len = codegen_operand(fx, len).load_scalar(fx);
let index = codegen_operand(fx, index).load_scalar(fx);
let location = fx
.get_caller_location(source_info.span)
.load_scalar(fx);
let location = fx.get_caller_location(source_info.span).load_scalar(fx);
codegen_panic_inner(
fx,
@ -681,7 +678,7 @@ fn codegen_stmt<'tcx>(
// FIXME use emit_small_memset where possible
let addr = lval.to_ptr().get_addr(fx);
let val = operand.load_scalar(fx);
fx.bcx.call_memset(fx.module.target_config(), addr, val, times);
fx.bcx.call_memset(fx.target_config, addr, val, times);
} else {
let loop_block = fx.bcx.create_block();
let loop_block2 = fx.bcx.create_block();
@ -754,8 +751,7 @@ fn codegen_stmt<'tcx>(
NullOp::AlignOf => layout.align.abi.bytes(),
NullOp::Box => unreachable!(),
};
let val =
CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
let val = CValue::const_val(fx, fx.layout_of(fx.tcx.types.usize), val.into());
lval.write_cvalue(fx, val);
}
Rvalue::Aggregate(ref kind, ref operands) => match kind.as_ref() {
@ -803,7 +799,7 @@ fn codegen_stmt<'tcx>(
let elem_size: u64 = pointee.size.bytes();
let bytes =
if elem_size != 1 { fx.bcx.ins().imul_imm(count, elem_size as i64) } else { count };
fx.bcx.call_memcpy(fx.module.target_config(), dst, src, bytes);
fx.bcx.call_memcpy(fx.target_config, dst, src, bytes);
}
}
}

View File

@ -1,3 +1,4 @@
use cranelift_codegen::isa::TargetFrontendConfig;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::layout::{
FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOfHelpers,
@ -235,6 +236,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
pub(crate) cx: &'clif mut crate::CodegenCx<'tcx>,
pub(crate) module: &'m mut dyn Module,
pub(crate) tcx: TyCtxt<'tcx>,
pub(crate) target_config: TargetFrontendConfig, // Cached from module
pub(crate) pointer_type: Type, // Cached from module
pub(crate) constants_cx: ConstantCx,
@ -255,8 +257,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
/// This should only be accessed by `CPlace::new_var`.
pub(crate) next_ssa_var: u32,
pub(crate) inline_asm_index: u32,
}
impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
@ -359,10 +359,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
crate::constant::codegen_const_value(self, const_loc, self.tcx.caller_location_ty())
}
pub(crate) fn triple(&self) -> &target_lexicon::Triple {
self.module.isa().triple()
}
pub(crate) fn anonymous_str(&mut self, msg: &str) -> Value {
let mut data_ctx = DataContext::new();
data_ctx.define(msg.as_bytes().to_vec().into_boxed_slice());

View File

@ -69,8 +69,6 @@ impl WriterRelocate {
/// Perform the collected relocations to be usable for JIT usage.
#[cfg(feature = "jit")]
pub(super) fn relocate_for_jit(mut self, jit_module: &cranelift_jit::JITModule) -> Vec<u8> {
use std::convert::TryInto;
for reloc in self.relocs.drain(..) {
match reloc.name {
super::DebugRelocName::Section(_) => unreachable!(),

View File

@ -10,7 +10,7 @@ use crate::prelude::*;
use rustc_index::vec::IndexVec;
use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{LabelValueLoc, StackSlots, ValueLabel, ValueLoc};
use cranelift_codegen::ir::{LabelValueLoc, ValueLabel};
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::ValueLocRange;
@ -67,7 +67,12 @@ impl<'tcx> DebugContext<'tcx> {
rustc_interface::util::version_str().unwrap_or("unknown version"),
cranelift_codegen::VERSION,
);
let comp_dir = tcx.sess.opts.working_dir.to_string_lossy(FileNameDisplayPreference::Remapped).into_owned();
let comp_dir = tcx
.sess
.opts
.working_dir
.to_string_lossy(FileNameDisplayPreference::Remapped)
.into_owned();
let (name, file_info) = match tcx.sess.local_crate_source_file.clone() {
Some(path) => {
let name = path.to_string_lossy().into_owned();
@ -250,7 +255,7 @@ impl<'tcx> DebugContext<'tcx> {
// FIXME make it more reliable and implement scopes before re-enabling this.
if false {
let value_labels_ranges = context.build_value_labels_ranges(isa).unwrap();
let value_labels_ranges = std::collections::HashMap::new(); // FIXME
for (local, _local_decl) in mir.local_decls.iter_enumerated() {
let ty = self.tcx.subst_and_normalize_erasing_regions(
@ -264,7 +269,6 @@ impl<'tcx> DebugContext<'tcx> {
self,
isa,
symbol,
context,
&local_map,
&value_labels_ranges,
Place { local, projection: ty::List::empty() },
@ -283,7 +287,6 @@ fn place_location<'tcx>(
debug_context: &mut DebugContext<'tcx>,
isa: &dyn TargetIsa,
symbol: usize,
context: &Context,
local_map: &IndexVec<mir::Local, CPlace<'tcx>>,
#[allow(rustc::default_hash_types)] value_labels_ranges: &std::collections::HashMap<
ValueLabel,
@ -306,12 +309,7 @@ fn place_location<'tcx>(
addend: i64::from(value_loc_range.start),
},
end: Address::Symbol { symbol, addend: i64::from(value_loc_range.end) },
data: translate_loc(
isa,
value_loc_range.loc,
&context.func.stack_slots,
)
.unwrap(),
data: translate_loc(isa, value_loc_range.loc).unwrap(),
})
.collect(),
);
@ -340,34 +338,14 @@ fn place_location<'tcx>(
AttributeValue::Exprloc(Expression::new())
// For PointerBase::Stack:
//AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot), &context.func.stack_slots).unwrap())
//AttributeValue::Exprloc(translate_loc(ValueLoc::Stack(*stack_slot)).unwrap())
}
}
}
// Adapted from https://github.com/CraneStation/wasmtime/blob/5a1845b4caf7a5dba8eda1fef05213a532ed4259/crates/debug/src/transform/expression.rs#L59-L137
fn translate_loc(
isa: &dyn TargetIsa,
loc: LabelValueLoc,
stack_slots: &StackSlots,
) -> Option<Expression> {
fn translate_loc(isa: &dyn TargetIsa, loc: LabelValueLoc) -> Option<Expression> {
match loc {
LabelValueLoc::ValueLoc(ValueLoc::Reg(reg)) => {
let machine_reg = isa.map_dwarf_register(reg).unwrap();
let mut expr = Expression::new();
expr.op_reg(gimli::Register(machine_reg));
Some(expr)
}
LabelValueLoc::ValueLoc(ValueLoc::Stack(ss)) => {
if let Some(ss_offset) = stack_slots[ss].offset {
let mut expr = Expression::new();
expr.op_breg(X86_64::RBP, i64::from(ss_offset) + 16);
Some(expr)
} else {
None
}
}
LabelValueLoc::ValueLoc(ValueLoc::Unassigned) => unreachable!(),
LabelValueLoc::Reg(reg) => {
let machine_reg = isa.map_regalloc_reg_to_dwarf(reg).unwrap();
let mut expr = Expression::new();

View File

@ -1,5 +1,3 @@
use std::convert::{TryFrom, TryInto};
use rustc_data_structures::fx::FxHashMap;
use cranelift_module::FuncId;

View File

@ -4,6 +4,7 @@
use std::path::PathBuf;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_metadata::EncodedMetadata;
@ -123,6 +124,7 @@ fn module_codegen(
backend_config.clone(),
module.isa(),
tcx.sess.opts.debuginfo != DebugInfo::None,
cgu_name,
);
super::predefine_mono_items(tcx, &mut module, &mono_items);
for (mono_item, _) in mono_items {
@ -277,7 +279,8 @@ pub(crate) fn run_aot(
let tmp_file =
tcx.output_filenames(()).temp_path(OutputType::Metadata, Some(&metadata_cgu_name));
let obj = crate::metadata::new_metadata_object(tcx, &metadata_cgu_name, &metadata);
let symbol_name = rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx);
let obj = create_compressed_metadata_file(tcx.sess, &metadata, &symbol_name);
if let Err(err) = std::fs::write(&tmp_file, obj) {
tcx.sess.fatal(&format!("error writing metadata object file: {}", err));

View File

@ -3,7 +3,7 @@
use std::cell::RefCell;
use std::ffi::CString;
use std::lazy::{Lazy, SyncOnceCell};
use std::lazy::SyncOnceCell;
use std::os::raw::{c_char, c_int};
use std::sync::{mpsc, Mutex};
@ -11,6 +11,7 @@ use cranelift_codegen::binemit::{NullStackMapSink, NullTrapSink};
use rustc_codegen_ssa::CrateInfo;
use rustc_middle::mir::mono::MonoItem;
use rustc_session::Session;
use rustc_span::Symbol;
use cranelift_jit::{JITBuilder, JITModule};
@ -23,7 +24,7 @@ struct JitState {
}
thread_local! {
static LAZY_JIT_STATE: RefCell<Option<JitState>> = RefCell::new(None);
static LAZY_JIT_STATE: RefCell<Option<JitState>> = const { RefCell::new(None) };
}
/// The Sender owned by the rustc thread
@ -50,12 +51,11 @@ impl UnsafeMessage {
fn send(self) -> Result<(), mpsc::SendError<UnsafeMessage>> {
thread_local! {
/// The Sender owned by the local thread
static LOCAL_MESSAGE_SENDER: Lazy<mpsc::Sender<UnsafeMessage>> = Lazy::new(||
static LOCAL_MESSAGE_SENDER: mpsc::Sender<UnsafeMessage> =
GLOBAL_MESSAGE_SENDER
.get().unwrap()
.lock().unwrap()
.clone()
);
.clone();
}
LOCAL_MESSAGE_SENDER.with(|sender| sender.send(self))
}
@ -76,7 +76,13 @@ fn create_jit_module<'tcx>(
jit_builder.symbols(imported_symbols);
let mut jit_module = JITModule::new(jit_builder);
let mut cx = crate::CodegenCx::new(tcx, backend_config.clone(), jit_module.isa(), false);
let mut cx = crate::CodegenCx::new(
tcx,
backend_config.clone(),
jit_module.isa(),
false,
Symbol::intern("dummy_cgu_name"),
);
crate::allocator::codegen(tcx, &mut jit_module, &mut cx.unwind_context);
crate::main_shim::maybe_create_entry_wrapper(
@ -246,7 +252,13 @@ fn jit_fn(instance_ptr: *const Instance<'static>, trampoline_ptr: *const u8) ->
jit_module.prepare_for_function_redefine(func_id).unwrap();
let mut cx = crate::CodegenCx::new(tcx, backend_config, jit_module.isa(), false);
let mut cx = crate::CodegenCx::new(
tcx,
backend_config,
jit_module.isa(),
false,
Symbol::intern("dummy_cgu_name"),
);
tcx.sess.time("codegen fn", || crate::base::codegen_fn(&mut cx, jit_module, instance));
assert!(cx.global_asm.is_empty());

View File

@ -6,6 +6,7 @@ use std::fmt::Write;
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_middle::mir::InlineAsmOperand;
use rustc_span::Symbol;
use rustc_target::asm::*;
pub(crate) fn codegen_inline_asm<'tcx>(
@ -17,10 +18,7 @@ pub(crate) fn codegen_inline_asm<'tcx>(
) {
// FIXME add .eh_frame unwind info directives
if template.is_empty() {
// Black box
return;
} else if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
let true_ = fx.bcx.ins().iconst(types::I32, 1);
fx.bcx.ins().trapnz(true_, TrapCode::User(1));
return;
@ -41,8 +39,10 @@ pub(crate) fn codegen_inline_asm<'tcx>(
assert_eq!(operands.len(), 4);
let (leaf, eax_place) = match operands[1] {
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
let reg = expect_reg(reg);
assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::ax));
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax))
);
(
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place.unwrap()),
@ -64,8 +64,10 @@ pub(crate) fn codegen_inline_asm<'tcx>(
};
let (sub_leaf, ecx_place) = match operands[2] {
InlineAsmOperand::InOut { reg, late: true, ref in_value, out_place } => {
let reg = expect_reg(reg);
assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::cx));
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::cx))
);
(
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
crate::base::codegen_place(fx, out_place.unwrap()),
@ -75,8 +77,10 @@ pub(crate) fn codegen_inline_asm<'tcx>(
};
let edx_place = match operands[3] {
InlineAsmOperand::Out { reg, late: true, place } => {
let reg = expect_reg(reg);
assert_eq!(reg, InlineAsmReg::X86(X86InlineAsmReg::dx));
assert_eq!(
reg,
InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::dx))
);
crate::base::codegen_place(fx, place.unwrap())
}
_ => unreachable!(),
@ -96,60 +100,59 @@ pub(crate) fn codegen_inline_asm<'tcx>(
crate::trap::trap_unimplemented(fx, "Alloca is not supported");
}
let mut slot_size = Size::from_bytes(0);
let mut clobbered_regs = Vec::new();
let mut inputs = Vec::new();
let mut outputs = Vec::new();
let mut new_slot = |reg_class: InlineAsmRegClass| {
let reg_size = reg_class
.supported_types(InlineAsmArch::X86_64)
.iter()
.map(|(ty, _)| ty.size())
.max()
.unwrap();
let align = rustc_target::abi::Align::from_bytes(reg_size.bytes()).unwrap();
slot_size = slot_size.align_to(align);
let offset = slot_size;
slot_size += reg_size;
offset
let mut asm_gen = InlineAssemblyGenerator {
tcx: fx.tcx,
arch: fx.tcx.sess.asm_arch.unwrap(),
template,
operands,
options,
registers: Vec::new(),
stack_slots_clobber: Vec::new(),
stack_slots_input: Vec::new(),
stack_slots_output: Vec::new(),
stack_slot_size: Size::from_bytes(0),
};
asm_gen.allocate_registers();
asm_gen.allocate_stack_slots();
// FIXME overlap input and output slots to save stack space
for operand in operands {
let inline_asm_index = fx.cx.inline_asm_index.get();
fx.cx.inline_asm_index.set(inline_asm_index + 1);
let asm_name = format!(
"__inline_asm_{}_n{}",
fx.cx.cgu_name.as_str().replace('.', "__").replace('-', "_"),
inline_asm_index
);
let generated_asm = asm_gen.generate_asm_wrapper(&asm_name);
fx.cx.global_asm.push_str(&generated_asm);
for (i, operand) in operands.iter().enumerate() {
match *operand {
InlineAsmOperand::In { reg, ref value } => {
let reg = expect_reg(reg);
clobbered_regs.push((reg, new_slot(reg.reg_class())));
InlineAsmOperand::In { reg: _, ref value } => {
inputs.push((
reg,
new_slot(reg.reg_class()),
asm_gen.stack_slots_input[i].unwrap(),
crate::base::codegen_operand(fx, value).load_scalar(fx),
));
}
InlineAsmOperand::Out { reg, late: _, place } => {
let reg = expect_reg(reg);
clobbered_regs.push((reg, new_slot(reg.reg_class())));
InlineAsmOperand::Out { reg: _, late: _, place } => {
if let Some(place) = place {
outputs.push((
reg,
new_slot(reg.reg_class()),
asm_gen.stack_slots_output[i].unwrap(),
crate::base::codegen_place(fx, place),
));
}
}
InlineAsmOperand::InOut { reg, late: _, ref in_value, out_place } => {
let reg = expect_reg(reg);
clobbered_regs.push((reg, new_slot(reg.reg_class())));
InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
inputs.push((
reg,
new_slot(reg.reg_class()),
asm_gen.stack_slots_input[i].unwrap(),
crate::base::codegen_operand(fx, in_value).load_scalar(fx),
));
if let Some(out_place) = out_place {
outputs.push((
reg,
new_slot(reg.reg_class()),
asm_gen.stack_slots_output[i].unwrap(),
crate::base::codegen_place(fx, out_place),
));
}
@ -160,110 +163,474 @@ pub(crate) fn codegen_inline_asm<'tcx>(
}
}
let inline_asm_index = fx.inline_asm_index;
fx.inline_asm_index += 1;
let asm_name = format!("{}__inline_asm_{}", fx.symbol_name, inline_asm_index);
let generated_asm = generate_asm_wrapper(
&asm_name,
InlineAsmArch::X86_64,
options,
template,
clobbered_regs,
&inputs,
&outputs,
);
fx.cx.global_asm.push_str(&generated_asm);
call_inline_asm(fx, &asm_name, slot_size, inputs, outputs);
call_inline_asm(fx, &asm_name, asm_gen.stack_slot_size, inputs, outputs);
}
fn generate_asm_wrapper(
asm_name: &str,
struct InlineAssemblyGenerator<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
arch: InlineAsmArch,
template: &'a [InlineAsmTemplatePiece],
operands: &'a [InlineAsmOperand<'tcx>],
options: InlineAsmOptions,
template: &[InlineAsmTemplatePiece],
clobbered_regs: Vec<(InlineAsmReg, Size)>,
inputs: &[(InlineAsmReg, Size, Value)],
outputs: &[(InlineAsmReg, Size, CPlace<'_>)],
) -> String {
let mut generated_asm = String::new();
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
writeln!(generated_asm, "{}:", asm_name).unwrap();
registers: Vec<Option<InlineAsmReg>>,
stack_slots_clobber: Vec<Option<Size>>,
stack_slots_input: Vec<Option<Size>>,
stack_slots_output: Vec<Option<Size>>,
stack_slot_size: Size,
}
generated_asm.push_str(".intel_syntax noprefix\n");
generated_asm.push_str(" push rbp\n");
generated_asm.push_str(" mov rbp,rdi\n");
impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
fn allocate_registers(&mut self) {
let sess = self.tcx.sess;
let map = allocatable_registers(
self.arch,
|feature| sess.target_features.contains(&Symbol::intern(feature)),
&sess.target,
);
let mut allocated = FxHashMap::<_, (bool, bool)>::default();
let mut regs = vec![None; self.operands.len()];
// Save clobbered registers
if !options.contains(InlineAsmOptions::NORETURN) {
// FIXME skip registers saved by the calling convention
for &(reg, offset) in &clobbered_regs {
save_register(&mut generated_asm, arch, reg, offset);
}
}
// Write input registers
for &(reg, offset, _value) in inputs {
restore_register(&mut generated_asm, arch, reg, offset);
}
if options.contains(InlineAsmOptions::ATT_SYNTAX) {
generated_asm.push_str(".att_syntax\n");
}
// The actual inline asm
for piece in template {
match piece {
InlineAsmTemplatePiece::String(s) => {
generated_asm.push_str(s);
// Add explicit registers to the allocated set.
for (i, operand) in self.operands.iter().enumerate() {
match *operand {
InlineAsmOperand::In { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => {
regs[i] = Some(reg);
allocated.entry(reg).or_default().0 = true;
}
InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::Reg(reg), late: true, ..
} => {
regs[i] = Some(reg);
allocated.entry(reg).or_default().1 = true;
}
InlineAsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(reg), .. }
| InlineAsmOperand::InOut { reg: InlineAsmRegOrRegClass::Reg(reg), .. } => {
regs[i] = Some(reg);
allocated.insert(reg, (true, true));
}
_ => (),
}
InlineAsmTemplatePiece::Placeholder { operand_idx: _, modifier: _, span: _ } => todo!(),
}
}
generated_asm.push('\n');
if options.contains(InlineAsmOptions::ATT_SYNTAX) {
generated_asm.push_str(".intel_syntax noprefix\n");
}
if !options.contains(InlineAsmOptions::NORETURN) {
// Read output registers
for &(reg, offset, _place) in outputs {
save_register(&mut generated_asm, arch, reg, offset);
}
// Restore clobbered registers
for &(reg, offset) in clobbered_regs.iter().rev() {
restore_register(&mut generated_asm, arch, reg, offset);
// Allocate out/inout/inlateout registers first because they are more constrained.
for (i, operand) in self.operands.iter().enumerate() {
match *operand {
InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::RegClass(class),
late: false,
..
}
| InlineAsmOperand::InOut {
reg: InlineAsmRegOrRegClass::RegClass(class), ..
} => {
let mut alloc_reg = None;
for &reg in &map[&class] {
let mut used = false;
reg.overlapping_regs(|r| {
if allocated.contains_key(&r) {
used = true;
}
});
if !used {
alloc_reg = Some(reg);
break;
}
}
let reg = alloc_reg.expect("cannot allocate registers");
regs[i] = Some(reg);
allocated.insert(reg, (true, true));
}
_ => (),
}
}
generated_asm.push_str(" pop rbp\n");
generated_asm.push_str(" ret\n");
} else {
generated_asm.push_str(" ud2\n");
// Allocate in/lateout.
for (i, operand) in self.operands.iter().enumerate() {
match *operand {
InlineAsmOperand::In { reg: InlineAsmRegOrRegClass::RegClass(class), .. } => {
let mut alloc_reg = None;
for &reg in &map[&class] {
let mut used = false;
reg.overlapping_regs(|r| {
if allocated.get(&r).copied().unwrap_or_default().0 {
used = true;
}
});
if !used {
alloc_reg = Some(reg);
break;
}
}
let reg = alloc_reg.expect("cannot allocate registers");
regs[i] = Some(reg);
allocated.entry(reg).or_default().0 = true;
}
InlineAsmOperand::Out {
reg: InlineAsmRegOrRegClass::RegClass(class),
late: true,
..
} => {
let mut alloc_reg = None;
for &reg in &map[&class] {
let mut used = false;
reg.overlapping_regs(|r| {
if allocated.get(&r).copied().unwrap_or_default().1 {
used = true;
}
});
if !used {
alloc_reg = Some(reg);
break;
}
}
let reg = alloc_reg.expect("cannot allocate registers");
regs[i] = Some(reg);
allocated.entry(reg).or_default().1 = true;
}
_ => (),
}
}
self.registers = regs;
}
generated_asm.push_str(".att_syntax\n");
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
generated_asm.push_str(".text\n");
generated_asm.push_str("\n\n");
fn allocate_stack_slots(&mut self) {
let mut slot_size = Size::from_bytes(0);
let mut slots_clobber = vec![None; self.operands.len()];
let mut slots_input = vec![None; self.operands.len()];
let mut slots_output = vec![None; self.operands.len()];
generated_asm
let new_slot_fn = |slot_size: &mut Size, reg_class: InlineAsmRegClass| {
let reg_size =
reg_class.supported_types(self.arch).iter().map(|(ty, _)| ty.size()).max().unwrap();
let align = rustc_target::abi::Align::from_bytes(reg_size.bytes()).unwrap();
let offset = slot_size.align_to(align);
*slot_size = offset + reg_size;
offset
};
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
// Allocate stack slots for saving clobbered registers
let abi_clobber = InlineAsmClobberAbi::parse(
self.arch,
|feature| self.tcx.sess.target_features.contains(&Symbol::intern(feature)),
&self.tcx.sess.target,
Symbol::intern("C"),
)
.unwrap()
.clobbered_regs();
for (i, reg) in self.registers.iter().enumerate().filter_map(|(i, r)| r.map(|r| (i, r))) {
let mut need_save = true;
// If the register overlaps with a register clobbered by function call, then
// we don't need to save it.
for r in abi_clobber {
r.overlapping_regs(|r| {
if r == reg {
need_save = false;
}
});
if !need_save {
break;
}
}
if need_save {
slots_clobber[i] = Some(new_slot(reg.reg_class()));
}
}
// Allocate stack slots for inout
for (i, operand) in self.operands.iter().enumerate() {
match *operand {
InlineAsmOperand::InOut { reg, out_place: Some(_), .. } => {
let slot = new_slot(reg.reg_class());
slots_input[i] = Some(slot);
slots_output[i] = Some(slot);
}
_ => (),
}
}
let slot_size_before_input = slot_size;
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
// Allocate stack slots for input
for (i, operand) in self.operands.iter().enumerate() {
match *operand {
InlineAsmOperand::In { reg, .. }
| InlineAsmOperand::InOut { reg, out_place: None, .. } => {
slots_input[i] = Some(new_slot(reg.reg_class()));
}
_ => (),
}
}
// Reset slot size to before input so that input and output operands can overlap
// and save some memory.
let slot_size_after_input = slot_size;
slot_size = slot_size_before_input;
let mut new_slot = |x| new_slot_fn(&mut slot_size, x);
// Allocate stack slots for output
for (i, operand) in self.operands.iter().enumerate() {
match *operand {
InlineAsmOperand::Out { reg, place: Some(_), .. } => {
slots_output[i] = Some(new_slot(reg.reg_class()));
}
_ => (),
}
}
slot_size = slot_size.max(slot_size_after_input);
self.stack_slots_clobber = slots_clobber;
self.stack_slots_input = slots_input;
self.stack_slots_output = slots_output;
self.stack_slot_size = slot_size;
}
fn generate_asm_wrapper(&self, asm_name: &str) -> String {
let mut generated_asm = String::new();
writeln!(generated_asm, ".globl {}", asm_name).unwrap();
writeln!(generated_asm, ".type {},@function", asm_name).unwrap();
writeln!(generated_asm, ".section .text.{},\"ax\",@progbits", asm_name).unwrap();
writeln!(generated_asm, "{}:", asm_name).unwrap();
let is_x86 = matches!(self.arch, InlineAsmArch::X86 | InlineAsmArch::X86_64);
if is_x86 {
generated_asm.push_str(".intel_syntax noprefix\n");
}
Self::prologue(&mut generated_asm, self.arch);
// Save clobbered registers
if !self.options.contains(InlineAsmOptions::NORETURN) {
for (reg, slot) in self
.registers
.iter()
.zip(self.stack_slots_clobber.iter().copied())
.filter_map(|(r, s)| r.zip(s))
{
Self::save_register(&mut generated_asm, self.arch, reg, slot);
}
}
// Write input registers
for (reg, slot) in self
.registers
.iter()
.zip(self.stack_slots_input.iter().copied())
.filter_map(|(r, s)| r.zip(s))
{
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
}
if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
generated_asm.push_str(".att_syntax\n");
}
// The actual inline asm
for piece in self.template {
match piece {
InlineAsmTemplatePiece::String(s) => {
generated_asm.push_str(s);
}
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier, span: _ } => {
if self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
generated_asm.push('%');
}
self.registers[*operand_idx]
.unwrap()
.emit(&mut generated_asm, self.arch, *modifier)
.unwrap();
}
}
}
generated_asm.push('\n');
if is_x86 && self.options.contains(InlineAsmOptions::ATT_SYNTAX) {
generated_asm.push_str(".intel_syntax noprefix\n");
}
if !self.options.contains(InlineAsmOptions::NORETURN) {
// Read output registers
for (reg, slot) in self
.registers
.iter()
.zip(self.stack_slots_output.iter().copied())
.filter_map(|(r, s)| r.zip(s))
{
Self::save_register(&mut generated_asm, self.arch, reg, slot);
}
// Restore clobbered registers
for (reg, slot) in self
.registers
.iter()
.zip(self.stack_slots_clobber.iter().copied())
.filter_map(|(r, s)| r.zip(s))
{
Self::restore_register(&mut generated_asm, self.arch, reg, slot);
}
Self::epilogue(&mut generated_asm, self.arch);
} else {
Self::epilogue_noreturn(&mut generated_asm, self.arch);
}
if is_x86 {
generated_asm.push_str(".att_syntax\n");
}
writeln!(generated_asm, ".size {name}, .-{name}", name = asm_name).unwrap();
generated_asm.push_str(".text\n");
generated_asm.push_str("\n\n");
generated_asm
}
fn prologue(generated_asm: &mut String, arch: InlineAsmArch) {
match arch {
InlineAsmArch::X86 => {
generated_asm.push_str(" push ebp\n");
generated_asm.push_str(" mov ebp,[esp+8]\n");
}
InlineAsmArch::X86_64 => {
generated_asm.push_str(" push rbp\n");
generated_asm.push_str(" mov rbp,rdi\n");
}
InlineAsmArch::RiscV32 => {
generated_asm.push_str(" addi sp, sp, -8\n");
generated_asm.push_str(" sw ra, 4(sp)\n");
generated_asm.push_str(" sw s0, 0(sp)\n");
generated_asm.push_str(" mv s0, a0\n");
}
InlineAsmArch::RiscV64 => {
generated_asm.push_str(" addi sp, sp, -16\n");
generated_asm.push_str(" sd ra, 8(sp)\n");
generated_asm.push_str(" sd s0, 0(sp)\n");
generated_asm.push_str(" mv s0, a0\n");
}
_ => unimplemented!("prologue for {:?}", arch),
}
}
fn epilogue(generated_asm: &mut String, arch: InlineAsmArch) {
match arch {
InlineAsmArch::X86 => {
generated_asm.push_str(" pop ebp\n");
generated_asm.push_str(" ret\n");
}
InlineAsmArch::X86_64 => {
generated_asm.push_str(" pop rbp\n");
generated_asm.push_str(" ret\n");
}
InlineAsmArch::RiscV32 => {
generated_asm.push_str(" lw s0, 0(sp)\n");
generated_asm.push_str(" lw ra, 4(sp)\n");
generated_asm.push_str(" addi sp, sp, 8\n");
generated_asm.push_str(" ret\n");
}
InlineAsmArch::RiscV64 => {
generated_asm.push_str(" ld s0, 0(sp)\n");
generated_asm.push_str(" ld ra, 8(sp)\n");
generated_asm.push_str(" addi sp, sp, 16\n");
generated_asm.push_str(" ret\n");
}
_ => unimplemented!("epilogue for {:?}", arch),
}
}
fn epilogue_noreturn(generated_asm: &mut String, arch: InlineAsmArch) {
match arch {
InlineAsmArch::X86 | InlineAsmArch::X86_64 => {
generated_asm.push_str(" ud2\n");
}
InlineAsmArch::RiscV32 | InlineAsmArch::RiscV64 => {
generated_asm.push_str(" ebreak\n");
}
_ => unimplemented!("epilogue_noreturn for {:?}", arch),
}
}
fn save_register(
generated_asm: &mut String,
arch: InlineAsmArch,
reg: InlineAsmReg,
offset: Size,
) {
match arch {
InlineAsmArch::X86 => {
write!(generated_asm, " mov [ebp+0x{:x}], ", offset.bytes()).unwrap();
reg.emit(generated_asm, InlineAsmArch::X86, None).unwrap();
generated_asm.push('\n');
}
InlineAsmArch::X86_64 => {
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
generated_asm.push('\n');
}
InlineAsmArch::RiscV32 => {
generated_asm.push_str(" sw ");
reg.emit(generated_asm, InlineAsmArch::RiscV32, None).unwrap();
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
}
InlineAsmArch::RiscV64 => {
generated_asm.push_str(" sd ");
reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
}
_ => unimplemented!("save_register for {:?}", arch),
}
}
fn restore_register(
generated_asm: &mut String,
arch: InlineAsmArch,
reg: InlineAsmReg,
offset: Size,
) {
match arch {
InlineAsmArch::X86 => {
generated_asm.push_str(" mov ");
reg.emit(generated_asm, InlineAsmArch::X86, None).unwrap();
writeln!(generated_asm, ", [ebp+0x{:x}]", offset.bytes()).unwrap();
}
InlineAsmArch::X86_64 => {
generated_asm.push_str(" mov ");
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
}
InlineAsmArch::RiscV32 => {
generated_asm.push_str(" lw ");
reg.emit(generated_asm, InlineAsmArch::RiscV32, None).unwrap();
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
}
InlineAsmArch::RiscV64 => {
generated_asm.push_str(" ld ");
reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
writeln!(generated_asm, ", 0x{:x}(s0)", offset.bytes()).unwrap();
}
_ => unimplemented!("restore_register for {:?}", arch),
}
}
}
fn call_inline_asm<'tcx>(
fx: &mut FunctionCx<'_, '_, 'tcx>,
asm_name: &str,
slot_size: Size,
inputs: Vec<(InlineAsmReg, Size, Value)>,
outputs: Vec<(InlineAsmReg, Size, CPlace<'tcx>)>,
inputs: Vec<(Size, Value)>,
outputs: Vec<(Size, CPlace<'tcx>)>,
) {
let stack_slot = fx.bcx.func.create_stack_slot(StackSlotData {
kind: StackSlotKind::ExplicitSlot,
offset: None,
size: u32::try_from(slot_size.bytes()).unwrap(),
});
if fx.clif_comments.enabled() {
@ -287,50 +654,16 @@ fn call_inline_asm<'tcx>(
fx.add_comment(inline_asm_func, asm_name);
}
for (_reg, offset, value) in inputs {
for (offset, value) in inputs {
fx.bcx.ins().stack_store(value, stack_slot, i32::try_from(offset.bytes()).unwrap());
}
let stack_slot_addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
fx.bcx.ins().call(inline_asm_func, &[stack_slot_addr]);
for (_reg, offset, place) in outputs {
for (offset, place) in outputs {
let ty = fx.clif_type(place.layout().ty).unwrap();
let value = fx.bcx.ins().stack_load(ty, stack_slot, i32::try_from(offset.bytes()).unwrap());
place.write_cvalue(fx, CValue::by_val(value, place.layout()));
}
}
fn expect_reg(reg_or_class: InlineAsmRegOrRegClass) -> InlineAsmReg {
match reg_or_class {
InlineAsmRegOrRegClass::Reg(reg) => reg,
InlineAsmRegOrRegClass::RegClass(class) => unimplemented!("{:?}", class),
}
}
fn save_register(generated_asm: &mut String, arch: InlineAsmArch, reg: InlineAsmReg, offset: Size) {
match arch {
InlineAsmArch::X86_64 => {
write!(generated_asm, " mov [rbp+0x{:x}], ", offset.bytes()).unwrap();
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
generated_asm.push('\n');
}
_ => unimplemented!("save_register for {:?}", arch),
}
}
fn restore_register(
generated_asm: &mut String,
arch: InlineAsmArch,
reg: InlineAsmReg,
offset: Size,
) {
match arch {
InlineAsmArch::X86_64 => {
generated_asm.push_str(" mov ");
reg.emit(generated_asm, InlineAsmArch::X86_64, None).unwrap();
writeln!(generated_asm, ", [rbp+0x{:x}]", offset.bytes()).unwrap();
}
_ => unimplemented!("restore_register for {:?}", arch),
}
}

View File

@ -503,10 +503,10 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
if intrinsic == sym::copy_nonoverlapping {
// FIXME emit_small_memcpy
fx.bcx.call_memcpy(fx.module.target_config(), dst, src, byte_amount);
fx.bcx.call_memcpy(fx.target_config, dst, src, byte_amount);
} else {
// FIXME emit_small_memmove
fx.bcx.call_memmove(fx.module.target_config(), dst, src, byte_amount);
fx.bcx.call_memmove(fx.target_config, dst, src, byte_amount);
}
};
// NOTE: the volatile variants have src and dst swapped
@ -522,10 +522,10 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
// FIXME make the copy actually volatile when using emit_small_mem{cpy,move}
if intrinsic == sym::volatile_copy_nonoverlapping_memory {
// FIXME emit_small_memcpy
fx.bcx.call_memcpy(fx.module.target_config(), dst, src, byte_amount);
fx.bcx.call_memcpy(fx.target_config, dst, src, byte_amount);
} else {
// FIXME emit_small_memmove
fx.bcx.call_memmove(fx.module.target_config(), dst, src, byte_amount);
fx.bcx.call_memmove(fx.target_config, dst, src, byte_amount);
}
};
size_of_val, <T> (c ptr) {
@ -673,7 +673,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
let dst_ptr = dst.load_scalar(fx);
// FIXME make the memset actually volatile when switching to emit_small_memset
// FIXME use emit_small_memset
fx.bcx.call_memset(fx.module.target_config(), dst_ptr, val, count);
fx.bcx.call_memset(fx.target_config, dst_ptr, val, count);
};
ctlz | ctlz_nonzero, <T> (v arg) {
// FIXME trap on `ctlz_nonzero` with zero arg.
@ -1067,7 +1067,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
kw.Try, (v f, v data, v _catch_fn) {
// FIXME once unwinding is supported, change this to actually catch panics
let f_sig = fx.bcx.func.import_signature(Signature {
call_conv: CallConv::triple_default(fx.triple()),
call_conv: fx.target_config.default_call_conv,
params: vec![AbiParam::new(fx.bcx.func.dfg.value_type(data))],
returns: vec![],
});

View File

@ -67,7 +67,34 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
_ if intrinsic.as_str().starts_with("simd_shuffle"), (c x, c y, o idx) {
validate_simd_type!(fx, intrinsic, span, x.layout().ty);
let n: u16 = intrinsic.as_str()["simd_shuffle".len()..].parse().unwrap();
// If this intrinsic is the older "simd_shuffleN" form, simply parse the integer.
// If there is no suffix, use the index array length.
let n: u16 = if intrinsic == sym::simd_shuffle {
// Make sure this is actually an array, since typeck only checks the length-suffixed
// version of this intrinsic.
let idx_ty = fx.monomorphize(idx.ty(fx.mir, fx.tcx));
match idx_ty.kind() {
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
len.try_eval_usize(fx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(|| {
span_bug!(span, "could not evaluate shuffle index array length")
}).try_into().unwrap()
}
_ => {
fx.tcx.sess.span_err(
span,
&format!(
"simd_shuffle index must be an array of `u32`, got `{}`",
idx_ty,
),
);
// Prevent verifier error
crate::trap::trap_unreachable(fx, "compilation should not have succeeded");
return;
}
}
} else {
intrinsic.as_str()["simd_shuffle".len()..].parse().unwrap()
};
assert_eq!(x.layout(), y.layout());
let layout = x.layout();
@ -378,27 +405,27 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
};
simd_reduce_min, (c v) {
// FIXME support floats
validate_simd_type!(fx, intrinsic, span, v.layout().ty);
simd_reduce(fx, v, None, ret, |fx, layout, a, b| {
let lt = fx.bcx.ins().icmp(if layout.ty.is_signed() {
IntCC::SignedLessThan
} else {
IntCC::UnsignedLessThan
}, a, b);
let lt = match layout.ty.kind() {
ty::Int(_) => fx.bcx.ins().icmp(IntCC::SignedLessThan, a, b),
ty::Uint(_) => fx.bcx.ins().icmp(IntCC::UnsignedLessThan, a, b),
ty::Float(_) => fx.bcx.ins().fcmp(FloatCC::LessThan, a, b),
_ => unreachable!(),
};
fx.bcx.ins().select(lt, a, b)
});
};
simd_reduce_max, (c v) {
// FIXME support floats
validate_simd_type!(fx, intrinsic, span, v.layout().ty);
simd_reduce(fx, v, None, ret, |fx, layout, a, b| {
let gt = fx.bcx.ins().icmp(if layout.ty.is_signed() {
IntCC::SignedGreaterThan
} else {
IntCC::UnsignedGreaterThan
}, a, b);
let gt = match layout.ty.kind() {
ty::Int(_) => fx.bcx.ins().icmp(IntCC::SignedGreaterThan, a, b),
ty::Uint(_) => fx.bcx.ins().icmp(IntCC::UnsignedGreaterThan, a, b),
ty::Float(_) => fx.bcx.ins().fcmp(FloatCC::GreaterThan, a, b),
_ => unreachable!(),
};
fx.bcx.ins().select(gt, a, b)
});
};

View File

@ -4,7 +4,6 @@
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]
extern crate snap;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_ast;
@ -26,6 +25,7 @@ extern crate rustc_target;
extern crate rustc_driver;
use std::any::Any;
use std::cell::Cell;
use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
@ -34,6 +34,7 @@ use rustc_metadata::EncodedMetadata;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_session::config::OutputFilenames;
use rustc_session::Session;
use rustc_span::Symbol;
use cranelift_codegen::isa::TargetIsa;
use cranelift_codegen::settings::{self, Configurable};
@ -59,7 +60,6 @@ mod inline_asm;
mod intrinsics;
mod linkage;
mod main_shim;
mod metadata;
mod num;
mod optimize;
mod pointer;
@ -71,9 +71,7 @@ mod value_and_place;
mod vtable;
mod prelude {
pub(crate) use std::convert::{TryFrom, TryInto};
pub(crate) use rustc_span::{Span, FileNameDisplayPreference};
pub(crate) use rustc_span::{FileNameDisplayPreference, Span};
pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
pub(crate) use rustc_middle::bug;
@ -125,9 +123,11 @@ impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
struct CodegenCx<'tcx> {
tcx: TyCtxt<'tcx>,
global_asm: String,
inline_asm_index: Cell<usize>,
cached_context: Context,
debug_context: Option<DebugContext<'tcx>>,
unwind_context: UnwindContext,
cgu_name: Symbol,
}
impl<'tcx> CodegenCx<'tcx> {
@ -136,6 +136,7 @@ impl<'tcx> CodegenCx<'tcx> {
backend_config: BackendConfig,
isa: &dyn TargetIsa,
debug_info: bool,
cgu_name: Symbol,
) -> Self {
assert_eq!(pointer_ty(tcx), isa.pointer_type());
@ -145,9 +146,11 @@ impl<'tcx> CodegenCx<'tcx> {
CodegenCx {
tcx,
global_asm: String::new(),
inline_asm_index: Cell::new(0),
cached_context: Context::new(),
debug_context,
unwind_context,
cgu_name,
}
}
}
@ -269,19 +272,16 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
let flags = settings::Flags::new(flags_builder);
let variant = cranelift_codegen::isa::BackendVariant::MachInst;
let isa_builder = match sess.opts.cg.target_cpu.as_deref() {
Some("native") => {
let builder = cranelift_native::builder_with_options(variant, true).unwrap();
let builder = cranelift_native::builder_with_options(true).unwrap();
builder
}
Some(value) => {
let mut builder =
cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant)
.unwrap_or_else(|err| {
sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
});
cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| {
sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
});
if let Err(_) = builder.enable(value) {
sess.fatal("the specified target cpu isn't currently supported by Cranelift.");
}
@ -289,10 +289,9 @@ fn build_isa(sess: &Session, backend_config: &BackendConfig) -> Box<dyn isa::Tar
}
None => {
let mut builder =
cranelift_codegen::isa::lookup_variant(target_triple.clone(), variant)
.unwrap_or_else(|err| {
sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
});
cranelift_codegen::isa::lookup(target_triple.clone()).unwrap_or_else(|err| {
sess.fatal(&format!("can't compile for {}: {}", target_triple, err));
});
if target_triple.architecture == target_lexicon::Architecture::X86_64 {
// Don't use "haswell" as the default, as it implies `has_lzcnt`.
// macOS CI is still at Ivy Bridge EP, so `lzcnt` is interpreted as `bsr`.

View File

@ -1,76 +0,0 @@
//! Writing of the rustc metadata for dylibs
use object::write::{Object, StandardSegment, Symbol, SymbolSection};
use object::{SectionKind, SymbolFlags, SymbolKind, SymbolScope};
use rustc_metadata::EncodedMetadata;
use rustc_middle::ty::TyCtxt;
// Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
pub(crate) fn new_metadata_object(
tcx: TyCtxt<'_>,
cgu_name: &str,
metadata: &EncodedMetadata,
) -> Vec<u8> {
use snap::write::FrameEncoder;
use std::io::Write;
let mut compressed = rustc_metadata::METADATA_HEADER.to_vec();
FrameEncoder::new(&mut compressed).write_all(metadata.raw_data()).unwrap();
let triple = crate::target_triple(tcx.sess);
let binary_format = match triple.binary_format {
target_lexicon::BinaryFormat::Elf => object::BinaryFormat::Elf,
target_lexicon::BinaryFormat::Coff => object::BinaryFormat::Coff,
target_lexicon::BinaryFormat::Macho => object::BinaryFormat::MachO,
binary_format => tcx.sess.fatal(&format!("binary format {} is unsupported", binary_format)),
};
let architecture = match triple.architecture {
target_lexicon::Architecture::Aarch64(_) => object::Architecture::Aarch64,
target_lexicon::Architecture::Arm(_) => object::Architecture::Arm,
target_lexicon::Architecture::Avr => object::Architecture::Avr,
target_lexicon::Architecture::Hexagon => object::Architecture::Hexagon,
target_lexicon::Architecture::Mips32(_) => object::Architecture::Mips,
target_lexicon::Architecture::Mips64(_) => object::Architecture::Mips64,
target_lexicon::Architecture::Msp430 => object::Architecture::Msp430,
target_lexicon::Architecture::Powerpc => object::Architecture::PowerPc,
target_lexicon::Architecture::Powerpc64 => object::Architecture::PowerPc64,
target_lexicon::Architecture::Powerpc64le => todo!(),
target_lexicon::Architecture::Riscv32(_) => object::Architecture::Riscv32,
target_lexicon::Architecture::Riscv64(_) => object::Architecture::Riscv64,
target_lexicon::Architecture::S390x => object::Architecture::S390x,
target_lexicon::Architecture::Sparc64 => object::Architecture::Sparc64,
target_lexicon::Architecture::Sparcv9 => object::Architecture::Sparc64,
target_lexicon::Architecture::X86_32(_) => object::Architecture::I386,
target_lexicon::Architecture::X86_64 => object::Architecture::X86_64,
architecture => {
tcx.sess.fatal(&format!("target architecture {:?} is unsupported", architecture,))
}
};
let endian = match triple.endianness().unwrap() {
target_lexicon::Endianness::Little => object::Endianness::Little,
target_lexicon::Endianness::Big => object::Endianness::Big,
};
let mut object = Object::new(binary_format, architecture, endian);
object.add_file_symbol(cgu_name.as_bytes().to_vec());
let segment = object.segment_name(StandardSegment::Data).to_vec();
let section_id = object.add_section(segment, b".rustc".to_vec(), SectionKind::Data);
let offset = object.append_section_data(section_id, &compressed, 1);
// For MachO and probably PE this is necessary to prevent the linker from throwing away the
// .rustc section. For ELF this isn't necessary, but it also doesn't harm.
object.add_symbol(Symbol {
name: rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx).into_bytes(),
value: offset,
size: compressed.len() as u64,
kind: SymbolKind::Data,
scope: SymbolScope::Dynamic,
weak: false,
section: SymbolSection::Section(section_id),
flags: SymbolFlags::None,
});
object.write().unwrap()
}

View File

@ -57,7 +57,7 @@ use std::io::Write;
use cranelift_codegen::{
entity::SecondaryMap,
ir::{entities::AnyEntity, function::DisplayFunctionAnnotations},
ir::entities::AnyEntity,
write::{FuncWriter, PlainWriter},
};
@ -129,7 +129,6 @@ impl FuncWriter for &'_ CommentWriter {
&mut self,
w: &mut dyn fmt::Write,
func: &Function,
reg_info: Option<&isa::RegInfo>,
) -> Result<bool, fmt::Error> {
for comment in &self.global_comments {
if !comment.is_empty() {
@ -142,7 +141,7 @@ impl FuncWriter for &'_ CommentWriter {
writeln!(w)?;
}
self.super_preamble(w, func, reg_info)
self.super_preamble(w, func)
}
fn write_entity_definition(
@ -165,11 +164,10 @@ impl FuncWriter for &'_ CommentWriter {
&mut self,
w: &mut dyn fmt::Write,
func: &Function,
isa: Option<&dyn isa::TargetIsa>,
block: Block,
indent: usize,
) -> fmt::Result {
PlainWriter.write_block_header(w, func, isa, block, indent)
PlainWriter.write_block_header(w, func, block, indent)
}
fn write_instruction(
@ -177,11 +175,10 @@ impl FuncWriter for &'_ CommentWriter {
w: &mut dyn fmt::Write,
func: &Function,
aliases: &SecondaryMap<Value, Vec<Value>>,
isa: Option<&dyn isa::TargetIsa>,
inst: Inst,
indent: usize,
) -> fmt::Result {
PlainWriter.write_instruction(w, func, aliases, isa, inst, indent)?;
PlainWriter.write_instruction(w, func, aliases, inst, indent)?;
if let Some(comment) = self.entity_comments.get(&inst.into()) {
writeln!(w, "; {}", comment.replace('\n', "\n; "))?;
}
@ -249,7 +246,6 @@ pub(crate) fn write_clif_file<'tcx>(
&mut clif_comments,
&mut clif,
&context.func,
&DisplayFunctionAnnotations { isa: Some(isa), value_ranges: None },
)
.unwrap();
@ -278,7 +274,6 @@ impl fmt::Debug for FunctionCx<'_, '_, '_> {
&mut &self.clif_comments,
&mut clif,
&self.bcx.func,
&DisplayFunctionAnnotations::default(),
)
.unwrap();
writeln!(f, "\n{}", clif)

View File

@ -9,7 +9,7 @@ fn codegen_print(fx: &mut FunctionCx<'_, '_, '_>, msg: &str) {
"puts",
Linkage::Import,
&Signature {
call_conv: CallConv::triple_default(fx.triple()),
call_conv: fx.target_config.default_call_conv,
params: vec![AbiParam::new(fx.pointer_type)],
returns: vec![AbiParam::new(types::I32)],
},

View File

@ -329,7 +329,6 @@ impl<'tcx> CPlace<'tcx> {
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
// specify stack slot alignment.
size: (u32::try_from(layout.size.bytes()).unwrap() + 15) / 16 * 16,
offset: None,
});
CPlace { inner: CPlaceInner::Addr(Pointer::stack_slot(stack_slot), None), layout }
}
@ -472,7 +471,6 @@ impl<'tcx> CPlace<'tcx> {
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
// specify stack slot alignment.
size: (src_ty.bytes() + 15) / 16 * 16,
offset: None,
});
let ptr = Pointer::stack_slot(stack_slot);
ptr.store(fx, data, MemFlags::trusted());
@ -512,6 +510,26 @@ impl<'tcx> CPlace<'tcx> {
let dst_layout = self.layout();
let to_ptr = match self.inner {
CPlaceInner::Var(_local, var) => {
if let ty::Array(element, len) = dst_layout.ty.kind() {
// Can only happen for vector types
let len =
u16::try_from(len.eval_usize(fx.tcx, ParamEnv::reveal_all())).unwrap();
let vector_ty = fx.clif_type(element).unwrap().by(len).unwrap();
let data = match from.0 {
CValueInner::ByRef(ptr, None) => {
let mut flags = MemFlags::new();
flags.set_notrap();
ptr.load(fx, vector_ty, flags)
}
CValueInner::ByVal(_)
| CValueInner::ByValPair(_, _)
| CValueInner::ByRef(_, Some(_)) => bug!("array should be ByRef"),
};
fx.bcx.def_var(var, data);
return;
}
let data = CValue(from.0, dst_layout).load_scalar(fx);
let dst_ty = fx.clif_type(self.layout().ty).unwrap();
transmute_value(fx, var, data, dst_ty);
@ -583,7 +601,7 @@ impl<'tcx> CPlace<'tcx> {
let src_align = src_layout.align.abi.bytes() as u8;
let dst_align = dst_layout.align.abi.bytes() as u8;
fx.bcx.emit_small_memory_copy(
fx.module.target_config(),
fx.target_config,
to_addr,
from_addr,
size,
@ -605,14 +623,39 @@ impl<'tcx> CPlace<'tcx> {
let layout = self.layout();
match self.inner {
CPlaceInner::Var(local, var) => {
if let Abi::Vector { .. } = layout.abi {
CPlaceInner::Var(local, var) => match layout.ty.kind() {
ty::Array(_, _) => {
// Can only happen for vector types
return CPlace {
inner: CPlaceInner::VarLane(local, var, field.as_u32().try_into().unwrap()),
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
};
}
}
ty::Adt(adt_def, substs) if layout.ty.is_simd() => {
let f0_ty = adt_def.non_enum_variant().fields[0].ty(fx.tcx, substs);
match f0_ty.kind() {
ty::Array(_, _) => {
assert_eq!(field.as_u32(), 0);
return CPlace {
inner: CPlaceInner::Var(local, var),
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
};
}
_ => {
return CPlace {
inner: CPlaceInner::VarLane(
local,
var,
field.as_u32().try_into().unwrap(),
),
layout: layout.field(fx, field.as_u32().try_into().unwrap()),
};
}
}
}
_ => {}
},
CPlaceInner::VarPair(local, var1, var2) => {
let layout = layout.field(&*fx, field.index());
@ -629,7 +672,12 @@ impl<'tcx> CPlace<'tcx> {
let (field_ptr, field_layout) = codegen_field(fx, base, extra, layout, field);
if field_layout.is_unsized() {
CPlace::for_ptr_with_extra(field_ptr, extra.unwrap(), field_layout)
if let ty::Foreign(_) = field_layout.ty.kind() {
assert!(extra.is_none());
CPlace::for_ptr(field_ptr, field_layout)
} else {
CPlace::for_ptr_with_extra(field_ptr, extra.unwrap(), field_layout)
}
} else {
CPlace::for_ptr(field_ptr, field_layout)
}

View File

@ -43,7 +43,9 @@ mod utils;
fn usage() {
eprintln!("Usage:");
eprintln!(" ./y.rs prepare");
eprintln!(" ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR]");
eprintln!(
" ./y.rs build [--debug] [--sysroot none|clif|llvm] [--target-dir DIR] [--no-unstable-features]"
);
}
macro_rules! arg_error {
@ -92,6 +94,7 @@ fn main() {
let mut target_dir = PathBuf::from("build");
let mut channel = "release";
let mut sysroot_kind = SysrootKind::Clif;
let mut use_unstable_features = true;
while let Some(arg) = args.next().as_deref() {
match arg {
"--target-dir" => {
@ -109,6 +112,7 @@ fn main() {
None => arg_error!("--sysroot requires argument"),
}
}
"--no-unstable-features" => use_unstable_features = false,
flag if flag.starts_with("-") => arg_error!("Unknown flag {}", flag),
arg => arg_error!("Unexpected argument {}", arg),
}
@ -141,7 +145,8 @@ fn main() {
process::exit(1);
}
let cg_clif_build_dir = build_backend::build_backend(channel, &host_triple);
let cg_clif_build_dir =
build_backend::build_backend(channel, &host_triple, use_unstable_features);
build_sysroot::build_sysroot(
channel,
sysroot_kind,