Merge pull request #313 from rust-lang/sync_from_rust_2023_08_12
Sync from rust 2023/08/12
This commit is contained in:
commit
2f11b37c80
4
.github/workflows/stdarch.yml
vendored
4
.github/workflows/stdarch.yml
vendored
@ -133,10 +133,10 @@ jobs:
|
|||||||
if: ${{ !matrix.cargo_runner }}
|
if: ${{ !matrix.cargo_runner }}
|
||||||
run: |
|
run: |
|
||||||
cd build_sysroot/sysroot_src/library/stdarch/
|
cd build_sysroot/sysroot_src/library/stdarch/
|
||||||
CHANNEL=release TARGET=x86_64-unknown-linux-gnu ../../../../cargo.sh test
|
CHANNEL=release TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test
|
||||||
|
|
||||||
- name: Run stdarch tests
|
- name: Run stdarch tests
|
||||||
if: ${{ matrix.cargo_runner }}
|
if: ${{ matrix.cargo_runner }}
|
||||||
run: |
|
run: |
|
||||||
cd build_sysroot/sysroot_src/library/stdarch/
|
cd build_sysroot/sysroot_src/library/stdarch/
|
||||||
STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu ../../../../cargo.sh test -- --skip rtm --skip tbm --skip sse4a
|
STDARCH_TEST_EVERYTHING=1 CHANNEL=release CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER="${{ matrix.cargo_runner }}" TARGET=x86_64-unknown-linux-gnu CG_RUSTFLAGS="-Ainternal_features" ../../../../cargo.sh test -- --skip rtm --skip tbm --skip sse4a
|
||||||
|
61
Cargo.lock
generated
61
Cargo.lock
generated
@ -11,18 +11,18 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.79"
|
version = "1.0.79"
|
||||||
@ -58,12 +58,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "1.9.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
|
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||||
dependencies = [
|
|
||||||
"instant",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fm"
|
name = "fm"
|
||||||
@ -77,7 +74,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gccjit"
|
name = "gccjit"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
source = "git+https://github.com/antoyo/gccjit.rs#61d8d55c894bd462ee66c096cc31157a44a9f869"
|
source = "git+https://github.com/antoyo/gccjit.rs#814eea1a0a098d08a113794225cad301622fd7b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gccjit_sys",
|
"gccjit_sys",
|
||||||
]
|
]
|
||||||
@ -85,7 +82,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "gccjit_sys"
|
name = "gccjit_sys"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
source = "git+https://github.com/antoyo/gccjit.rs#61d8d55c894bd462ee66c096cc31157a44a9f869"
|
source = "git+https://github.com/antoyo/gccjit.rs#814eea1a0a098d08a113794225cad301622fd7b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
@ -105,26 +102,6 @@ version = "0.3.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "instant"
|
|
||||||
version = "0.1.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "io-lifetimes"
|
|
||||||
version = "1.0.11"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi",
|
|
||||||
"libc",
|
|
||||||
"windows-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lang_tester"
|
name = "lang_tester"
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
@ -149,9 +126,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.3.8"
|
version = "0.4.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
|
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
@ -175,7 +152,7 @@ version = "0.3.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -207,13 +184,12 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.37.22"
|
version = "0.38.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
|
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags 2.4.0",
|
||||||
"errno",
|
"errno",
|
||||||
"io-lifetimes",
|
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
@ -236,11 +212,10 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.6.0"
|
version = "3.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
|
checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
|
@ -28,6 +28,8 @@ gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
|
|||||||
#gccjit = { path = "../gccjit.rs" }
|
#gccjit = { path = "../gccjit.rs" }
|
||||||
|
|
||||||
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
||||||
|
# TODO(antoyo): make tempfile optional.
|
||||||
|
tempfile = "3.7.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
lang_tester = "0.3.9"
|
lang_tester = "0.3.9"
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
authors = ["bjorn3 <bjorn3@users.noreply.github.com>"]
|
authors = ["bjorn3 <bjorn3@users.noreply.github.com>"]
|
||||||
name = "sysroot"
|
name = "sysroot"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
core = { path = "./sysroot_src/library/core" }
|
core = { path = "./sysroot_src/library/core" }
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
|
#![feature(start, core_intrinsics, alloc_error_handler, lang_items)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
extern crate alloc_system;
|
extern crate alloc_system;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#[cfg(any(target_arch = "x86",
|
#[cfg(any(target_arch = "x86",
|
||||||
target_arch = "arm",
|
target_arch = "arm",
|
||||||
target_arch = "mips",
|
target_arch = "mips",
|
||||||
|
target_arch = "mips32r6",
|
||||||
target_arch = "powerpc",
|
target_arch = "powerpc",
|
||||||
target_arch = "powerpc64"))]
|
target_arch = "powerpc64"))]
|
||||||
const MIN_ALIGN: usize = 8;
|
const MIN_ALIGN: usize = 8;
|
||||||
@ -17,6 +18,7 @@ const MIN_ALIGN: usize = 8;
|
|||||||
target_arch = "aarch64",
|
target_arch = "aarch64",
|
||||||
target_arch = "loongarch64",
|
target_arch = "loongarch64",
|
||||||
target_arch = "mips64",
|
target_arch = "mips64",
|
||||||
|
target_arch = "mips64r6",
|
||||||
target_arch = "s390x",
|
target_arch = "s390x",
|
||||||
target_arch = "sparc64"))]
|
target_arch = "sparc64"))]
|
||||||
const MIN_ALIGN: usize = 16;
|
const MIN_ALIGN: usize = 16;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
|
#![feature(arbitrary_self_types, unsize, coerce_unsized, dispatch_from_dyn)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
ops::{Deref, CoerceUnsized, DispatchFromDyn},
|
ops::{Deref, CoerceUnsized, DispatchFromDyn},
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
thread_local
|
thread_local
|
||||||
)]
|
)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code, internal_features)]
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
unsafe extern "C" fn _Unwind_Resume() {
|
unsafe extern "C" fn _Unwind_Resume() {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
extern_types, thread_local
|
extern_types, thread_local
|
||||||
)]
|
)]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
#![allow(dead_code, non_camel_case_types)]
|
#![allow(dead_code, internal_features, non_camel_case_types)]
|
||||||
|
|
||||||
extern crate mini_core;
|
extern crate mini_core;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#![feature(start, core_intrinsics, lang_items)]
|
#![feature(start, core_intrinsics, lang_items)]
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#[link(name = "c")]
|
#[link(name = "c")]
|
||||||
extern {}
|
extern {}
|
||||||
|
@ -67,3 +67,6 @@ tests/ui/issues/issue-29948.rs
|
|||||||
tests/ui/panic-while-printing.rs
|
tests/ui/panic-while-printing.rs
|
||||||
tests/ui/enum-discriminant/get_discr.rs
|
tests/ui/enum-discriminant/get_discr.rs
|
||||||
tests/ui/panics/nested_panic_caught.rs
|
tests/ui/panics/nested_panic_caught.rs
|
||||||
|
tests/ui/simd/intrinsic/generic-bswap-byte.rs
|
||||||
|
tests/ui/const_prop/ice-issue-111353.rs
|
||||||
|
tests/ui/process/println-with-broken-pipe.rs
|
||||||
|
57
messages.ftl
57
messages.ftl
@ -1,63 +1,6 @@
|
|||||||
codegen_gcc_invalid_minimum_alignment =
|
codegen_gcc_invalid_minimum_alignment =
|
||||||
invalid minimum global alignment: {$err}
|
invalid minimum global alignment: {$err}
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_basic_integer =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_expected_signed_unsigned =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected element type `{$elem_ty}` of vector type `{$vec_ty}` to be a signed or unsigned integer type
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_expected_simd =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected SIMD {$expected_ty} type, found non-SIMD `{$found_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_inserted_type =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_invalid_bitmask =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_invalid_float_vector =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$elem_ty}` of floating-point vector `{$vec_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_mask_type =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_mismatched_lengths =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_not_float =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: `{$ty}` is not a floating-point type
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_return_element =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_return_integer_type =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_return_length =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_return_length_input_type =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_return_type =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_simd_shuffle =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_unrecognized =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_unsupported_cast =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_unsupported_element =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}`
|
|
||||||
|
|
||||||
codegen_gcc_invalid_monomorphization_unsupported_operation =
|
|
||||||
invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
|
|
||||||
|
|
||||||
codegen_gcc_lto_not_supported =
|
codegen_gcc_lto_not_supported =
|
||||||
LTO is not supported. You may get a linker error.
|
LTO is not supported. You may get a linker error.
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2023-06-19"
|
channel = "nightly-2023-08-12"
|
||||||
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
components = ["rust-src", "rustc-dev", "llvm-tools-preview"]
|
||||||
|
@ -26,8 +26,8 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam
|
|||||||
if kind == AllocatorKind::Default {
|
if kind == AllocatorKind::Default {
|
||||||
for method in ALLOCATOR_METHODS {
|
for method in ALLOCATOR_METHODS {
|
||||||
let mut types = Vec::with_capacity(method.inputs.len());
|
let mut types = Vec::with_capacity(method.inputs.len());
|
||||||
for ty in method.inputs.iter() {
|
for input in method.inputs.iter() {
|
||||||
match *ty {
|
match input.ty {
|
||||||
AllocatorTy::Layout => {
|
AllocatorTy::Layout => {
|
||||||
types.push(usize);
|
types.push(usize);
|
||||||
types.push(usize);
|
types.push(usize);
|
||||||
|
13
src/base.rs
13
src/base.rs
@ -6,8 +6,10 @@ use std::time::Instant;
|
|||||||
use gccjit::{
|
use gccjit::{
|
||||||
Context,
|
Context,
|
||||||
FunctionType,
|
FunctionType,
|
||||||
GlobalKind, TargetInfo,
|
GlobalKind,
|
||||||
};
|
};
|
||||||
|
#[cfg(feature="master")]
|
||||||
|
use gccjit::TargetInfo;
|
||||||
use rustc_middle::dep_graph;
|
use rustc_middle::dep_graph;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature="master")]
|
||||||
@ -20,6 +22,8 @@ use rustc_codegen_ssa::traits::DebugInfoMethods;
|
|||||||
use rustc_session::config::DebugInfo;
|
use rustc_session::config::DebugInfo;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
|
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
use crate::TargetInfo;
|
||||||
use crate::GccContext;
|
use crate::GccContext;
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
@ -144,6 +148,9 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Arc<
|
|||||||
if env::var("CG_GCCJIT_DUMP_RTL").as_deref() == Ok("1") {
|
if env::var("CG_GCCJIT_DUMP_RTL").as_deref() == Ok("1") {
|
||||||
context.add_command_line_option("-fdump-rtl-vregs");
|
context.add_command_line_option("-fdump-rtl-vregs");
|
||||||
}
|
}
|
||||||
|
if env::var("CG_GCCJIT_DUMP_RTL_ALL").as_deref() == Ok("1") {
|
||||||
|
context.add_command_line_option("-fdump-rtl-all");
|
||||||
|
}
|
||||||
if env::var("CG_GCCJIT_DUMP_TREE_ALL").as_deref() == Ok("1") {
|
if env::var("CG_GCCJIT_DUMP_TREE_ALL").as_deref() == Ok("1") {
|
||||||
context.add_command_line_option("-fdump-tree-all");
|
context.add_command_line_option("-fdump-tree-all");
|
||||||
}
|
}
|
||||||
@ -168,8 +175,8 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Arc<
|
|||||||
let cx = CodegenCx::new(&context, cgu, tcx, target_info.supports_128bit_int());
|
let cx = CodegenCx::new(&context, cgu, tcx, target_info.supports_128bit_int());
|
||||||
|
|
||||||
let mono_items = cgu.items_in_deterministic_order(tcx);
|
let mono_items = cgu.items_in_deterministic_order(tcx);
|
||||||
for &(mono_item, (linkage, visibility)) in &mono_items {
|
for &(mono_item, data) in &mono_items {
|
||||||
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
|
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... and now that we have everything pre-defined, fill out those definitions.
|
// ... and now that we have everything pre-defined, fill out those definitions.
|
||||||
|
@ -27,7 +27,6 @@ use rustc_codegen_ssa::traits::{
|
|||||||
BaseTypeMethods,
|
BaseTypeMethods,
|
||||||
BuilderMethods,
|
BuilderMethods,
|
||||||
ConstMethods,
|
ConstMethods,
|
||||||
DerivedTypeMethods,
|
|
||||||
LayoutTypeMethods,
|
LayoutTypeMethods,
|
||||||
HasCodegen,
|
HasCodegen,
|
||||||
OverflowOp,
|
OverflowOp,
|
||||||
@ -248,16 +247,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_store(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>) -> RValue<'gcc> {
|
fn check_store(&mut self, val: RValue<'gcc>, ptr: RValue<'gcc>) -> RValue<'gcc> {
|
||||||
let dest_ptr_ty = self.cx.val_ty(ptr).make_pointer(); // TODO(antoyo): make sure make_pointer() is okay here.
|
|
||||||
let stored_ty = self.cx.val_ty(val);
|
let stored_ty = self.cx.val_ty(val);
|
||||||
let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
|
let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
|
||||||
|
self.bitcast(ptr, stored_ptr_ty)
|
||||||
if dest_ptr_ty == stored_ptr_ty {
|
|
||||||
ptr
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.bitcast(ptr, stored_ptr_ty)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_func(&self) -> Function<'gcc> {
|
pub fn current_func(&self) -> Function<'gcc> {
|
||||||
@ -501,7 +493,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature="master"))]
|
#[cfg(not(feature="master"))]
|
||||||
fn invoke(&mut self, typ: Type<'gcc>, fn_attrs: &CodegenFnAttrs, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> {
|
fn invoke(&mut self, typ: Type<'gcc>, fn_attrs: Option<&CodegenFnAttrs>, fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> {
|
||||||
let call_site = self.call(typ, fn_attrs, None, func, args, None);
|
let call_site = self.call(typ, fn_attrs, None, func, args, None);
|
||||||
let condition = self.context.new_rvalue_from_int(self.bool_type, 1);
|
let condition = self.context.new_rvalue_from_int(self.bool_type, 1);
|
||||||
self.llbb().end_with_conditional(None, condition, then, catch);
|
self.llbb().end_with_conditional(None, condition, then, catch);
|
||||||
@ -917,7 +909,9 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
.add_eval(None, self.context.new_call(None, atomic_store, &[ptr, value, ordering]));
|
.add_eval(None, self.context.new_call(None, atomic_store, &[ptr, value, ordering]));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gep(&mut self, _typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> {
|
fn gep(&mut self, typ: Type<'gcc>, ptr: RValue<'gcc>, indices: &[RValue<'gcc>]) -> RValue<'gcc> {
|
||||||
|
// NOTE: due to opaque pointers now being used, we need to cast here.
|
||||||
|
let ptr = self.context.new_cast(None, ptr, typ.make_pointer());
|
||||||
let ptr_type = ptr.get_type();
|
let ptr_type = ptr.get_type();
|
||||||
let mut pointee_type = ptr.get_type();
|
let mut pointee_type = ptr.get_type();
|
||||||
// NOTE: we cannot use array indexing here like in inbounds_gep because array indexing is
|
// NOTE: we cannot use array indexing here like in inbounds_gep because array indexing is
|
||||||
|
@ -17,8 +17,8 @@ use crate::context::CodegenCx;
|
|||||||
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
|
pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>) -> Function<'gcc> {
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
|
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
assert!(!instance.substs.has_escaping_bound_vars());
|
assert!(!instance.args.has_escaping_bound_vars());
|
||||||
|
|
||||||
let sym = tcx.symbol_name(instance).name;
|
let sym = tcx.symbol_name(instance).name;
|
||||||
|
|
||||||
@ -100,7 +100,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
|
|||||||
// whether we are sharing generics or not. The important thing here is
|
// whether we are sharing generics or not. The important thing here is
|
||||||
// that the visibility we apply to the declaration is the same one that
|
// that the visibility we apply to the declaration is the same one that
|
||||||
// has been applied to the definition (wherever that definition may be).
|
// has been applied to the definition (wherever that definition may be).
|
||||||
let is_generic = instance.substs.non_erasable_generics().next().is_some();
|
let is_generic = instance.args.non_erasable_generics().next().is_some();
|
||||||
|
|
||||||
if is_generic {
|
if is_generic {
|
||||||
// This is a monomorphization. Its expected visibility depends
|
// This is a monomorphization. Its expected visibility depends
|
||||||
|
@ -16,6 +16,10 @@ use crate::context::CodegenCx;
|
|||||||
use crate::type_of::LayoutGccExt;
|
use crate::type_of::LayoutGccExt;
|
||||||
|
|
||||||
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
||||||
|
pub fn const_ptrcast(&self, val: RValue<'gcc>, ty: Type<'gcc>) -> RValue<'gcc> {
|
||||||
|
self.context.new_cast(None, val, ty)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn const_bytes(&self, bytes: &[u8]) -> RValue<'gcc> {
|
pub fn const_bytes(&self, bytes: &[u8]) -> RValue<'gcc> {
|
||||||
bytes_in_context(self, bytes)
|
bytes_in_context(self, bytes)
|
||||||
}
|
}
|
||||||
@ -242,10 +246,6 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||||||
const_alloc_to_gcc(self, alloc)
|
const_alloc_to_gcc(self, alloc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn const_ptrcast(&self, val: RValue<'gcc>, ty: Type<'gcc>) -> RValue<'gcc> {
|
|
||||||
self.context.new_cast(None, val, ty)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
|
fn const_bitcast(&self, value: RValue<'gcc>, typ: Type<'gcc>) -> RValue<'gcc> {
|
||||||
if value.get_type() == self.bool_type.make_pointer() {
|
if value.get_type() == self.bool_type.make_pointer() {
|
||||||
if let Some(pointee) = typ.get_pointee() {
|
if let Some(pointee) = typ.get_pointee() {
|
||||||
|
@ -476,7 +476,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
|
||||||
if let LayoutError::SizeOverflow(_) = err {
|
if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
|
||||||
self.sess().emit_fatal(respan(span, err.into_diagnostic()))
|
self.sess().emit_fatal(respan(span, err.into_diagnostic()))
|
||||||
} else {
|
} else {
|
||||||
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
|
||||||
|
@ -1,69 +1,11 @@
|
|||||||
use gccjit::RValue;
|
use rustc_codegen_ssa::traits::CoverageInfoBuilderMethods;
|
||||||
use rustc_codegen_ssa::traits::{CoverageInfoBuilderMethods, CoverageInfoMethods};
|
use rustc_middle::mir::Coverage;
|
||||||
use rustc_hir::def_id::DefId;
|
|
||||||
use rustc_middle::mir::coverage::{
|
|
||||||
CodeRegion,
|
|
||||||
CounterValueReference,
|
|
||||||
ExpressionOperandId,
|
|
||||||
InjectedExpressionId,
|
|
||||||
Op,
|
|
||||||
};
|
|
||||||
use rustc_middle::ty::Instance;
|
use rustc_middle::ty::Instance;
|
||||||
|
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::context::CodegenCx;
|
|
||||||
|
|
||||||
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
impl<'a, 'gcc, 'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
||||||
fn set_function_source_hash(
|
fn add_coverage(&mut self, _instance: Instance<'tcx>, _coverage: &Coverage) {
|
||||||
&mut self,
|
|
||||||
_instance: Instance<'tcx>,
|
|
||||||
_function_source_hash: u64,
|
|
||||||
) -> bool {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_coverage_counter(&mut self, _instance: Instance<'tcx>, _id: CounterValueReference, _region: CodeRegion) -> bool {
|
|
||||||
// TODO(antoyo)
|
// TODO(antoyo)
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_coverage_counter_expression(&mut self, _instance: Instance<'tcx>, _id: InjectedExpressionId, _lhs: ExpressionOperandId, _op: Op, _rhs: ExpressionOperandId, _region: Option<CodeRegion>) -> bool {
|
|
||||||
// TODO(antoyo)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_coverage_unreachable(&mut self, _instance: Instance<'tcx>, _region: CodeRegion) -> bool {
|
|
||||||
// TODO(antoyo)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'gcc, 'tcx> CoverageInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|
||||||
fn coverageinfo_finalize(&self) {
|
|
||||||
// TODO(antoyo)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_pgo_func_name_var(&self, _instance: Instance<'tcx>) -> RValue<'gcc> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Functions with MIR-based coverage are normally codegenned _only_ if
|
|
||||||
/// called. LLVM coverage tools typically expect every function to be
|
|
||||||
/// defined (even if unused), with at least one call to LLVM intrinsic
|
|
||||||
/// `instrprof.increment`.
|
|
||||||
///
|
|
||||||
/// Codegen a small function that will never be called, with one counter
|
|
||||||
/// that will never be incremented.
|
|
||||||
///
|
|
||||||
/// For used/called functions, the coverageinfo was already added to the
|
|
||||||
/// `function_coverage_map` (keyed by function `Instance`) during codegen.
|
|
||||||
/// But in this case, since the unused function was _not_ previously
|
|
||||||
/// codegenned, collect the coverage `CodeRegion`s from the MIR and add
|
|
||||||
/// them. The first `CodeRegion` is used to add a single counter, with the
|
|
||||||
/// same counter ID used in the injected `instrprof.increment` intrinsic
|
|
||||||
/// call. Since the function is never called, all other `CodeRegion`s can be
|
|
||||||
/// added as `unreachable_region`s.
|
|
||||||
fn define_unused_fn(&self, _def_id: DefId) {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
198
src/errors.rs
198
src/errors.rs
@ -1,7 +1,6 @@
|
|||||||
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
|
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
|
||||||
use rustc_macros::Diagnostic;
|
use rustc_macros::Diagnostic;
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_span::Span;
|
||||||
use rustc_span::{Span, Symbol};
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
struct ExitCode(Option<i32>);
|
struct ExitCode(Option<i32>);
|
||||||
@ -16,201 +15,6 @@ impl IntoDiagnosticArg for ExitCode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_basic_integer, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationBasicInteger<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_invalid_float_vector, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationInvalidFloatVector<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub elem_ty: &'a str,
|
|
||||||
pub vec_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_not_float, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationNotFloat<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_unrecognized, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationUnrecognized {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_expected_signed_unsigned, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationExpectedSignedUnsigned<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub elem_ty: Ty<'a>,
|
|
||||||
pub vec_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_unsupported_element, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationUnsupportedElement<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub elem_ty: Ty<'a>,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_invalid_bitmask, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationInvalidBitmask<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub ty: Ty<'a>,
|
|
||||||
pub expected_int_bits: u64,
|
|
||||||
pub expected_bytes: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_simd_shuffle, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationSimdShuffle<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_expected_simd, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationExpectedSimd<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub position: &'a str,
|
|
||||||
pub found_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_mask_type, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationMaskType<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_return_length, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationReturnLength<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_len: u64,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
pub out_len: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_return_length_input_type, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationReturnLengthInputType<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_len: u64,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
pub out_len: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_return_element, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationReturnElement<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_elem: Ty<'a>,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
pub out_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_return_type, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationReturnType<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_elem: Ty<'a>,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_inserted_type, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationInsertedType<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_elem: Ty<'a>,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub out_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_return_integer_type, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationReturnIntegerType<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
pub out_ty: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_mismatched_lengths, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationMismatchedLengths {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub m_len: u64,
|
|
||||||
pub v_len: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_unsupported_cast, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationUnsupportedCast<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub in_elem: Ty<'a>,
|
|
||||||
pub ret_ty: Ty<'a>,
|
|
||||||
pub out_elem: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
|
||||||
#[diag(codegen_gcc_invalid_monomorphization_unsupported_operation, code = "E0511")]
|
|
||||||
pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> {
|
|
||||||
#[primary_span]
|
|
||||||
pub span: Span,
|
|
||||||
pub name: Symbol,
|
|
||||||
pub in_ty: Ty<'a>,
|
|
||||||
pub in_elem: Ty<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(codegen_gcc_lto_not_supported)]
|
#[diag(codegen_gcc_lto_not_supported)]
|
||||||
pub(crate) struct LTONotSupported;
|
pub(crate) struct LTONotSupported;
|
||||||
|
@ -546,7 +546,12 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn gcc_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
|
pub fn gcc_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
|
||||||
if self.is_native_int_type_or_bool(typ) {
|
if typ.is_u128(self) {
|
||||||
|
// FIXME(antoyo): libgccjit cannot create 128-bit values yet.
|
||||||
|
let num = self.context.new_rvalue_from_long(self.u64_type, int as i64);
|
||||||
|
self.gcc_int_cast(num, typ)
|
||||||
|
}
|
||||||
|
else if self.is_native_int_type_or_bool(typ) {
|
||||||
self.context.new_rvalue_from_long(typ, u64::try_from(int).expect("u64::try_from") as i64)
|
self.context.new_rvalue_from_long(typ, u64::try_from(int).expect("u64::try_from") as i64)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -572,6 +577,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if typ.is_i128(self) {
|
else if typ.is_i128(self) {
|
||||||
|
// FIXME(antoyo): libgccjit cannot create 128-bit values yet.
|
||||||
let num = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64);
|
let num = self.context.new_rvalue_from_long(self.u64_type, num as u64 as i64);
|
||||||
self.gcc_int_cast(num, typ)
|
self.gcc_int_cast(num, typ)
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,10 @@ use rustc_codegen_ssa::base::wants_msvc_seh;
|
|||||||
use rustc_codegen_ssa::common::IntPredicate;
|
use rustc_codegen_ssa::common::IntPredicate;
|
||||||
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
||||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||||
use rustc_codegen_ssa::traits::{ArgAbiMethods, BaseTypeMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods};
|
use rustc_codegen_ssa::traits::{ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods};
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature="master")]
|
||||||
use rustc_codegen_ssa::traits::{DerivedTypeMethods, MiscMethods};
|
use rustc_codegen_ssa::traits::{BaseTypeMethods, MiscMethods};
|
||||||
|
use rustc_codegen_ssa::errors::InvalidMonomorphization;
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::ty::{self, Instance, Ty};
|
use rustc_middle::ty::{self, Instance, Ty};
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
@ -31,7 +32,6 @@ use crate::abi::FnAbiGccExt;
|
|||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::common::{SignType, TypeReflection};
|
use crate::common::{SignType, TypeReflection};
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
use crate::errors::InvalidMonomorphizationBasicInteger;
|
|
||||||
use crate::type_of::LayoutGccExt;
|
use crate::type_of::LayoutGccExt;
|
||||||
use crate::intrinsic::simd::generic_simd_intrinsic;
|
use crate::intrinsic::simd::generic_simd_intrinsic;
|
||||||
|
|
||||||
@ -92,8 +92,8 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
let callee_ty = instance.ty(tcx, ty::ParamEnv::reveal_all());
|
||||||
|
|
||||||
let (def_id, substs) = match *callee_ty.kind() {
|
let (def_id, fn_args) = match *callee_ty.kind() {
|
||||||
ty::FnDef(def_id, substs) => (def_id, substs),
|
ty::FnDef(def_id, fn_args) => (def_id, fn_args),
|
||||||
_ => bug!("expected fn item type, found {}", callee_ty),
|
_ => bug!("expected fn item type, found {}", callee_ty),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
let mut ptr = args[0].immediate();
|
let mut ptr = args[0].immediate();
|
||||||
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
if let PassMode::Cast(ty, _) = &fn_abi.ret.mode {
|
||||||
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
ptr = self.pointercast(ptr, self.type_ptr_to(ty.gcc_type(self)));
|
||||||
@ -256,7 +256,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
tcx.sess.emit_err(InvalidMonomorphizationBasicInteger { span, name, ty });
|
tcx.sess.emit_err(InvalidMonomorphization::BasicIntegerType { span, name, ty });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
|
|
||||||
sym::raw_eq => {
|
sym::raw_eq => {
|
||||||
use rustc_target::abi::Abi::*;
|
use rustc_target::abi::Abi::*;
|
||||||
let tp_ty = substs.type_at(0);
|
let tp_ty = fn_args.type_at(0);
|
||||||
let layout = self.layout_of(tp_ty).layout;
|
let layout = self.layout_of(tp_ty).layout;
|
||||||
let _use_integer_compare = match layout.abi() {
|
let _use_integer_compare = match layout.abi() {
|
||||||
Scalar(_) | ScalarPair(_, _) => true,
|
Scalar(_) | ScalarPair(_, _) => true,
|
||||||
@ -302,6 +302,21 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sym::compare_bytes => {
|
||||||
|
let a = args[0].immediate();
|
||||||
|
let b = args[1].immediate();
|
||||||
|
let n = args[2].immediate();
|
||||||
|
|
||||||
|
let void_ptr_type = self.context.new_type::<*const ()>();
|
||||||
|
let a_ptr = self.bitcast(a, void_ptr_type);
|
||||||
|
let b_ptr = self.bitcast(b, void_ptr_type);
|
||||||
|
|
||||||
|
// Here we assume that the `memcmp` provided by the target is a NOP for size 0.
|
||||||
|
let builtin = self.context.get_builtin_function("memcmp");
|
||||||
|
let cmp = self.context.new_call(None, builtin, &[a_ptr, b_ptr, n]);
|
||||||
|
self.sext(cmp, self.type_ix(32))
|
||||||
|
}
|
||||||
|
|
||||||
sym::black_box => {
|
sym::black_box => {
|
||||||
args[0].val.store(self, result);
|
args[0].val.store(self, result);
|
||||||
|
|
||||||
@ -1147,19 +1162,19 @@ fn get_rust_try_fn<'a, 'gcc, 'tcx>(cx: &'a CodegenCx<'gcc, 'tcx>, codegen: &mut
|
|||||||
|
|
||||||
// Define the type up front for the signature of the rust_try function.
|
// Define the type up front for the signature of the rust_try function.
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
let i8p = tcx.mk_mut_ptr(tcx.types.i8);
|
let i8p = Ty::new_mut_ptr(tcx,tcx.types.i8);
|
||||||
// `unsafe fn(*mut i8) -> ()`
|
// `unsafe fn(*mut i8) -> ()`
|
||||||
let try_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
let try_fn_ty = Ty::new_fn_ptr(tcx,ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
iter::once(i8p),
|
iter::once(i8p),
|
||||||
tcx.mk_unit(),
|
Ty::new_unit(tcx,),
|
||||||
false,
|
false,
|
||||||
rustc_hir::Unsafety::Unsafe,
|
rustc_hir::Unsafety::Unsafe,
|
||||||
Abi::Rust,
|
Abi::Rust,
|
||||||
)));
|
)));
|
||||||
// `unsafe fn(*mut i8, *mut i8) -> ()`
|
// `unsafe fn(*mut i8, *mut i8) -> ()`
|
||||||
let catch_fn_ty = tcx.mk_fn_ptr(ty::Binder::dummy(tcx.mk_fn_sig(
|
let catch_fn_ty = Ty::new_fn_ptr(tcx,ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
[i8p, i8p].iter().cloned(),
|
[i8p, i8p].iter().cloned(),
|
||||||
tcx.mk_unit(),
|
Ty::new_unit(tcx,),
|
||||||
false,
|
false,
|
||||||
rustc_hir::Unsafety::Unsafe,
|
rustc_hir::Unsafety::Unsafe,
|
||||||
Abi::Rust,
|
Abi::Rust,
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#[cfg(feature="master")]
|
|
||||||
use gccjit::{ComparisonOp, UnaryOp};
|
|
||||||
use gccjit::ToRValue;
|
use gccjit::ToRValue;
|
||||||
use gccjit::{BinaryOp, RValue, Type};
|
use gccjit::{BinaryOp, RValue, Type};
|
||||||
|
#[cfg(feature = "master")]
|
||||||
|
use gccjit::{ComparisonOp, UnaryOp};
|
||||||
|
|
||||||
use rustc_codegen_ssa::base::compare_simd_types;
|
use rustc_codegen_ssa::base::compare_simd_types;
|
||||||
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
use rustc_codegen_ssa::errors::ExpectedPointerMutability;
|
use rustc_codegen_ssa::errors::ExpectedPointerMutability;
|
||||||
use rustc_codegen_ssa::errors::InvalidMonomorphization;
|
use rustc_codegen_ssa::errors::InvalidMonomorphization;
|
||||||
use rustc_codegen_ssa::mir::operand::OperandRef;
|
use rustc_codegen_ssa::mir::operand::OperandRef;
|
||||||
@ -19,21 +19,8 @@ use rustc_span::{sym, Span, Symbol};
|
|||||||
use rustc_target::abi::Align;
|
use rustc_target::abi::Align;
|
||||||
|
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
#[cfg(feature="master")]
|
|
||||||
use crate::errors::{InvalidMonomorphizationExpectedSignedUnsigned, InvalidMonomorphizationInsertedType};
|
|
||||||
use crate::errors::{
|
|
||||||
InvalidMonomorphizationExpectedSimd,
|
|
||||||
InvalidMonomorphizationInvalidBitmask,
|
|
||||||
InvalidMonomorphizationInvalidFloatVector, InvalidMonomorphizationMaskType,
|
|
||||||
InvalidMonomorphizationMismatchedLengths, InvalidMonomorphizationNotFloat,
|
|
||||||
InvalidMonomorphizationReturnElement, InvalidMonomorphizationReturnIntegerType,
|
|
||||||
InvalidMonomorphizationReturnLength, InvalidMonomorphizationReturnLengthInputType,
|
|
||||||
InvalidMonomorphizationReturnType, InvalidMonomorphizationSimdShuffle,
|
|
||||||
InvalidMonomorphizationUnrecognized, InvalidMonomorphizationUnsupportedElement,
|
|
||||||
InvalidMonomorphizationUnsupportedOperation,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
||||||
bx: &mut Builder<'a, 'gcc, 'tcx>,
|
bx: &mut Builder<'a, 'gcc, 'tcx>,
|
||||||
@ -59,16 +46,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
macro_rules! require_simd {
|
macro_rules! require_simd {
|
||||||
($ty: expr, $position: expr) => {
|
($ty: expr, $diag: expr) => {
|
||||||
require!(
|
require!($ty.is_simd(), $diag)
|
||||||
$ty.is_simd(),
|
|
||||||
InvalidMonomorphizationExpectedSimd {
|
|
||||||
span,
|
|
||||||
name,
|
|
||||||
position: $position,
|
|
||||||
found_ty: $ty
|
|
||||||
}
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +57,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
let arg_tys = sig.inputs();
|
let arg_tys = sig.inputs();
|
||||||
|
|
||||||
if name == sym::simd_select_bitmask {
|
if name == sym::simd_select_bitmask {
|
||||||
require_simd!(arg_tys[1], "argument");
|
require_simd!(
|
||||||
|
arg_tys[1],
|
||||||
|
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
|
||||||
|
);
|
||||||
let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
let (len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||||
|
|
||||||
let expected_int_bits = (len.max(8) - 1).next_power_of_two();
|
let expected_int_bits = (len.max(8) - 1).next_power_of_two();
|
||||||
@ -99,10 +81,10 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty));
|
let ptr = bx.pointercast(place.llval, bx.cx.type_ptr_to(int_ty));
|
||||||
bx.load(int_ty, ptr, Align::ONE)
|
bx.load(int_ty, ptr, Align::ONE)
|
||||||
}
|
}
|
||||||
_ => return_error!(InvalidMonomorphizationInvalidBitmask {
|
_ => return_error!(InvalidMonomorphization::InvalidBitmask {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
ty: mask_ty,
|
mask_ty,
|
||||||
expected_int_bits,
|
expected_int_bits,
|
||||||
expected_bytes
|
expected_bytes
|
||||||
}),
|
}),
|
||||||
@ -116,7 +98,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
// NOTE: since the arguments can be vectors of floats, make sure the mask is a vector of
|
// NOTE: since the arguments can be vectors of floats, make sure the mask is a vector of
|
||||||
// integer.
|
// integer.
|
||||||
let mask_element_type = bx.type_ix(arg1_element_type.get_size() as u64 * 8);
|
let mask_element_type = bx.type_ix(arg1_element_type.get_size() as u64 * 8);
|
||||||
let vector_mask_type = bx.context.new_vector_type(mask_element_type, arg1_vector_type.get_num_units() as u64);
|
let vector_mask_type =
|
||||||
|
bx.context.new_vector_type(mask_element_type, arg1_vector_type.get_num_units() as u64);
|
||||||
|
|
||||||
let mut elements = vec![];
|
let mut elements = vec![];
|
||||||
let one = bx.context.new_rvalue_one(mask.get_type());
|
let one = bx.context.new_rvalue_one(mask.get_type());
|
||||||
@ -131,7 +114,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// every intrinsic below takes a SIMD vector as its first argument
|
// every intrinsic below takes a SIMD vector as its first argument
|
||||||
require_simd!(arg_tys[0], "input");
|
require_simd!(arg_tys[0], InvalidMonomorphization::SimdInput { span, name, ty: arg_tys[0] });
|
||||||
let in_ty = arg_tys[0];
|
let in_ty = arg_tys[0];
|
||||||
|
|
||||||
let comparison = match name {
|
let comparison = match name {
|
||||||
@ -146,12 +129,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
|
|
||||||
let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx());
|
let (in_len, in_elem) = arg_tys[0].simd_size_and_type(bx.tcx());
|
||||||
if let Some(cmp_op) = comparison {
|
if let Some(cmp_op) = comparison {
|
||||||
require_simd!(ret_ty, "return");
|
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||||
|
|
||||||
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
||||||
require!(
|
require!(
|
||||||
in_len == out_len,
|
in_len == out_len,
|
||||||
InvalidMonomorphizationReturnLengthInputType {
|
InvalidMonomorphization::ReturnLengthInputType {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
in_len,
|
in_len,
|
||||||
@ -162,7 +145,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
);
|
);
|
||||||
require!(
|
require!(
|
||||||
bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
|
bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
|
||||||
InvalidMonomorphizationReturnIntegerType { span, name, ret_ty, out_ty }
|
InvalidMonomorphization::ReturnIntegerType { span, name, ret_ty, out_ty }
|
||||||
);
|
);
|
||||||
|
|
||||||
let arg1 = args[0].immediate();
|
let arg1 = args[0].immediate();
|
||||||
@ -170,48 +153,34 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
// compare them as equal, so bitcast.
|
// compare them as equal, so bitcast.
|
||||||
// FIXME(antoyo): allow comparing vector types as equal in libgccjit.
|
// FIXME(antoyo): allow comparing vector types as equal in libgccjit.
|
||||||
let arg2 = bx.context.new_bitcast(None, args[1].immediate(), arg1.get_type());
|
let arg2 = bx.context.new_bitcast(None, args[1].immediate(), arg1.get_type());
|
||||||
return Ok(compare_simd_types(
|
return Ok(compare_simd_types(bx, arg1, arg2, in_elem, llret_ty, cmp_op));
|
||||||
bx,
|
|
||||||
arg1,
|
|
||||||
arg2,
|
|
||||||
in_elem,
|
|
||||||
llret_ty,
|
|
||||||
cmp_op,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(stripped) = name.as_str().strip_prefix("simd_shuffle") {
|
if name == sym::simd_shuffle {
|
||||||
let n: u64 = if stripped.is_empty() {
|
// Make sure this is actually an array, since typeck only checks the length-suffixed
|
||||||
// Make sure this is actually an array, since typeck only checks the length-suffixed
|
// version of this intrinsic.
|
||||||
// version of this intrinsic.
|
let n: u64 = match args[2].layout.ty.kind() {
|
||||||
match args[2].layout.ty.kind() {
|
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
||||||
ty::Array(ty, len) if matches!(ty.kind(), ty::Uint(ty::UintTy::U32)) => {
|
len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
|
||||||
len.try_eval_target_usize(bx.cx.tcx, ty::ParamEnv::reveal_all()).unwrap_or_else(
|
|| span_bug!(span, "could not evaluate shuffle index array length"),
|
||||||
|| span_bug!(span, "could not evaluate shuffle index array length"),
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
_ => return_error!(InvalidMonomorphizationSimdShuffle {
|
|
||||||
span,
|
|
||||||
name,
|
|
||||||
ty: args[2].layout.ty
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
} else {
|
_ => return_error!(InvalidMonomorphization::SimdShuffle {
|
||||||
stripped.parse().unwrap_or_else(|_| {
|
span,
|
||||||
span_bug!(span, "bad `simd_shuffle` instruction only caught in codegen?")
|
name,
|
||||||
})
|
ty: args[2].layout.ty
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||||
require_simd!(ret_ty, "return");
|
|
||||||
|
|
||||||
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
|
||||||
require!(
|
require!(
|
||||||
out_len == n,
|
out_len == n,
|
||||||
InvalidMonomorphizationReturnLength { span, name, in_len: n, ret_ty, out_len }
|
InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
|
||||||
);
|
);
|
||||||
require!(
|
require!(
|
||||||
in_elem == out_ty,
|
in_elem == out_ty,
|
||||||
InvalidMonomorphizationReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
|
InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
|
||||||
);
|
);
|
||||||
|
|
||||||
let vector = args[2].immediate();
|
let vector = args[2].immediate();
|
||||||
@ -223,7 +192,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
if name == sym::simd_insert {
|
if name == sym::simd_insert {
|
||||||
require!(
|
require!(
|
||||||
in_elem == arg_tys[2],
|
in_elem == arg_tys[2],
|
||||||
InvalidMonomorphizationInsertedType { span, name, in_elem, in_ty, out_ty: arg_tys[2] }
|
InvalidMonomorphization::InsertedType {
|
||||||
|
span,
|
||||||
|
name,
|
||||||
|
in_elem,
|
||||||
|
in_ty,
|
||||||
|
out_ty: arg_tys[2]
|
||||||
|
}
|
||||||
);
|
);
|
||||||
let vector = args[0].immediate();
|
let vector = args[0].immediate();
|
||||||
let index = args[1].immediate();
|
let index = args[1].immediate();
|
||||||
@ -240,7 +215,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
if name == sym::simd_extract {
|
if name == sym::simd_extract {
|
||||||
require!(
|
require!(
|
||||||
ret_ty == in_elem,
|
ret_ty == in_elem,
|
||||||
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
|
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||||
);
|
);
|
||||||
let vector = args[0].immediate();
|
let vector = args[0].immediate();
|
||||||
return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
|
return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
|
||||||
@ -249,26 +224,29 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
if name == sym::simd_select {
|
if name == sym::simd_select {
|
||||||
let m_elem_ty = in_elem;
|
let m_elem_ty = in_elem;
|
||||||
let m_len = in_len;
|
let m_len = in_len;
|
||||||
require_simd!(arg_tys[1], "argument");
|
require_simd!(
|
||||||
|
arg_tys[1],
|
||||||
|
InvalidMonomorphization::SimdArgument { span, name, ty: arg_tys[1] }
|
||||||
|
);
|
||||||
let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||||
require!(
|
require!(
|
||||||
m_len == v_len,
|
m_len == v_len,
|
||||||
InvalidMonomorphizationMismatchedLengths { span, name, m_len, v_len }
|
InvalidMonomorphization::MismatchedLengths { span, name, m_len, v_len }
|
||||||
);
|
);
|
||||||
match m_elem_ty.kind() {
|
match m_elem_ty.kind() {
|
||||||
ty::Int(_) => {}
|
ty::Int(_) => {}
|
||||||
_ => return_error!(InvalidMonomorphizationMaskType { span, name, ty: m_elem_ty }),
|
_ => return_error!(InvalidMonomorphization::MaskType { span, name, ty: m_elem_ty }),
|
||||||
}
|
}
|
||||||
return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate()));
|
return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
if name == sym::simd_cast || name == sym::simd_as {
|
if name == sym::simd_cast || name == sym::simd_as {
|
||||||
require_simd!(ret_ty, "return");
|
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||||
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
|
||||||
require!(
|
require!(
|
||||||
in_len == out_len,
|
in_len == out_len,
|
||||||
InvalidMonomorphizationReturnLengthInputType {
|
InvalidMonomorphization::ReturnLengthInputType {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
in_len,
|
in_len,
|
||||||
@ -288,19 +266,17 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
Unsupported,
|
Unsupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
let in_style =
|
let in_style = match in_elem.kind() {
|
||||||
match in_elem.kind() {
|
ty::Int(_) | ty::Uint(_) => Style::Int,
|
||||||
ty::Int(_) | ty::Uint(_) => Style::Int,
|
ty::Float(_) => Style::Float,
|
||||||
ty::Float(_) => Style::Float,
|
_ => Style::Unsupported,
|
||||||
_ => Style::Unsupported,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
let out_style =
|
let out_style = match out_elem.kind() {
|
||||||
match out_elem.kind() {
|
ty::Int(_) | ty::Uint(_) => Style::Int,
|
||||||
ty::Int(_) | ty::Uint(_) => Style::Int,
|
ty::Float(_) => Style::Float,
|
||||||
ty::Float(_) => Style::Float,
|
_ => Style::Unsupported,
|
||||||
_ => Style::Unsupported,
|
};
|
||||||
};
|
|
||||||
|
|
||||||
match (in_style, out_style) {
|
match (in_style, out_style) {
|
||||||
(Style::Unsupported, Style::Unsupported) => {
|
(Style::Unsupported, Style::Unsupported) => {
|
||||||
@ -315,7 +291,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
out_elem
|
out_elem
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
_ => return Ok(bx.context.convert_vector(None, args[0].immediate(), llret_ty)),
|
_ => return Ok(bx.context.convert_vector(None, args[0].immediate(), llret_ty)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +305,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
})*
|
})*
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem })
|
return_error!(InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem })
|
||||||
})*
|
})*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,10 +339,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
|
|
||||||
let mut shift = 0;
|
let mut shift = 0;
|
||||||
for i in 0..in_len {
|
for i in 0..in_len {
|
||||||
let elem = bx.extract_element(vector, bx.context.new_rvalue_from_int(bx.int_type, i as i32));
|
let elem =
|
||||||
|
bx.extract_element(vector, bx.context.new_rvalue_from_int(bx.int_type, i as i32));
|
||||||
let shifted = elem >> sign_shift;
|
let shifted = elem >> sign_shift;
|
||||||
let masked = shifted & one;
|
let masked = shifted & one;
|
||||||
result = result | (bx.context.new_cast(None, masked, result_type) << bx.context.new_rvalue_from_int(result_type, shift));
|
result = result
|
||||||
|
| (bx.context.new_cast(None, masked, result_type)
|
||||||
|
<< bx.context.new_rvalue_from_int(result_type, shift));
|
||||||
shift += 1;
|
shift += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,46 +394,50 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
return Err(());
|
return Err(());
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
let (elem_ty_str, elem_ty) =
|
let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() {
|
||||||
if let ty::Float(f) = in_elem.kind() {
|
let elem_ty = bx.cx.type_float_from_ty(*f);
|
||||||
let elem_ty = bx.cx.type_float_from_ty(*f);
|
match f.bit_width() {
|
||||||
match f.bit_width() {
|
32 => ("f", elem_ty),
|
||||||
32 => ("f", elem_ty),
|
64 => ("", elem_ty),
|
||||||
64 => ("", elem_ty),
|
_ => {
|
||||||
_ => {
|
return_error!(InvalidMonomorphization::FloatingPointVector {
|
||||||
return_error!(InvalidMonomorphizationInvalidFloatVector { span, name, elem_ty: f.name_str(), vec_ty: in_ty });
|
span,
|
||||||
}
|
name,
|
||||||
|
f_ty: *f,
|
||||||
|
in_ty
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty });
|
return_error!(InvalidMonomorphization::FloatingPointType { span, name, in_ty });
|
||||||
};
|
};
|
||||||
|
|
||||||
let vec_ty = bx.cx.type_vector(elem_ty, in_len);
|
let vec_ty = bx.cx.type_vector(elem_ty, in_len);
|
||||||
|
|
||||||
let intr_name =
|
let intr_name = match name {
|
||||||
match name {
|
sym::simd_ceil => "ceil",
|
||||||
sym::simd_ceil => "ceil",
|
sym::simd_fabs => "fabs", // TODO(antoyo): pand with 170141183420855150465331762880109871103
|
||||||
sym::simd_fabs => "fabs", // TODO(antoyo): pand with 170141183420855150465331762880109871103
|
sym::simd_fcos => "cos",
|
||||||
sym::simd_fcos => "cos",
|
sym::simd_fexp2 => "exp2",
|
||||||
sym::simd_fexp2 => "exp2",
|
sym::simd_fexp => "exp",
|
||||||
sym::simd_fexp => "exp",
|
sym::simd_flog10 => "log10",
|
||||||
sym::simd_flog10 => "log10",
|
sym::simd_flog2 => "log2",
|
||||||
sym::simd_flog2 => "log2",
|
sym::simd_flog => "log",
|
||||||
sym::simd_flog => "log",
|
sym::simd_floor => "floor",
|
||||||
sym::simd_floor => "floor",
|
sym::simd_fma => "fma",
|
||||||
sym::simd_fma => "fma",
|
sym::simd_fpowi => "__builtin_powi",
|
||||||
sym::simd_fpowi => "__builtin_powi",
|
sym::simd_fpow => "pow",
|
||||||
sym::simd_fpow => "pow",
|
sym::simd_fsin => "sin",
|
||||||
sym::simd_fsin => "sin",
|
sym::simd_fsqrt => "sqrt",
|
||||||
sym::simd_fsqrt => "sqrt",
|
sym::simd_round => "round",
|
||||||
sym::simd_round => "round",
|
sym::simd_trunc => "trunc",
|
||||||
sym::simd_trunc => "trunc",
|
_ => return_error!(InvalidMonomorphization::UnrecognizedIntrinsic { span, name }),
|
||||||
_ => return_error!(InvalidMonomorphizationUnrecognized { span, name })
|
};
|
||||||
};
|
|
||||||
let builtin_name = format!("{}{}", intr_name, elem_ty_str);
|
let builtin_name = format!("{}{}", intr_name, elem_ty_str);
|
||||||
let funcs = bx.cx.functions.borrow();
|
let funcs = bx.cx.functions.borrow();
|
||||||
let function = funcs.get(&builtin_name).unwrap_or_else(|| panic!("unable to find builtin function {}", builtin_name));
|
let function = funcs
|
||||||
|
.get(&builtin_name)
|
||||||
|
.unwrap_or_else(|| panic!("unable to find builtin function {}", builtin_name));
|
||||||
|
|
||||||
// TODO(antoyo): add platform-specific behavior here for architectures that have these
|
// TODO(antoyo): add platform-specific behavior here for architectures that have these
|
||||||
// intrinsics as instructions (for instance, gpus)
|
// intrinsics as instructions (for instance, gpus)
|
||||||
@ -500,8 +483,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
|
return simd_simple_float_intrinsic(name, in_elem, in_ty, in_len, bx, span, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
fn vector_ty<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, elem_ty: Ty<'tcx>, vec_len: u64) -> Type<'gcc> {
|
fn vector_ty<'gcc, 'tcx>(
|
||||||
|
cx: &CodegenCx<'gcc, 'tcx>,
|
||||||
|
elem_ty: Ty<'tcx>,
|
||||||
|
vec_len: u64,
|
||||||
|
) -> Type<'gcc> {
|
||||||
// FIXME: use cx.layout_of(ty).llvm_type() ?
|
// FIXME: use cx.layout_of(ty).llvm_type() ?
|
||||||
let elem_ty = match *elem_ty.kind() {
|
let elem_ty = match *elem_ty.kind() {
|
||||||
ty::Int(v) => cx.type_int_from_ty(v),
|
ty::Int(v) => cx.type_int_from_ty(v),
|
||||||
@ -512,15 +499,22 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
cx.type_vector(elem_ty, vec_len)
|
cx.type_vector(elem_ty, vec_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
fn gather<'a, 'gcc, 'tcx>(default: RValue<'gcc>, pointers: RValue<'gcc>, mask: RValue<'gcc>, pointer_count: usize, bx: &mut Builder<'a, 'gcc, 'tcx>, in_len: u64, underlying_ty: Ty<'tcx>, invert: bool) -> RValue<'gcc> {
|
fn gather<'a, 'gcc, 'tcx>(
|
||||||
let vector_type =
|
default: RValue<'gcc>,
|
||||||
if pointer_count > 1 {
|
pointers: RValue<'gcc>,
|
||||||
bx.context.new_vector_type(bx.usize_type, in_len)
|
mask: RValue<'gcc>,
|
||||||
}
|
pointer_count: usize,
|
||||||
else {
|
bx: &mut Builder<'a, 'gcc, 'tcx>,
|
||||||
vector_ty(bx, underlying_ty, in_len)
|
in_len: u64,
|
||||||
};
|
underlying_ty: Ty<'tcx>,
|
||||||
|
invert: bool,
|
||||||
|
) -> RValue<'gcc> {
|
||||||
|
let vector_type = if pointer_count > 1 {
|
||||||
|
bx.context.new_vector_type(bx.usize_type, in_len)
|
||||||
|
} else {
|
||||||
|
vector_ty(bx, underlying_ty, in_len)
|
||||||
|
};
|
||||||
let elem_type = vector_type.dyncast_vector().expect("vector type").get_element_type();
|
let elem_type = vector_type.dyncast_vector().expect("vector type").get_element_type();
|
||||||
|
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
@ -551,13 +545,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
|
|
||||||
if invert {
|
if invert {
|
||||||
bx.shuffle_vector(vector, default, mask)
|
bx.shuffle_vector(vector, default, mask)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
bx.shuffle_vector(default, vector, mask)
|
bx.shuffle_vector(default, vector, mask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
if name == sym::simd_gather {
|
if name == sym::simd_gather {
|
||||||
// simd_gather(values: <N x T>, pointers: <N x *_ T>,
|
// simd_gather(values: <N x T>, pointers: <N x *_ T>,
|
||||||
// mask: <N x i{M}>) -> <N x T>
|
// mask: <N x i{M}>) -> <N x T>
|
||||||
@ -566,10 +559,16 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
// * M: any integer width is supported, will be truncated to i1
|
// * M: any integer width is supported, will be truncated to i1
|
||||||
|
|
||||||
// All types must be simd vector types
|
// All types must be simd vector types
|
||||||
require_simd!(in_ty, "first");
|
require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
|
||||||
require_simd!(arg_tys[1], "second");
|
require_simd!(
|
||||||
require_simd!(arg_tys[2], "third");
|
arg_tys[1],
|
||||||
require_simd!(ret_ty, "return");
|
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
|
||||||
|
);
|
||||||
|
require_simd!(
|
||||||
|
arg_tys[2],
|
||||||
|
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
|
||||||
|
);
|
||||||
|
require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
|
||||||
|
|
||||||
// Of the same length:
|
// Of the same length:
|
||||||
let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
let (out_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||||
@ -662,10 +661,19 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(gather(args[0].immediate(), args[1].immediate(), args[2].immediate(), pointer_count, bx, in_len, underlying_ty, false));
|
return Ok(gather(
|
||||||
|
args[0].immediate(),
|
||||||
|
args[1].immediate(),
|
||||||
|
args[2].immediate(),
|
||||||
|
pointer_count,
|
||||||
|
bx,
|
||||||
|
in_len,
|
||||||
|
underlying_ty,
|
||||||
|
false,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="master")]
|
#[cfg(feature = "master")]
|
||||||
if name == sym::simd_scatter {
|
if name == sym::simd_scatter {
|
||||||
// simd_scatter(values: <N x T>, pointers: <N x *mut T>,
|
// simd_scatter(values: <N x T>, pointers: <N x *mut T>,
|
||||||
// mask: <N x i{M}>) -> ()
|
// mask: <N x i{M}>) -> ()
|
||||||
@ -674,9 +682,15 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
// * M: any integer width is supported, will be truncated to i1
|
// * M: any integer width is supported, will be truncated to i1
|
||||||
|
|
||||||
// All types must be simd vector types
|
// All types must be simd vector types
|
||||||
require_simd!(in_ty, "first");
|
require_simd!(in_ty, InvalidMonomorphization::SimdFirst { span, name, ty: in_ty });
|
||||||
require_simd!(arg_tys[1], "second");
|
require_simd!(
|
||||||
require_simd!(arg_tys[2], "third");
|
arg_tys[1],
|
||||||
|
InvalidMonomorphization::SimdSecond { span, name, ty: arg_tys[1] }
|
||||||
|
);
|
||||||
|
require_simd!(
|
||||||
|
arg_tys[2],
|
||||||
|
InvalidMonomorphization::SimdThird { span, name, ty: arg_tys[2] }
|
||||||
|
);
|
||||||
|
|
||||||
// Of the same length:
|
// Of the same length:
|
||||||
let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
let (element_len1, _) = arg_tys[1].simd_size_and_type(bx.tcx());
|
||||||
@ -765,17 +779,24 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = gather(args[0].immediate(), args[1].immediate(), args[2].immediate(), pointer_count, bx, in_len, underlying_ty, true);
|
let result = gather(
|
||||||
|
args[0].immediate(),
|
||||||
|
args[1].immediate(),
|
||||||
|
args[2].immediate(),
|
||||||
|
pointer_count,
|
||||||
|
bx,
|
||||||
|
in_len,
|
||||||
|
underlying_ty,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
let pointers = args[1].immediate();
|
let pointers = args[1].immediate();
|
||||||
|
|
||||||
let vector_type =
|
let vector_type = if pointer_count > 1 {
|
||||||
if pointer_count > 1 {
|
bx.context.new_vector_type(bx.usize_type, in_len)
|
||||||
bx.context.new_vector_type(bx.usize_type, in_len)
|
} else {
|
||||||
}
|
vector_ty(bx, underlying_ty, in_len)
|
||||||
else {
|
};
|
||||||
vector_ty(bx, underlying_ty, in_len)
|
|
||||||
};
|
|
||||||
let elem_type = vector_type.dyncast_vector().expect("vector type").get_element_type();
|
let elem_type = vector_type.dyncast_vector().expect("vector type").get_element_type();
|
||||||
|
|
||||||
for i in 0..in_len {
|
for i in 0..in_len {
|
||||||
@ -815,7 +836,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
})*
|
})*
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem })
|
return_error!(InvalidMonomorphization::UnsupportedOperation { span, name, in_ty, in_elem })
|
||||||
})*
|
})*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -830,91 +851,97 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
let rhs = args[1].immediate();
|
let rhs = args[1].immediate();
|
||||||
let is_add = name == sym::simd_saturating_add;
|
let is_add = name == sym::simd_saturating_add;
|
||||||
let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _;
|
let ptr_bits = bx.tcx().data_layout.pointer_size.bits() as _;
|
||||||
let (signed, elem_width, elem_ty) =
|
let (signed, elem_width, elem_ty) = match *in_elem.kind() {
|
||||||
match *in_elem.kind() {
|
ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits) / 8, bx.cx.type_int_from_ty(i)),
|
||||||
ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits) / 8, bx.cx.type_int_from_ty(i)),
|
ty::Uint(i) => {
|
||||||
ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits) / 8, bx.cx.type_uint_from_ty(i)),
|
(false, i.bit_width().unwrap_or(ptr_bits) / 8, bx.cx.type_uint_from_ty(i))
|
||||||
_ => {
|
}
|
||||||
return_error!(InvalidMonomorphizationExpectedSignedUnsigned {
|
_ => {
|
||||||
|
return_error!(InvalidMonomorphization::ExpectedVectorElementType {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
elem_ty: arg_tys[0].simd_size_and_type(bx.tcx()).1,
|
expected_element: arg_tys[0].simd_size_and_type(bx.tcx()).1,
|
||||||
vec_ty: arg_tys[0],
|
vector_type: arg_tys[0],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let result =
|
let result = match (signed, is_add) {
|
||||||
match (signed, is_add) {
|
(false, true) => {
|
||||||
(false, true) => {
|
let res = lhs + rhs;
|
||||||
let res = lhs + rhs;
|
let cmp = bx.context.new_comparison(None, ComparisonOp::LessThan, res, lhs);
|
||||||
let cmp = bx.context.new_comparison(None, ComparisonOp::LessThan, res, lhs);
|
res | cmp
|
||||||
res | cmp
|
}
|
||||||
},
|
(true, true) => {
|
||||||
(true, true) => {
|
// Algorithm from: https://codereview.stackexchange.com/questions/115869/saturated-signed-addition
|
||||||
// Algorithm from: https://codereview.stackexchange.com/questions/115869/saturated-signed-addition
|
// TODO(antoyo): improve using conditional operators if possible.
|
||||||
// TODO(antoyo): improve using conditional operators if possible.
|
// TODO(antoyo): dyncast_vector should not require a call to unqualified.
|
||||||
// TODO(antoyo): dyncast_vector should not require a call to unqualified.
|
let arg_type = lhs.get_type().unqualified();
|
||||||
let arg_type = lhs.get_type().unqualified();
|
// TODO(antoyo): convert lhs and rhs to unsigned.
|
||||||
// TODO(antoyo): convert lhs and rhs to unsigned.
|
let sum = lhs + rhs;
|
||||||
let sum = lhs + rhs;
|
let vector_type = arg_type.dyncast_vector().expect("vector type");
|
||||||
let vector_type = arg_type.dyncast_vector().expect("vector type");
|
let unit = vector_type.get_num_units();
|
||||||
let unit = vector_type.get_num_units();
|
let a = bx.context.new_rvalue_from_int(elem_ty, ((elem_width as i32) << 3) - 1);
|
||||||
let a = bx.context.new_rvalue_from_int(elem_ty, ((elem_width as i32) << 3) - 1);
|
let width = bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![a; unit]);
|
||||||
let width = bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![a; unit]);
|
|
||||||
|
|
||||||
let xor1 = lhs ^ rhs;
|
let xor1 = lhs ^ rhs;
|
||||||
let xor2 = lhs ^ sum;
|
let xor2 = lhs ^ sum;
|
||||||
let and = bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, xor1) & xor2;
|
let and =
|
||||||
let mask = and >> width;
|
bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, xor1) & xor2;
|
||||||
|
let mask = and >> width;
|
||||||
|
|
||||||
let one = bx.context.new_rvalue_one(elem_ty);
|
let one = bx.context.new_rvalue_one(elem_ty);
|
||||||
let ones = bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![one; unit]);
|
let ones =
|
||||||
let shift1 = ones << width;
|
bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![one; unit]);
|
||||||
let shift2 = sum >> width;
|
let shift1 = ones << width;
|
||||||
let mask_min = shift1 ^ shift2;
|
let shift2 = sum >> width;
|
||||||
|
let mask_min = shift1 ^ shift2;
|
||||||
|
|
||||||
let and1 = bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, mask) & sum;
|
let and1 =
|
||||||
let and2 = mask & mask_min;
|
bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, mask) & sum;
|
||||||
|
let and2 = mask & mask_min;
|
||||||
|
|
||||||
and1 + and2
|
and1 + and2
|
||||||
},
|
}
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
let res = lhs - rhs;
|
let res = lhs - rhs;
|
||||||
let cmp = bx.context.new_comparison(None, ComparisonOp::LessThanEquals, res, lhs);
|
let cmp = bx.context.new_comparison(None, ComparisonOp::LessThanEquals, res, lhs);
|
||||||
res & cmp
|
res & cmp
|
||||||
},
|
}
|
||||||
(true, false) => {
|
(true, false) => {
|
||||||
// TODO(antoyo): dyncast_vector should not require a call to unqualified.
|
// TODO(antoyo): dyncast_vector should not require a call to unqualified.
|
||||||
let arg_type = lhs.get_type().unqualified();
|
let arg_type = lhs.get_type().unqualified();
|
||||||
// TODO(antoyo): this uses the same algorithm from saturating add, but add the
|
// TODO(antoyo): this uses the same algorithm from saturating add, but add the
|
||||||
// negative of the right operand. Find a proper subtraction algorithm.
|
// negative of the right operand. Find a proper subtraction algorithm.
|
||||||
let rhs = bx.context.new_unary_op(None, UnaryOp::Minus, arg_type, rhs);
|
let rhs = bx.context.new_unary_op(None, UnaryOp::Minus, arg_type, rhs);
|
||||||
|
|
||||||
// TODO(antoyo): convert lhs and rhs to unsigned.
|
// TODO(antoyo): convert lhs and rhs to unsigned.
|
||||||
let sum = lhs + rhs;
|
let sum = lhs + rhs;
|
||||||
let vector_type = arg_type.dyncast_vector().expect("vector type");
|
let vector_type = arg_type.dyncast_vector().expect("vector type");
|
||||||
let unit = vector_type.get_num_units();
|
let unit = vector_type.get_num_units();
|
||||||
let a = bx.context.new_rvalue_from_int(elem_ty, ((elem_width as i32) << 3) - 1);
|
let a = bx.context.new_rvalue_from_int(elem_ty, ((elem_width as i32) << 3) - 1);
|
||||||
let width = bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![a; unit]);
|
let width = bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![a; unit]);
|
||||||
|
|
||||||
let xor1 = lhs ^ rhs;
|
let xor1 = lhs ^ rhs;
|
||||||
let xor2 = lhs ^ sum;
|
let xor2 = lhs ^ sum;
|
||||||
let and = bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, xor1) & xor2;
|
let and =
|
||||||
let mask = and >> width;
|
bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, xor1) & xor2;
|
||||||
|
let mask = and >> width;
|
||||||
|
|
||||||
let one = bx.context.new_rvalue_one(elem_ty);
|
let one = bx.context.new_rvalue_one(elem_ty);
|
||||||
let ones = bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![one; unit]);
|
let ones =
|
||||||
let shift1 = ones << width;
|
bx.context.new_rvalue_from_vector(None, lhs.get_type(), &vec![one; unit]);
|
||||||
let shift2 = sum >> width;
|
let shift1 = ones << width;
|
||||||
let mask_min = shift1 ^ shift2;
|
let shift2 = sum >> width;
|
||||||
|
let mask_min = shift1 ^ shift2;
|
||||||
|
|
||||||
let and1 = bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, mask) & sum;
|
let and1 =
|
||||||
let and2 = mask & mask_min;
|
bx.context.new_unary_op(None, UnaryOp::BitwiseNegate, arg_type, mask) & sum;
|
||||||
|
let and2 = mask & mask_min;
|
||||||
|
|
||||||
and1 + and2
|
and1 + and2
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
@ -925,7 +952,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
if name == sym::$name {
|
if name == sym::$name {
|
||||||
require!(
|
require!(
|
||||||
ret_ty == in_elem,
|
ret_ty == in_elem,
|
||||||
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
|
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||||
);
|
);
|
||||||
return match in_elem.kind() {
|
return match in_elem.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) => {
|
ty::Int(_) | ty::Uint(_) => {
|
||||||
@ -947,11 +974,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op))
|
Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return_error!(InvalidMonomorphizationUnsupportedElement {
|
_ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
|
symbol: sym::$name,
|
||||||
in_ty,
|
in_ty,
|
||||||
elem_ty: in_elem,
|
in_elem,
|
||||||
ret_ty
|
ret_ty
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@ -988,18 +1016,24 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
1.0
|
1.0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
macro_rules! minmax_red {
|
macro_rules! minmax_red {
|
||||||
($name:ident: $int_red:ident, $float_red:ident) => {
|
($name:ident: $int_red:ident, $float_red:ident) => {
|
||||||
if name == sym::$name {
|
if name == sym::$name {
|
||||||
require!(
|
require!(
|
||||||
ret_ty == in_elem,
|
ret_ty == in_elem,
|
||||||
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
|
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||||
);
|
);
|
||||||
return match in_elem.kind() {
|
return match in_elem.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())),
|
ty::Int(_) | ty::Uint(_) => Ok(bx.$int_red(args[0].immediate())),
|
||||||
ty::Float(_) => Ok(bx.$float_red(args[0].immediate())),
|
ty::Float(_) => Ok(bx.$float_red(args[0].immediate())),
|
||||||
_ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
|
_ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
|
||||||
|
span,
|
||||||
|
name,
|
||||||
|
symbol: sym::$name,
|
||||||
|
in_ty,
|
||||||
|
in_elem,
|
||||||
|
ret_ty
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1017,17 +1051,18 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
let input = if !$boolean {
|
let input = if !$boolean {
|
||||||
require!(
|
require!(
|
||||||
ret_ty == in_elem,
|
ret_ty == in_elem,
|
||||||
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
|
InvalidMonomorphization::ReturnType { span, name, in_elem, in_ty, ret_ty }
|
||||||
);
|
);
|
||||||
args[0].immediate()
|
args[0].immediate()
|
||||||
} else {
|
} else {
|
||||||
match in_elem.kind() {
|
match in_elem.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) => {}
|
ty::Int(_) | ty::Uint(_) => {}
|
||||||
_ => return_error!(InvalidMonomorphizationUnsupportedElement {
|
_ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
|
symbol: sym::$name,
|
||||||
in_ty,
|
in_ty,
|
||||||
elem_ty: in_elem,
|
in_elem,
|
||||||
ret_ty
|
ret_ty
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
@ -1037,13 +1072,22 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(
|
|||||||
return match in_elem.kind() {
|
return match in_elem.kind() {
|
||||||
ty::Int(_) | ty::Uint(_) => {
|
ty::Int(_) | ty::Uint(_) => {
|
||||||
let r = bx.vector_reduce_op(input, $op);
|
let r = bx.vector_reduce_op(input, $op);
|
||||||
Ok(if !$boolean { r } else { bx.icmp(IntPredicate::IntNE, r, bx.context.new_rvalue_zero(r.get_type())) })
|
Ok(if !$boolean {
|
||||||
|
r
|
||||||
|
} else {
|
||||||
|
bx.icmp(
|
||||||
|
IntPredicate::IntNE,
|
||||||
|
r,
|
||||||
|
bx.context.new_rvalue_zero(r.get_type()),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_ => return_error!(InvalidMonomorphizationUnsupportedElement {
|
_ => return_error!(InvalidMonomorphization::UnsupportedSymbol {
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
|
symbol: sym::$name,
|
||||||
in_ty,
|
in_ty,
|
||||||
elem_ty: in_elem,
|
in_elem,
|
||||||
ret_ty
|
ret_ty
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
81
src/lib.rs
81
src/lib.rs
@ -64,13 +64,19 @@ mod type_of;
|
|||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
use crate::errors::LTONotSupported;
|
use crate::errors::LTONotSupported;
|
||||||
use gccjit::{Context, OptimizationLevel, TargetInfo};
|
use gccjit::{Context, OptimizationLevel};
|
||||||
|
#[cfg(feature="master")]
|
||||||
|
use gccjit::TargetInfo;
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
use gccjit::CType;
|
||||||
use rustc_ast::expand::allocator::AllocatorKind;
|
use rustc_ast::expand::allocator::AllocatorKind;
|
||||||
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
|
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
|
||||||
use rustc_codegen_ssa::base::codegen_crate;
|
use rustc_codegen_ssa::base::codegen_crate;
|
||||||
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig, TargetMachineFactoryFn};
|
use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn};
|
||||||
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
|
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
|
||||||
use rustc_codegen_ssa::target_features::supported_target_features;
|
use rustc_codegen_ssa::target_features::supported_target_features;
|
||||||
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
|
use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
|
||||||
@ -85,6 +91,8 @@ use rustc_session::config::{Lto, OptLevel, OutputFilenames};
|
|||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
use rustc_span::fatal_error::FatalError;
|
use rustc_span::fatal_error::FatalError;
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
use tempfile::TempDir;
|
||||||
|
|
||||||
fluent_messages! { "../messages.ftl" }
|
fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
@ -98,6 +106,23 @@ impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TargetInfo {
|
||||||
|
supports_128bit_integers: AtomicBool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
impl TargetInfo {
|
||||||
|
fn cpu_supports(&self, _feature: &str) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn supports_128bit_int(&self) -> bool {
|
||||||
|
self.supports_128bit_integers.load(Ordering::SeqCst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GccCodegenBackend {
|
pub struct GccCodegenBackend {
|
||||||
target_info: Arc<TargetInfo>,
|
target_info: Arc<TargetInfo>,
|
||||||
@ -114,6 +139,18 @@ impl CodegenBackend for GccCodegenBackend {
|
|||||||
if sess.lto() != Lto::No {
|
if sess.lto() != Lto::No {
|
||||||
sess.emit_warning(LTONotSupported {});
|
sess.emit_warning(LTONotSupported {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
{
|
||||||
|
let temp_dir = TempDir::new().expect("cannot create temporary directory");
|
||||||
|
let temp_file = temp_dir.into_path().join("result.asm");
|
||||||
|
let check_context = Context::default();
|
||||||
|
check_context.set_print_errors_to_stderr(false);
|
||||||
|
let _int128_ty = check_context.new_c_type(CType::UInt128t);
|
||||||
|
// NOTE: we cannot just call compile() as this would require other files than libgccjit.so.
|
||||||
|
check_context.compile_to_file(gccjit::OutputKind::Assembler, temp_file.to_str().expect("path to str"));
|
||||||
|
self.target_info.supports_128bit_integers.store(check_context.get_last_error() == Ok(None), Ordering::SeqCst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn provide(&self, providers: &mut Providers) {
|
fn provide(&self, providers: &mut Providers) {
|
||||||
@ -206,14 +243,14 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||||||
type ThinData = ();
|
type ThinData = ();
|
||||||
type ThinBuffer = ThinBuffer;
|
type ThinBuffer = ThinBuffer;
|
||||||
|
|
||||||
fn run_fat_lto(_cgcx: &CodegenContext<Self>, mut modules: Vec<FatLTOInput<Self>>, _cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>) -> Result<LtoModuleCodegen<Self>, FatalError> {
|
fn run_fat_lto(_cgcx: &CodegenContext<Self>, mut modules: Vec<FatLtoInput<Self>>, _cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>) -> Result<LtoModuleCodegen<Self>, FatalError> {
|
||||||
// TODO(antoyo): implement LTO by sending -flto to libgccjit and adding the appropriate gcc linker plugins.
|
// TODO(antoyo): implement LTO by sending -flto to libgccjit and adding the appropriate gcc linker plugins.
|
||||||
// NOTE: implemented elsewhere.
|
// NOTE: implemented elsewhere.
|
||||||
// TODO(antoyo): what is implemented elsewhere ^ ?
|
// TODO(antoyo): what is implemented elsewhere ^ ?
|
||||||
let module =
|
let module =
|
||||||
match modules.remove(0) {
|
match modules.remove(0) {
|
||||||
FatLTOInput::InMemory(module) => module,
|
FatLtoInput::InMemory(module) => module,
|
||||||
FatLTOInput::Serialized { .. } => {
|
FatLtoInput::Serialized { .. } => {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -228,6 +265,10 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_statistics(&self) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
|
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
|
||||||
module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
|
module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -262,14 +303,21 @@ impl WriteBackendMethods for GccCodegenBackend {
|
|||||||
/// This is the entrypoint for a hot plugged rustc_codegen_gccjit
|
/// This is the entrypoint for a hot plugged rustc_codegen_gccjit
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
|
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
|
||||||
// Get the native arch and check whether the target supports 128-bit integers.
|
#[cfg(feature="master")]
|
||||||
let context = Context::default();
|
let target_info = {
|
||||||
let arch = context.get_target_info().arch().unwrap();
|
// Get the native arch and check whether the target supports 128-bit integers.
|
||||||
|
let context = Context::default();
|
||||||
|
let arch = context.get_target_info().arch().unwrap();
|
||||||
|
|
||||||
// Get the second TargetInfo with the correct CPU features by setting the arch.
|
// Get the second TargetInfo with the correct CPU features by setting the arch.
|
||||||
let context = Context::default();
|
let context = Context::default();
|
||||||
context.add_driver_option(&format!("-march={}", arch.to_str().unwrap()));
|
context.add_driver_option(&format!("-march={}", arch.to_str().unwrap()));
|
||||||
let target_info = Arc::new(context.get_target_info());
|
Arc::new(context.get_target_info())
|
||||||
|
};
|
||||||
|
#[cfg(not(feature="master"))]
|
||||||
|
let target_info = Arc::new(TargetInfo {
|
||||||
|
supports_128bit_integers: AtomicBool::new(false),
|
||||||
|
});
|
||||||
|
|
||||||
Box::new(GccCodegenBackend {
|
Box::new(GccCodegenBackend {
|
||||||
target_info,
|
target_info,
|
||||||
@ -315,14 +363,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool, target_info: &Arc<T
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.filter(|_feature| {
|
.filter(|_feature| {
|
||||||
#[cfg(feature="master")]
|
target_info.cpu_supports(_feature)
|
||||||
{
|
|
||||||
target_info.cpu_supports(_feature)
|
|
||||||
}
|
|
||||||
#[cfg(not(feature="master"))]
|
|
||||||
{
|
|
||||||
false
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512ifma,
|
adx, aes, avx, avx2, avx512bf16, avx512bitalg, avx512bw, avx512cd, avx512dq, avx512er, avx512f, avx512ifma,
|
||||||
avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq,
|
avx512pf, avx512vbmi, avx512vbmi2, avx512vl, avx512vnni, avx512vp2intersect, avx512vpopcntdq,
|
||||||
|
@ -31,7 +31,7 @@ impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||||||
|
|
||||||
#[cfg_attr(not(feature="master"), allow(unused_variables))]
|
#[cfg_attr(not(feature="master"), allow(unused_variables))]
|
||||||
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
|
fn predefine_fn(&self, instance: Instance<'tcx>, linkage: Linkage, visibility: Visibility, symbol_name: &str) {
|
||||||
assert!(!instance.substs.has_infer());
|
assert!(!instance.args.has_infer());
|
||||||
|
|
||||||
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
|
||||||
self.linkage.set(base::linkage_to_gcc(linkage));
|
self.linkage.set(base::linkage_to_gcc(linkage));
|
||||||
|
26
src/type_.rs
26
src/type_.rs
@ -54,6 +54,23 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
|
|||||||
self.u128_type
|
self.u128_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn type_ptr_to(&self, ty: Type<'gcc>) -> Type<'gcc> {
|
||||||
|
ty.make_pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_ptr_to_ext(&self, ty: Type<'gcc>, _address_space: AddressSpace) -> Type<'gcc> {
|
||||||
|
// TODO(antoyo): use address_space, perhaps with TYPE_ADDR_SPACE?
|
||||||
|
ty.make_pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_i8p(&self) -> Type<'gcc> {
|
||||||
|
self.type_ptr_to(self.type_i8())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_i8p_ext(&self, address_space: AddressSpace) -> Type<'gcc> {
|
||||||
|
self.type_ptr_to_ext(self.type_i8(), address_space)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn type_pointee_for_align(&self, align: Align) -> Type<'gcc> {
|
pub fn type_pointee_for_align(&self, align: Align) -> Type<'gcc> {
|
||||||
// FIXME(eddyb) We could find a better approximation if ity.align < align.
|
// FIXME(eddyb) We could find a better approximation if ity.align < align.
|
||||||
let ity = Integer::approximate_align(self, align);
|
let ity = Integer::approximate_align(self, align);
|
||||||
@ -149,13 +166,12 @@ impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_ptr_to(&self, ty: Type<'gcc>) -> Type<'gcc> {
|
fn type_ptr(&self) -> Type<'gcc> {
|
||||||
ty.make_pointer()
|
self.type_ptr_to(self.type_void())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn type_ptr_to_ext(&self, ty: Type<'gcc>, _address_space: AddressSpace) -> Type<'gcc> {
|
fn type_ptr_ext(&self, address_space: AddressSpace) -> Type<'gcc> {
|
||||||
// TODO(antoyo): use address_space, perhaps with TYPE_ADDR_SPACE?
|
self.type_ptr_to_ext(self.type_void(), address_space)
|
||||||
ty.make_pointer()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn element_type(&self, ty: Type<'gcc>) -> Type<'gcc> {
|
fn element_type(&self, ty: Type<'gcc>) -> Type<'gcc> {
|
||||||
|
@ -101,7 +101,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
|
|||||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
||||||
(layout.ty.kind(), &layout.variants)
|
(layout.ty.kind(), &layout.variants)
|
||||||
{
|
{
|
||||||
write!(&mut name, "::{}", ty::GeneratorSubsts::variant_name(index)).unwrap();
|
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
||||||
}
|
}
|
||||||
Some(name)
|
Some(name)
|
||||||
}
|
}
|
||||||
@ -282,8 +282,8 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
|
|||||||
}
|
}
|
||||||
// only wide pointer boxes are handled as pointers
|
// only wide pointer boxes are handled as pointers
|
||||||
// thin pointer boxes with scalar allocators are handled by the general logic below
|
// thin pointer boxes with scalar allocators are handled by the general logic below
|
||||||
ty::Adt(def, substs) if def.is_box() && cx.layout_of(substs.type_at(1)).is_zst() => {
|
ty::Adt(def, args) if def.is_box() && cx.layout_of(args.type_at(1)).is_zst() => {
|
||||||
let ptr_ty = cx.tcx.mk_mut_ptr(self.ty.boxed_ty());
|
let ptr_ty = Ty::new_mut_ptr(cx.tcx,self.ty.boxed_ty());
|
||||||
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
|
return cx.layout_of(ptr_ty).scalar_pair_element_gcc_type(cx, index, immediate);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
6
test.sh
6
test.sh
@ -346,7 +346,9 @@ function test_rustc() {
|
|||||||
git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
git checkout -- tests/ui/issues/auxiliary/issue-3136-a.rs # contains //~ERROR, but shouldn't be removed
|
||||||
|
|
||||||
rm -r tests/ui/{abi*,extern/,unsized-locals/,proc-macro/,threads-sendsync/,thinlto/,borrowck/,chalkify/bugs/,test*,*lto*.rs,consts/const-float-bits-reject-conv.rs,consts/issue-miri-1910.rs} || true
|
rm -r tests/ui/{abi*,extern/,unsized-locals/,proc-macro/,threads-sendsync/,thinlto/,borrowck/,chalkify/bugs/,test*,*lto*.rs,consts/const-float-bits-reject-conv.rs,consts/issue-miri-1910.rs} || true
|
||||||
rm tests/ui/mir/mir_heavy_promoted.rs # this tests is oom-killed in the CI.
|
rm tests/ui/mir/mir_heavy_promoted.rs # this test is oom-killed in the CI.
|
||||||
|
# Tests generating errors.
|
||||||
|
rm tests/ui/consts/const-eval/nonnull_as_ref_ub.rs tests/ui/consts/issue-94675.rs
|
||||||
for test in $(rg --files-with-matches "thread|lto" tests/ui); do
|
for test in $(rg --files-with-matches "thread|lto" tests/ui); do
|
||||||
rm $test
|
rm $test
|
||||||
done
|
done
|
||||||
@ -354,6 +356,8 @@ function test_rustc() {
|
|||||||
git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
|
git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice.rs
|
||||||
git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
|
git checkout tests/ui/type-alias-impl-trait/auxiliary/cross_crate_ice2.rs
|
||||||
git checkout tests/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs
|
git checkout tests/ui/macros/rfc-2011-nicer-assert-messages/auxiliary/common.rs
|
||||||
|
git checkout tests/ui/imports/ambiguous-1.rs
|
||||||
|
git checkout tests/ui/imports/ambiguous-4-extern.rs
|
||||||
|
|
||||||
RUSTC_ARGS="$TEST_FLAGS -Csymbol-mangling-version=v0 -Zcodegen-backend="$(pwd)"/../target/"$CHANNEL"/librustc_codegen_gcc."$dylib_ext" --sysroot "$(pwd)"/../build_sysroot/sysroot"
|
RUSTC_ARGS="$TEST_FLAGS -Csymbol-mangling-version=v0 -Zcodegen-backend="$(pwd)"/../target/"$CHANNEL"/librustc_codegen_gcc."$dylib_ext" --sysroot "$(pwd)"/../build_sysroot/sysroot"
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// status: signal
|
// status: signal
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// status: signal
|
// status: signal
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
// 10
|
// 10
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// 7 8
|
// 7 8
|
||||||
// 10
|
// 10
|
||||||
|
|
||||||
#![allow(unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, track_caller)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics, track_caller)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics,
|
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics,
|
||||||
unboxed_closures)]
|
unboxed_closures)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
// 1
|
// 1
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// status: 0
|
// status: 0
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start)]
|
#![feature(auto_traits, lang_items, no_core, start)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// status: 2
|
// status: 2
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
// status: 1
|
// status: 1
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start)]
|
#![feature(auto_traits, lang_items, no_core, start)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// stdout: 1
|
// stdout: 1
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
// stdout: Success
|
// stdout: Success
|
||||||
// status: signal
|
// status: signal
|
||||||
|
|
||||||
#![allow(unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
// 6
|
// 6
|
||||||
// 11
|
// 11
|
||||||
|
|
||||||
#![allow(unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, track_caller)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics, track_caller)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// 39
|
// 39
|
||||||
// 10
|
// 10
|
||||||
|
|
||||||
#![allow(unused_attributes)]
|
#![allow(internal_features, unused_attributes)]
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics, arbitrary_self_types)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// stdout: 1
|
// stdout: 1
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
// 42
|
// 42
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// stdout: 5
|
// stdout: 5
|
||||||
|
|
||||||
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(arbitrary_self_types, auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
// 1
|
// 1
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
// 2
|
// 2
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
// stdout: 3
|
// stdout: 3
|
||||||
|
|
||||||
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
#![feature(auto_traits, lang_items, no_core, start, intrinsics)]
|
||||||
|
#![allow(internal_features)]
|
||||||
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![no_core]
|
#![no_core]
|
||||||
|
@ -3,7 +3,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
from os import walk
|
|
||||||
|
|
||||||
|
|
||||||
def run_command(command, cwd=None):
|
def run_command(command, cwd=None):
|
||||||
@ -180,7 +179,7 @@ def update_intrinsics(llvm_path, llvmint, llvmint2):
|
|||||||
intrinsics[arch].sort(key=lambda x: (x[0], x[2]))
|
intrinsics[arch].sort(key=lambda x: (x[0], x[2]))
|
||||||
out.write(' // {}\n'.format(arch))
|
out.write(' // {}\n'.format(arch))
|
||||||
for entry in intrinsics[arch]:
|
for entry in intrinsics[arch]:
|
||||||
if entry[2] == True: # if it is a duplicate
|
if entry[2] is True: # if it is a duplicate
|
||||||
out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(entry[0], entry[1]))
|
out.write(' // [DUPLICATE]: "{}" => "{}",\n'.format(entry[0], entry[1]))
|
||||||
elif "_round_mask" in entry[1]:
|
elif "_round_mask" in entry[1]:
|
||||||
out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(entry[0], entry[1]))
|
out.write(' // [INVALID CONVERSION]: "{}" => "{}",\n'.format(entry[0], entry[1]))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user