mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 14:56:27 +00:00
abi: readjust FnAbi
s to remove unsupported PassMode
s, via query hooks.
This commit is contained in:
parent
13678f8644
commit
111bebdd68
@ -13,13 +13,13 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
|
|||||||
use rustc_middle::ty::query::Providers;
|
use rustc_middle::ty::query::Providers;
|
||||||
use rustc_middle::ty::subst::SubstsRef;
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Const, FloatTy, GeneratorSubsts, IntTy, ParamEnv, PolyFnSig, Ty, TyKind, TypeAndMut,
|
self, Const, FloatTy, GeneratorSubsts, IntTy, ParamEnv, PolyFnSig, Ty, TyCtxt, TyKind,
|
||||||
UintTy,
|
TypeAndMut, UintTy,
|
||||||
};
|
};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use rustc_target::abi::call::{CastTarget, FnAbi, PassMode, Reg, RegKind};
|
use rustc_target::abi::call::{ArgAbi, ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
|
||||||
use rustc_target::abi::{Abi, Align, FieldsShape, Primitive, Scalar, Size, VariantIdx, Variants};
|
use rustc_target::abi::{Abi, Align, FieldsShape, Primitive, Scalar, Size, VariantIdx, Variants};
|
||||||
use rustc_target::spec::abi::Abi as SpecAbi;
|
use rustc_target::spec::abi::Abi as SpecAbi;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -35,7 +35,7 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||||||
// However, those functions will be implemented by compiler-builtins:
|
// However, those functions will be implemented by compiler-builtins:
|
||||||
// https://github.com/rust-lang/rust/blob/5fae56971d8487088c0099c82c0a5ce1638b5f62/library/core/src/lib.rs#L23-L27
|
// https://github.com/rust-lang/rust/blob/5fae56971d8487088c0099c82c0a5ce1638b5f62/library/core/src/lib.rs#L23-L27
|
||||||
// This theoretically then should be fine to leave as C, but, there's no backend hook for
|
// This theoretically then should be fine to leave as C, but, there's no backend hook for
|
||||||
// FnAbi::adjust_for_cabi, causing it to panic:
|
// `FnAbi::adjust_for_cabi`, causing it to panic:
|
||||||
// https://github.com/rust-lang/rust/blob/5fae56971d8487088c0099c82c0a5ce1638b5f62/compiler/rustc_target/src/abi/call/mod.rs#L603
|
// https://github.com/rust-lang/rust/blob/5fae56971d8487088c0099c82c0a5ce1638b5f62/compiler/rustc_target/src/abi/call/mod.rs#L603
|
||||||
// So, treat any `extern "C"` functions as `extern "unadjusted"`, to be able to compile libcore with arch=spirv.
|
// So, treat any `extern "C"` functions as `extern "unadjusted"`, to be able to compile libcore with arch=spirv.
|
||||||
providers.fn_sig = |tcx, def_id| {
|
providers.fn_sig = |tcx, def_id| {
|
||||||
@ -49,6 +49,46 @@ pub(crate) fn provide(providers: &mut Providers) {
|
|||||||
inner
|
inner
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For the Rust ABI, `FnAbi` adjustments are backend-agnostic, but they will
|
||||||
|
// use features like `PassMode::Cast`, that are incompatible with SPIR-V.
|
||||||
|
// By hooking the queries computing `FnAbi`s, we can recompute the `FnAbi`
|
||||||
|
// from the return/args layouts, to e.g. prefer using `PassMode::Direct`.
|
||||||
|
fn readjust_fn_abi<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
|
||||||
|
) -> &'tcx FnAbi<'tcx, Ty<'tcx>> {
|
||||||
|
let readjust_arg_abi = |arg: &ArgAbi<'tcx, Ty<'tcx>>| {
|
||||||
|
let mut arg = ArgAbi::new(&tcx, arg.layout, |_, _, _| ArgAttributes::new());
|
||||||
|
|
||||||
|
// Avoid pointlessly passing ZSTs, just like the official Rust ABI.
|
||||||
|
if arg.layout.is_zst() {
|
||||||
|
arg.mode = PassMode::Ignore;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg
|
||||||
|
};
|
||||||
|
tcx.arena.alloc(FnAbi {
|
||||||
|
args: fn_abi.args.iter().map(readjust_arg_abi).collect(),
|
||||||
|
ret: readjust_arg_abi(&fn_abi.ret),
|
||||||
|
|
||||||
|
// FIXME(eddyb) validate some of these, and report errors - however,
|
||||||
|
// we can't just emit errors from here, since we have no `Span`, so
|
||||||
|
// we should have instead a check on MIR for e.g. C variadic calls.
|
||||||
|
c_variadic: fn_abi.c_variadic,
|
||||||
|
fixed_count: fn_abi.fixed_count,
|
||||||
|
conv: fn_abi.conv,
|
||||||
|
can_unwind: fn_abi.can_unwind,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
providers.fn_abi_of_fn_ptr = |tcx, key| {
|
||||||
|
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS.fn_abi_of_fn_ptr)(tcx, key);
|
||||||
|
Ok(readjust_fn_abi(tcx, result?))
|
||||||
|
};
|
||||||
|
providers.fn_abi_of_instance = |tcx, key| {
|
||||||
|
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS.fn_abi_of_instance)(tcx, key);
|
||||||
|
Ok(readjust_fn_abi(tcx, result?))
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn provide_extern(providers: &mut Providers) {
|
pub(crate) fn provide_extern(providers: &mut Providers) {
|
||||||
|
@ -17,6 +17,7 @@ OpDecorate %2 Location 0
|
|||||||
%8 = OpTypeInt 32 0
|
%8 = OpTypeInt 32 0
|
||||||
%9 = OpConstant %8 3
|
%9 = OpConstant %8 3
|
||||||
%5 = OpTypeArray %7 %9
|
%5 = OpTypeArray %7 %9
|
||||||
%10 = OpTypePointer Input %5
|
%10 = OpTypeFunction %6 %5
|
||||||
%11 = OpTypeFunction %6
|
%11 = OpTypeFunction %6
|
||||||
%2 = OpVariable %10 Input
|
%12 = OpTypePointer Input %5
|
||||||
|
%2 = OpVariable %12 Input
|
||||||
|
@ -6,7 +6,7 @@ error: constant arrays/structs cannot contain pointers to other constants
|
|||||||
|
|
|
|
||||||
= note: Stack:
|
= note: Stack:
|
||||||
nested_ref_in_composite::main_pair
|
nested_ref_in_composite::main_pair
|
||||||
Unnamed function ID %26
|
Unnamed function ID %24
|
||||||
|
|
||||||
error: constant arrays/structs cannot contain pointers to other constants
|
error: constant arrays/structs cannot contain pointers to other constants
|
||||||
--> $DIR/nested-ref-in-composite.rs:27:19
|
--> $DIR/nested-ref-in-composite.rs:27:19
|
||||||
@ -16,7 +16,7 @@ error: constant arrays/structs cannot contain pointers to other constants
|
|||||||
|
|
|
|
||||||
= note: Stack:
|
= note: Stack:
|
||||||
nested_ref_in_composite::main_array3
|
nested_ref_in_composite::main_array3
|
||||||
Unnamed function ID %34
|
Unnamed function ID %33
|
||||||
|
|
||||||
error: error:0:0 - No OpEntryPoint instruction was found. This is only allowed if the Linkage capability is being used.
|
error: error:0:0 - No OpEntryPoint instruction was found. This is only allowed if the Linkage capability is being used.
|
||||||
|
|
|
|
||||||
|
Loading…
Reference in New Issue
Block a user