Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate #[spirv(block)] and auto-wrap in "interface blocks" instead. #576

Merged
merged 8 commits into from
Apr 5, 2021
43 changes: 3 additions & 40 deletions crates/rustc_codegen_spirv/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,6 @@ impl<'tcx> ConvSpirvType<'tcx> for CastTarget {
field_types: args,
field_offsets,
field_names: None,
is_block: false,
}
.def(span, cx)
}
Expand Down Expand Up @@ -325,34 +324,6 @@ fn trans_type_impl<'tcx>(
) -> Word {
if let TyKind::Adt(adt, substs) = *ty.ty.kind() {
let attrs = AggregatedSpirvAttributes::parse(cx, cx.tcx.get_attrs(adt.did));
if attrs.block.is_some() {
if !adt.is_struct() {
cx.tcx.sess.span_err(
span,
&format!(
"`#[spirv(block)]` can only be used on a `struct`, \
but `{}` is a `{}`",
ty.ty,
adt.descr(),
),
);
}

if !matches!(ty.abi, Abi::Aggregate { .. }) {
cx.tcx.sess.span_err(
span,
&format!(
"`#[spirv(block)]` can only be used on aggregates, \
but `{}` has `Abi::{:?}`",
ty.ty, ty.abi,
),
);
}

assert!(matches!(ty.fields, FieldsShape::Arbitrary { .. }));

return trans_struct(cx, span, ty, true);
}

if let Some(intrinsic_type_attr) = attrs.intrinsic_type.map(|attr| attr.value) {
if let Ok(spirv_type) = trans_intrinsic_type(cx, span, ty, substs, intrinsic_type_attr)
Expand All @@ -361,6 +332,7 @@ fn trans_type_impl<'tcx>(
}
}
}

// Note: ty.layout is orthogonal to ty.ty, e.g. `ManuallyDrop<Result<isize, isize>>` has abi
// `ScalarPair`.
// There's a few layers that we go through here. First we inspect layout.abi, then if relevant, layout.fields, etc.
Expand All @@ -372,7 +344,6 @@ fn trans_type_impl<'tcx>(
field_types: Vec::new(),
field_offsets: Vec::new(),
field_names: None,
is_block: false,
}
.def_with_name(cx, span, TyLayoutNameKey::from(ty)),
Abi::Scalar(ref scalar) => trans_scalar(cx, span, ty, scalar, None, is_immediate),
Expand All @@ -392,7 +363,6 @@ fn trans_type_impl<'tcx>(
field_types: vec![one_spirv, two_spirv],
field_offsets: vec![one_offset, two_offset],
field_names: None,
is_block: false,
}
.def_with_name(cx, span, TyLayoutNameKey::from(ty))
}
Expand Down Expand Up @@ -621,7 +591,6 @@ fn trans_aggregate<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>
field_types: Vec::new(),
field_offsets: Vec::new(),
field_names: None,
is_block: false,
}
.def_with_name(cx, span, TyLayoutNameKey::from(ty))
} else {
Expand All @@ -642,7 +611,7 @@ fn trans_aggregate<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>
FieldsShape::Arbitrary {
offsets: _,
memory_index: _,
} => trans_struct(cx, span, ty, false),
} => trans_struct(cx, span, ty),
}
}

Expand Down Expand Up @@ -672,12 +641,7 @@ pub fn auto_struct_layout<'tcx>(
}

// see struct_llfields in librustc_codegen_llvm for implementation hints
fn trans_struct<'tcx>(
cx: &CodegenCx<'tcx>,
span: Span,
ty: TyAndLayout<'tcx>,
is_block: bool,
) -> Word {
fn trans_struct<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>) -> Word {
if let TyKind::Foreign(_) = ty.ty.kind() {
// "An unsized FFI type that is opaque to Rust", `extern type A;` (currently unstable)
if cx.kernel_mode {
Expand Down Expand Up @@ -726,7 +690,6 @@ fn trans_struct<'tcx>(
field_types,
field_offsets,
field_names: Some(field_names),
is_block,
}
.def_with_name(cx, span, TyLayoutNameKey::from(ty))
}
Expand Down
10 changes: 10 additions & 0 deletions crates/rustc_codegen_spirv/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,16 @@ impl CheckSpirvAttrVisitor<'_> {
},
}
}

// At this point we have all of the attributes (valid for this target),
// so we can perform further checks, emit warnings, etc.

if let Some(block_attr) = aggregated_attrs.block {
self.tcx.sess.span_warn(
block_attr.span,
"#[spirv(block)] is no longer needed and should be removed",
);
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
SpirvType::Image { .. } => self.fatal("cannot memset image"),
SpirvType::Sampler => self.fatal("cannot memset sampler"),
SpirvType::SampledImage { .. } => self.fatal("cannot memset sampled image"),
SpirvType::InterfaceBlock { .. } => self.fatal("cannot memset interface block"),
}
}

Expand Down Expand Up @@ -288,6 +289,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
SpirvType::Image { .. } => self.fatal("cannot memset image"),
SpirvType::Sampler => self.fatal("cannot memset sampler"),
SpirvType::SampledImage { .. } => self.fatal("cannot memset sampled image"),
SpirvType::InterfaceBlock { .. } => self.fatal("cannot memset interface block"),
}
}

Expand Down Expand Up @@ -1041,6 +1043,10 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
SpirvType::Array { element, .. }
| SpirvType::RuntimeArray { element, .. }
| SpirvType::Vector { element, .. } => element,
SpirvType::InterfaceBlock { inner_type } => {
assert_eq!(idx, 0);
inner_type
}
other => self.fatal(&format!(
"struct_gep not on struct, array, or vector type: {:?}, index {}",
other, idx
Expand Down
5 changes: 4 additions & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ impl<'tcx> ConstMethods<'tcx> for CodegenCx<'tcx> {
field_types,
field_offsets,
field_names: None,
is_block: false,
}
.def(DUMMY_SP, self);
self.constant_composite(struct_ty, elts.iter().map(|f| f.def_cx(self)).collect())
Expand Down Expand Up @@ -524,6 +523,10 @@ impl<'tcx> CodegenCx<'tcx> {
.tcx
.sess
.fatal("Cannot create a constant sampled image value"),
SpirvType::InterfaceBlock { .. } => self
.tcx
.sess
.fatal("Cannot create a constant interface block value"),
}
}
}
Loading