mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-22 14:56:27 +00:00
Simplify FnAbi
handling for the fewer PassMode
s possible now.
This commit is contained in:
parent
6d43d60142
commit
2dc88f26ac
@ -19,7 +19,7 @@ use rustc_middle::{bug, span_bug};
|
|||||||
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::{ArgAbi, ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
|
use rustc_target::abi::call::{ArgAbi, ArgAttributes, FnAbi, PassMode};
|
||||||
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;
|
||||||
@ -236,87 +236,6 @@ impl<'tcx> ConvSpirvType<'tcx> for PointeeTy<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> ConvSpirvType<'tcx> for Reg {
|
|
||||||
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
|
|
||||||
match self.kind {
|
|
||||||
RegKind::Integer => SpirvType::Integer(self.size.bits() as u32, false).def(span, cx),
|
|
||||||
RegKind::Float => SpirvType::Float(self.size.bits() as u32).def(span, cx),
|
|
||||||
RegKind::Vector => SpirvType::Vector {
|
|
||||||
element: SpirvType::Integer(8, false).def(span, cx),
|
|
||||||
count: self.size.bytes() as u32,
|
|
||||||
}
|
|
||||||
.def(span, cx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> ConvSpirvType<'tcx> for CastTarget {
|
|
||||||
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
|
|
||||||
let rest_ll_unit = self.rest.unit.spirv_type(span, cx);
|
|
||||||
let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
|
|
||||||
(0, 0)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
self.rest.total.bytes() / self.rest.unit.size.bytes(),
|
|
||||||
self.rest.total.bytes() % self.rest.unit.size.bytes(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.prefix.iter().all(|x| x.is_none()) {
|
|
||||||
// Simplify to a single unit when there is no prefix and size <= unit size
|
|
||||||
if self.rest.total <= self.rest.unit.size {
|
|
||||||
return rest_ll_unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplify to array when all chunks are the same size and type
|
|
||||||
if rem_bytes == 0 {
|
|
||||||
return SpirvType::Array {
|
|
||||||
element: rest_ll_unit,
|
|
||||||
count: cx.constant_u32(span, rest_count as u32),
|
|
||||||
}
|
|
||||||
.def(span, cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create list of fields in the main structure
|
|
||||||
let mut args: Vec<_> = self
|
|
||||||
.prefix
|
|
||||||
.iter()
|
|
||||||
.flatten()
|
|
||||||
.map(|&kind| {
|
|
||||||
Reg {
|
|
||||||
kind,
|
|
||||||
size: self.prefix_chunk_size,
|
|
||||||
}
|
|
||||||
.spirv_type(span, cx)
|
|
||||||
})
|
|
||||||
.chain((0..rest_count).map(|_| rest_ll_unit))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Append final integer
|
|
||||||
if rem_bytes != 0 {
|
|
||||||
// Only integers can be really split further.
|
|
||||||
assert_eq!(self.rest.unit.kind, RegKind::Integer);
|
|
||||||
args.push(SpirvType::Integer(rem_bytes as u32 * 8, false).def(span, cx));
|
|
||||||
}
|
|
||||||
|
|
||||||
let size = Some(self.size(cx));
|
|
||||||
let align = self.align(cx);
|
|
||||||
let (field_offsets, computed_size, computed_align) = auto_struct_layout(cx, &args);
|
|
||||||
assert_eq!(size, computed_size, "{:#?}", self);
|
|
||||||
assert_eq!(align, computed_align, "{:#?}", self);
|
|
||||||
SpirvType::Adt {
|
|
||||||
def_id: None,
|
|
||||||
size,
|
|
||||||
align,
|
|
||||||
field_types: args,
|
|
||||||
field_offsets,
|
|
||||||
field_names: None,
|
|
||||||
}
|
|
||||||
.def(span, cx)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
||||||
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
|
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
|
||||||
let mut argument_types = Vec::new();
|
let mut argument_types = Vec::new();
|
||||||
@ -326,14 +245,11 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||||||
PassMode::Direct(_) | PassMode::Pair(..) => {
|
PassMode::Direct(_) | PassMode::Pair(..) => {
|
||||||
self.ret.layout.spirv_type_immediate(span, cx)
|
self.ret.layout.spirv_type_immediate(span, cx)
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast_target) => cast_target.spirv_type(span, cx),
|
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
|
||||||
PassMode::Indirect { .. } => {
|
span,
|
||||||
let pointee = self.ret.layout.spirv_type(span, cx);
|
"query hooks should've made this `PassMode` impossible: {:#?}",
|
||||||
let pointer = SpirvType::Pointer { pointee }.def(span, cx);
|
self.ret
|
||||||
// Important: the return pointer comes *first*, not last.
|
),
|
||||||
argument_types.push(pointer);
|
|
||||||
SpirvType::Void.def(span, cx)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for arg in &self.args {
|
for arg in &self.args {
|
||||||
@ -349,27 +265,11 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PassMode::Cast(cast_target) => cast_target.spirv_type(span, cx),
|
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
|
||||||
PassMode::Indirect {
|
span,
|
||||||
extra_attrs: Some(_),
|
"query hooks should've made this `PassMode` impossible: {:#?}",
|
||||||
..
|
arg
|
||||||
} => {
|
),
|
||||||
let ptr_ty = cx.tcx.mk_mut_ptr(arg.layout.ty);
|
|
||||||
let ptr_layout = cx.layout_of(ptr_ty);
|
|
||||||
argument_types.push(scalar_pair_element_backend_type(
|
|
||||||
cx, span, ptr_layout, 0, true,
|
|
||||||
));
|
|
||||||
argument_types.push(scalar_pair_element_backend_type(
|
|
||||||
cx, span, ptr_layout, 1, true,
|
|
||||||
));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
PassMode::Indirect {
|
|
||||||
extra_attrs: None, ..
|
|
||||||
} => {
|
|
||||||
let pointee = arg.layout.spirv_type(span, cx);
|
|
||||||
SpirvType::Pointer { pointee }.def(span, cx)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
argument_types.push(arg_type);
|
argument_types.push(arg_type);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ use rustc_middle::ty::{FnDef, Instance, ParamEnv, Ty, TyKind};
|
|||||||
use rustc_span::source_map::Span;
|
use rustc_span::source_map::Span;
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
use rustc_target::abi::call::{FnAbi, PassMode};
|
use rustc_target::abi::call::{FnAbi, PassMode};
|
||||||
|
use std::assert_matches::assert_matches;
|
||||||
|
|
||||||
fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_>) -> Option<(u64, bool)> {
|
fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_>) -> Option<(u64, bool)> {
|
||||||
match ty.kind() {
|
match ty.kind() {
|
||||||
@ -100,17 +101,10 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
|
|||||||
|
|
||||||
sym::volatile_load | sym::unaligned_volatile_load => {
|
sym::volatile_load | sym::unaligned_volatile_load => {
|
||||||
let ptr = args[0].immediate();
|
let ptr = args[0].immediate();
|
||||||
if let PassMode::Cast(ty) = fn_abi.ret.mode {
|
|
||||||
let pointee = ty.spirv_type(self.span(), self);
|
|
||||||
let pointer = SpirvType::Pointer { pointee }.def(self.span(), self);
|
|
||||||
let ptr = self.pointercast(ptr, pointer);
|
|
||||||
self.volatile_load(pointee, ptr)
|
|
||||||
} else {
|
|
||||||
let layout = self.layout_of(substs.type_at(0));
|
let layout = self.layout_of(substs.type_at(0));
|
||||||
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
|
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
|
||||||
self.to_immediate(load, layout)
|
self.to_immediate(load, layout)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sym::prefetch_read_data
|
sym::prefetch_read_data
|
||||||
| sym::prefetch_write_data
|
| sym::prefetch_write_data
|
||||||
@ -330,15 +324,12 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if !fn_abi.ret.is_ignore() {
|
if !fn_abi.ret.is_ignore() {
|
||||||
if let PassMode::Cast(_ty) = fn_abi.ret.mode {
|
assert_matches!(fn_abi.ret.mode, PassMode::Direct(_) | PassMode::Pair(..));
|
||||||
self.fatal("TODO: PassMode::Cast not implemented yet in intrinsics");
|
|
||||||
} else {
|
|
||||||
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
|
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
|
||||||
.val
|
.val
|
||||||
.store(self, result);
|
.store(self, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn abort(&mut self) {
|
fn abort(&mut self) {
|
||||||
// HACK(eddyb) there is no `abort` or `trap` instruction in SPIR-V,
|
// HACK(eddyb) there is no `abort` or `trap` instruction in SPIR-V,
|
||||||
|
@ -24,6 +24,7 @@ use rustc_errors::DiagnosticBuilder;
|
|||||||
use rustc_middle::mir::coverage::{
|
use rustc_middle::mir::coverage::{
|
||||||
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
|
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
|
||||||
};
|
};
|
||||||
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::layout::{
|
use rustc_middle::ty::layout::{
|
||||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
|
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
|
||||||
TyAndLayout,
|
TyAndLayout,
|
||||||
@ -286,27 +287,18 @@ impl<'a, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'tcx> {
|
|||||||
val
|
val
|
||||||
}
|
}
|
||||||
match arg_abi.mode {
|
match arg_abi.mode {
|
||||||
PassMode::Ignore => (),
|
PassMode::Ignore => {}
|
||||||
|
PassMode::Direct(_) => {
|
||||||
|
OperandValue::Immediate(next(self, idx)).store(self, dst);
|
||||||
|
}
|
||||||
PassMode::Pair(..) => {
|
PassMode::Pair(..) => {
|
||||||
OperandValue::Pair(next(self, idx), next(self, idx)).store(self, dst);
|
OperandValue::Pair(next(self, idx), next(self, idx)).store(self, dst);
|
||||||
}
|
}
|
||||||
PassMode::Indirect {
|
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
|
||||||
extra_attrs: Some(_),
|
self.span(),
|
||||||
..
|
"query hooks should've made this `PassMode` impossible: {:#?}",
|
||||||
} => OperandValue::Ref(
|
arg_abi
|
||||||
next(self, idx),
|
),
|
||||||
Some(next(self, idx)),
|
|
||||||
arg_abi.layout.align.abi,
|
|
||||||
)
|
|
||||||
.store(self, dst),
|
|
||||||
PassMode::Direct(_)
|
|
||||||
| PassMode::Indirect {
|
|
||||||
extra_attrs: None, ..
|
|
||||||
}
|
|
||||||
| PassMode::Cast(_) => {
|
|
||||||
let next_arg = next(self, idx);
|
|
||||||
self.store_arg(arg_abi, next_arg, dst);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,21 +308,17 @@ impl<'a, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'tcx> {
|
|||||||
val: Self::Value,
|
val: Self::Value,
|
||||||
dst: PlaceRef<'tcx, Self::Value>,
|
dst: PlaceRef<'tcx, Self::Value>,
|
||||||
) {
|
) {
|
||||||
if arg_abi.is_ignore() {
|
match arg_abi.mode {
|
||||||
return;
|
PassMode::Ignore => {}
|
||||||
}
|
PassMode::Direct(_) | PassMode::Pair(..) => {
|
||||||
if arg_abi.is_sized_indirect() {
|
|
||||||
OperandValue::Ref(val, None, arg_abi.layout.align.abi).store(self, dst);
|
|
||||||
} else if arg_abi.is_unsized_indirect() {
|
|
||||||
self.fatal("unsized `ArgAbi` must be handled through `store_fn_arg`");
|
|
||||||
} else if let PassMode::Cast(cast) = arg_abi.mode {
|
|
||||||
let cast_ty = cast.spirv_type(self.span(), self);
|
|
||||||
let cast_ptr_ty = SpirvType::Pointer { pointee: cast_ty }.def(self.span(), self);
|
|
||||||
let cast_dst = self.pointercast(dst.llval, cast_ptr_ty);
|
|
||||||
self.store(val, cast_dst, arg_abi.layout.align.abi);
|
|
||||||
} else {
|
|
||||||
OperandValue::Immediate(val).store(self, dst);
|
OperandValue::Immediate(val).store(self, dst);
|
||||||
}
|
}
|
||||||
|
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
|
||||||
|
self.span(),
|
||||||
|
"query hooks should've made this `PassMode` impossible: {:#?}",
|
||||||
|
arg_abi
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type {
|
fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type {
|
||||||
|
@ -11,13 +11,12 @@ use rspirv::spirv::{
|
|||||||
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
|
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
|
use rustc_middle::span_bug;
|
||||||
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
|
||||||
use rustc_middle::ty::{Instance, Ty, TyKind};
|
use rustc_middle::ty::{self, Instance, Ty};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{
|
use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
|
||||||
call::{ArgAbi, ArgAttribute, ArgAttributes, FnAbi, PassMode},
|
use std::assert_matches::assert_matches;
|
||||||
Size,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl<'tcx> CodegenCx<'tcx> {
|
impl<'tcx> CodegenCx<'tcx> {
|
||||||
// Entry points declare their "interface" (all uniforms, inputs, outputs, etc.) as parameters.
|
// Entry points declare their "interface" (all uniforms, inputs, outputs, etc.) as parameters.
|
||||||
@ -47,43 +46,53 @@ impl<'tcx> CodegenCx<'tcx> {
|
|||||||
let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(fn_hir_id));
|
let body = self.tcx.hir().body(self.tcx.hir().body_owned_by(fn_hir_id));
|
||||||
body.params
|
body.params
|
||||||
};
|
};
|
||||||
const EMPTY: ArgAttribute = ArgAttribute::empty();
|
for (arg_abi, hir_param) in fn_abi.args.iter().zip(hir_params) {
|
||||||
for (abi, hir_param) in fn_abi.args.iter().zip(hir_params) {
|
match arg_abi.mode {
|
||||||
match abi.mode {
|
PassMode::Direct(_) => {}
|
||||||
PassMode::Direct(_)
|
PassMode::Pair(..) => {
|
||||||
| PassMode::Indirect { .. }
|
// FIXME(eddyb) implement `ScalarPair` `Input`s, or change
|
||||||
// plain DST/RTA/VLA
|
// the `FnAbi` readjustment to only use `PassMode::Pair` for
|
||||||
| PassMode::Pair(
|
// pointers to `!Sized` types, but not other `ScalarPair`s.
|
||||||
ArgAttributes {
|
if !matches!(arg_abi.layout.ty.kind(), ty::Ref(..)) {
|
||||||
pointee_size: Size::ZERO,
|
self.tcx.sess.span_err(
|
||||||
..
|
|
||||||
},
|
|
||||||
ArgAttributes { regular: EMPTY, .. },
|
|
||||||
)
|
|
||||||
// DST struct with fields before the DST member
|
|
||||||
| PassMode::Pair(
|
|
||||||
ArgAttributes { .. },
|
|
||||||
ArgAttributes {
|
|
||||||
pointee_size: Size::ZERO,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
) => {}
|
|
||||||
_ => self.tcx.sess.span_err(
|
|
||||||
hir_param.ty_span,
|
hir_param.ty_span,
|
||||||
&format!("PassMode {:?} invalid for entry point parameter", abi.mode),
|
&format!(
|
||||||
|
"entry point parameter type not yet supported \
|
||||||
|
(`{}` has `ScalarPair` ABI but is not a `&T`)",
|
||||||
|
arg_abi.layout.ty
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// FIXME(eddyb) support these (by just ignoring them) - if there
|
||||||
|
// is any validation concern, it should be done on the types.
|
||||||
|
PassMode::Ignore => self.tcx.sess.span_err(
|
||||||
|
hir_param.ty_span,
|
||||||
|
&format!(
|
||||||
|
"entry point parameter type not yet supported \
|
||||||
|
(`{}` has size `0`)",
|
||||||
|
arg_abi.layout.ty
|
||||||
|
),
|
||||||
|
),
|
||||||
|
_ => span_bug!(
|
||||||
|
hir_param.ty_span,
|
||||||
|
"query hooks should've made this `PassMode` impossible: {:#?}",
|
||||||
|
arg_abi
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let PassMode::Ignore = fn_abi.ret.mode {
|
if fn_abi.ret.layout.ty.is_unit() {
|
||||||
|
assert_matches!(fn_abi.ret.mode, PassMode::Ignore);
|
||||||
} else {
|
} else {
|
||||||
self.tcx.sess.span_err(
|
self.tcx.sess.span_err(
|
||||||
span,
|
span,
|
||||||
&format!(
|
&format!(
|
||||||
"PassMode {:?} invalid for entry point return type",
|
"entry point should return `()`, not `{}`",
|
||||||
fn_abi.ret.mode
|
fn_abi.ret.layout.ty
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// let execution_model = entry.execution_model;
|
// let execution_model = entry.execution_model;
|
||||||
let fn_id = self.shader_entry_stub(
|
let fn_id = self.shader_entry_stub(
|
||||||
span,
|
span,
|
||||||
@ -168,7 +177,7 @@ impl<'tcx> CodegenCx<'tcx> {
|
|||||||
// FIXME(eddyb) also check the type for compatibility with being
|
// FIXME(eddyb) also check the type for compatibility with being
|
||||||
// part of the interface, including potentially `Sync`ness etc.
|
// part of the interface, including potentially `Sync`ness etc.
|
||||||
let (value_ty, mutbl, is_ref) = match *layout.ty.kind() {
|
let (value_ty, mutbl, is_ref) = match *layout.ty.kind() {
|
||||||
TyKind::Ref(_, pointee_ty, mutbl) => (pointee_ty, mutbl, true),
|
ty::Ref(_, pointee_ty, mutbl) => (pointee_ty, mutbl, true),
|
||||||
_ => (layout.ty, hir::Mutability::Not, false),
|
_ => (layout.ty, hir::Mutability::Not, false),
|
||||||
};
|
};
|
||||||
let spirv_ty = self.layout_of(value_ty).spirv_type(hir_param.ty_span, self);
|
let spirv_ty = self.layout_of(value_ty).spirv_type(hir_param.ty_span, self);
|
||||||
@ -396,7 +405,7 @@ impl<'tcx> CodegenCx<'tcx> {
|
|||||||
// Compute call argument(s) to match what the Rust entry `fn` expects,
|
// Compute call argument(s) to match what the Rust entry `fn` expects,
|
||||||
// starting from the `value_ptr` pointing to a `value_spirv_type`
|
// starting from the `value_ptr` pointing to a `value_spirv_type`
|
||||||
// (e.g. `Input` doesn't use indirection, so we have to load from it).
|
// (e.g. `Input` doesn't use indirection, so we have to load from it).
|
||||||
if let TyKind::Ref(..) = entry_arg_abi.layout.ty.kind() {
|
if let ty::Ref(..) = entry_arg_abi.layout.ty.kind() {
|
||||||
call_args.push(value_ptr);
|
call_args.push(value_ptr);
|
||||||
match entry_arg_abi.mode {
|
match entry_arg_abi.mode {
|
||||||
PassMode::Direct(_) => assert_eq!(value_len, None),
|
PassMode::Direct(_) => assert_eq!(value_len, None),
|
||||||
@ -405,16 +414,14 @@ impl<'tcx> CodegenCx<'tcx> {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert_eq!(storage_class, StorageClass::Input);
|
assert_eq!(storage_class, StorageClass::Input);
|
||||||
|
assert_matches!(entry_arg_abi.mode, PassMode::Direct(_));
|
||||||
|
|
||||||
call_args.push(match entry_arg_abi.mode {
|
let value = bx.load(
|
||||||
PassMode::Indirect { .. } => value_ptr,
|
|
||||||
PassMode::Direct(_) => bx.load(
|
|
||||||
entry_arg_abi.layout.spirv_type(hir_param.ty_span, bx),
|
entry_arg_abi.layout.spirv_type(hir_param.ty_span, bx),
|
||||||
value_ptr,
|
value_ptr,
|
||||||
entry_arg_abi.layout.align.abi,
|
entry_arg_abi.layout.align.abi,
|
||||||
),
|
);
|
||||||
_ => unreachable!(),
|
call_args.push(value);
|
||||||
});
|
|
||||||
assert_eq!(value_len, None);
|
assert_eq!(value_len, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,10 @@ impl<'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type {
|
fn cast_backend_type(&self, ty: &CastTarget) -> Self::Type {
|
||||||
ty.spirv_type(DUMMY_SP, self)
|
bug!(
|
||||||
|
"cast_backend_type({:?}): query hooks should've made `PassMode::Cast` impossible",
|
||||||
|
ty
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type {
|
fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type {
|
||||||
@ -84,7 +87,10 @@ impl<'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reg_backend_type(&self, ty: &Reg) -> Self::Type {
|
fn reg_backend_type(&self, ty: &Reg) -> Self::Type {
|
||||||
ty.spirv_type(DUMMY_SP, self)
|
bug!(
|
||||||
|
"reg_backend_type({:?}): query hooks should've made `PassMode::Cast` impossible",
|
||||||
|
ty
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type {
|
fn immediate_backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type {
|
||||||
|
Loading…
Reference in New Issue
Block a user