Skip to content

Commit 2dc88f2

Browse files
committed
Simplify FnAbi handling for the fewer PassModes possible now.
1 parent 6d43d60 commit 2dc88f2

File tree

5 files changed

+96
-204
lines changed

5 files changed

+96
-204
lines changed

crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 11 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_middle::{bug, span_bug};
1919
use rustc_span::def_id::DefId;
2020
use rustc_span::Span;
2121
use rustc_span::DUMMY_SP;
22-
use rustc_target::abi::call::{ArgAbi, ArgAttributes, CastTarget, FnAbi, PassMode, Reg, RegKind};
22+
use rustc_target::abi::call::{ArgAbi, ArgAttributes, FnAbi, PassMode};
2323
use rustc_target::abi::{Abi, Align, FieldsShape, Primitive, Scalar, Size, VariantIdx, Variants};
2424
use rustc_target::spec::abi::Abi as SpecAbi;
2525
use std::cell::RefCell;
@@ -236,87 +236,6 @@ impl<'tcx> ConvSpirvType<'tcx> for PointeeTy<'tcx> {
236236
}
237237
}
238238

239-
impl<'tcx> ConvSpirvType<'tcx> for Reg {
240-
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
241-
match self.kind {
242-
RegKind::Integer => SpirvType::Integer(self.size.bits() as u32, false).def(span, cx),
243-
RegKind::Float => SpirvType::Float(self.size.bits() as u32).def(span, cx),
244-
RegKind::Vector => SpirvType::Vector {
245-
element: SpirvType::Integer(8, false).def(span, cx),
246-
count: self.size.bytes() as u32,
247-
}
248-
.def(span, cx),
249-
}
250-
}
251-
}
252-
253-
impl<'tcx> ConvSpirvType<'tcx> for CastTarget {
254-
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
255-
let rest_ll_unit = self.rest.unit.spirv_type(span, cx);
256-
let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
257-
(0, 0)
258-
} else {
259-
(
260-
self.rest.total.bytes() / self.rest.unit.size.bytes(),
261-
self.rest.total.bytes() % self.rest.unit.size.bytes(),
262-
)
263-
};
264-
265-
if self.prefix.iter().all(|x| x.is_none()) {
266-
// Simplify to a single unit when there is no prefix and size <= unit size
267-
if self.rest.total <= self.rest.unit.size {
268-
return rest_ll_unit;
269-
}
270-
271-
// Simplify to array when all chunks are the same size and type
272-
if rem_bytes == 0 {
273-
return SpirvType::Array {
274-
element: rest_ll_unit,
275-
count: cx.constant_u32(span, rest_count as u32),
276-
}
277-
.def(span, cx);
278-
}
279-
}
280-
281-
// Create list of fields in the main structure
282-
let mut args: Vec<_> = self
283-
.prefix
284-
.iter()
285-
.flatten()
286-
.map(|&kind| {
287-
Reg {
288-
kind,
289-
size: self.prefix_chunk_size,
290-
}
291-
.spirv_type(span, cx)
292-
})
293-
.chain((0..rest_count).map(|_| rest_ll_unit))
294-
.collect();
295-
296-
// Append final integer
297-
if rem_bytes != 0 {
298-
// Only integers can be really split further.
299-
assert_eq!(self.rest.unit.kind, RegKind::Integer);
300-
args.push(SpirvType::Integer(rem_bytes as u32 * 8, false).def(span, cx));
301-
}
302-
303-
let size = Some(self.size(cx));
304-
let align = self.align(cx);
305-
let (field_offsets, computed_size, computed_align) = auto_struct_layout(cx, &args);
306-
assert_eq!(size, computed_size, "{:#?}", self);
307-
assert_eq!(align, computed_align, "{:#?}", self);
308-
SpirvType::Adt {
309-
def_id: None,
310-
size,
311-
align,
312-
field_types: args,
313-
field_offsets,
314-
field_names: None,
315-
}
316-
.def(span, cx)
317-
}
318-
}
319-
320239
impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
321240
fn spirv_type(&self, span: Span, cx: &CodegenCx<'tcx>) -> Word {
322241
let mut argument_types = Vec::new();
@@ -326,14 +245,11 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
326245
PassMode::Direct(_) | PassMode::Pair(..) => {
327246
self.ret.layout.spirv_type_immediate(span, cx)
328247
}
329-
PassMode::Cast(cast_target) => cast_target.spirv_type(span, cx),
330-
PassMode::Indirect { .. } => {
331-
let pointee = self.ret.layout.spirv_type(span, cx);
332-
let pointer = SpirvType::Pointer { pointee }.def(span, cx);
333-
// Important: the return pointer comes *first*, not last.
334-
argument_types.push(pointer);
335-
SpirvType::Void.def(span, cx)
336-
}
248+
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
249+
span,
250+
"query hooks should've made this `PassMode` impossible: {:#?}",
251+
self.ret
252+
),
337253
};
338254

339255
for arg in &self.args {
@@ -349,27 +265,11 @@ impl<'tcx> ConvSpirvType<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
349265
));
350266
continue;
351267
}
352-
PassMode::Cast(cast_target) => cast_target.spirv_type(span, cx),
353-
PassMode::Indirect {
354-
extra_attrs: Some(_),
355-
..
356-
} => {
357-
let ptr_ty = cx.tcx.mk_mut_ptr(arg.layout.ty);
358-
let ptr_layout = cx.layout_of(ptr_ty);
359-
argument_types.push(scalar_pair_element_backend_type(
360-
cx, span, ptr_layout, 0, true,
361-
));
362-
argument_types.push(scalar_pair_element_backend_type(
363-
cx, span, ptr_layout, 1, true,
364-
));
365-
continue;
366-
}
367-
PassMode::Indirect {
368-
extra_attrs: None, ..
369-
} => {
370-
let pointee = arg.layout.spirv_type(span, cx);
371-
SpirvType::Pointer { pointee }.def(span, cx)
372-
}
268+
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
269+
span,
270+
"query hooks should've made this `PassMode` impossible: {:#?}",
271+
arg
272+
),
373273
};
374274
argument_types.push(arg_type);
375275
}

crates/rustc_codegen_spirv/src/builder/intrinsics.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_middle::ty::{FnDef, Instance, ParamEnv, Ty, TyKind};
1313
use rustc_span::source_map::Span;
1414
use rustc_span::sym;
1515
use rustc_target::abi::call::{FnAbi, PassMode};
16+
use std::assert_matches::assert_matches;
1617

1718
fn int_type_width_signed(ty: Ty<'_>, cx: &CodegenCx<'_>) -> Option<(u64, bool)> {
1819
match ty.kind() {
@@ -100,16 +101,9 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
100101

101102
sym::volatile_load | sym::unaligned_volatile_load => {
102103
let ptr = args[0].immediate();
103-
if let PassMode::Cast(ty) = fn_abi.ret.mode {
104-
let pointee = ty.spirv_type(self.span(), self);
105-
let pointer = SpirvType::Pointer { pointee }.def(self.span(), self);
106-
let ptr = self.pointercast(ptr, pointer);
107-
self.volatile_load(pointee, ptr)
108-
} else {
109-
let layout = self.layout_of(substs.type_at(0));
110-
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
111-
self.to_immediate(load, layout)
112-
}
104+
let layout = self.layout_of(substs.type_at(0));
105+
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
106+
self.to_immediate(load, layout)
113107
}
114108

115109
sym::prefetch_read_data
@@ -330,13 +324,10 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
330324
};
331325

332326
if !fn_abi.ret.is_ignore() {
333-
if let PassMode::Cast(_ty) = fn_abi.ret.mode {
334-
self.fatal("TODO: PassMode::Cast not implemented yet in intrinsics");
335-
} else {
336-
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
337-
.val
338-
.store(self, result);
339-
}
327+
assert_matches!(fn_abi.ret.mode, PassMode::Direct(_) | PassMode::Pair(..));
328+
OperandRef::from_immediate_or_packed_pair(self, value, result.layout)
329+
.val
330+
.store(self, result);
340331
}
341332
}
342333

crates/rustc_codegen_spirv/src/builder/mod.rs

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc_errors::DiagnosticBuilder;
2424
use rustc_middle::mir::coverage::{
2525
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
2626
};
27+
use rustc_middle::span_bug;
2728
use rustc_middle::ty::layout::{
2829
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
2930
TyAndLayout,
@@ -286,27 +287,18 @@ impl<'a, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'tcx> {
286287
val
287288
}
288289
match arg_abi.mode {
289-
PassMode::Ignore => (),
290+
PassMode::Ignore => {}
291+
PassMode::Direct(_) => {
292+
OperandValue::Immediate(next(self, idx)).store(self, dst);
293+
}
290294
PassMode::Pair(..) => {
291295
OperandValue::Pair(next(self, idx), next(self, idx)).store(self, dst);
292296
}
293-
PassMode::Indirect {
294-
extra_attrs: Some(_),
295-
..
296-
} => OperandValue::Ref(
297-
next(self, idx),
298-
Some(next(self, idx)),
299-
arg_abi.layout.align.abi,
300-
)
301-
.store(self, dst),
302-
PassMode::Direct(_)
303-
| PassMode::Indirect {
304-
extra_attrs: None, ..
305-
}
306-
| PassMode::Cast(_) => {
307-
let next_arg = next(self, idx);
308-
self.store_arg(arg_abi, next_arg, dst);
309-
}
297+
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
298+
self.span(),
299+
"query hooks should've made this `PassMode` impossible: {:#?}",
300+
arg_abi
301+
),
310302
}
311303
}
312304

@@ -316,20 +308,16 @@ impl<'a, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'tcx> {
316308
val: Self::Value,
317309
dst: PlaceRef<'tcx, Self::Value>,
318310
) {
319-
if arg_abi.is_ignore() {
320-
return;
321-
}
322-
if arg_abi.is_sized_indirect() {
323-
OperandValue::Ref(val, None, arg_abi.layout.align.abi).store(self, dst);
324-
} else if arg_abi.is_unsized_indirect() {
325-
self.fatal("unsized `ArgAbi` must be handled through `store_fn_arg`");
326-
} else if let PassMode::Cast(cast) = arg_abi.mode {
327-
let cast_ty = cast.spirv_type(self.span(), self);
328-
let cast_ptr_ty = SpirvType::Pointer { pointee: cast_ty }.def(self.span(), self);
329-
let cast_dst = self.pointercast(dst.llval, cast_ptr_ty);
330-
self.store(val, cast_dst, arg_abi.layout.align.abi);
331-
} else {
332-
OperandValue::Immediate(val).store(self, dst);
311+
match arg_abi.mode {
312+
PassMode::Ignore => {}
313+
PassMode::Direct(_) | PassMode::Pair(..) => {
314+
OperandValue::Immediate(val).store(self, dst);
315+
}
316+
PassMode::Cast(_) | PassMode::Indirect { .. } => span_bug!(
317+
self.span(),
318+
"query hooks should've made this `PassMode` impossible: {:#?}",
319+
arg_abi
320+
),
333321
}
334322
}
335323

0 commit comments

Comments
 (0)