Skip to content

Commit 0c6e50c

Browse files
committed
vec3: SIMD to C, directly calling the rust layout function is easier
1 parent 93378c3 commit 0c6e50c

File tree

1 file changed

+58
-41
lines changed
  • crates/rustc_codegen_spirv/src

1 file changed

+58
-41
lines changed

crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ use crate::codegen_cx::CodegenCx;
66
use crate::spirv_type::SpirvType;
77
use itertools::Itertools;
88
use rspirv::spirv::{Dim, ImageFormat, StorageClass, Word};
9-
use rustc_abi::ExternAbi as Abi;
109
use rustc_abi::{
1110
Align, BackendRepr, FieldIdx, FieldsShape, LayoutData, Primitive, ReprFlags, ReprOptions,
1211
Scalar, Size, TagEncoding, VariantIdx, Variants,
1312
};
13+
use rustc_abi::{ExternAbi as Abi, Integer};
1414
use rustc_data_structures::fx::FxHashMap;
1515
use rustc_errors::ErrorGuaranteed;
1616
use rustc_index::{Idx, IndexVec};
1717
use rustc_middle::query::Providers;
18-
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
18+
use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout};
1919
use rustc_middle::ty::{
20-
self, Const, CoroutineArgs, CoroutineArgsExt as _, FieldDef, FloatTy, IntTy, PolyFnSig, Ty,
21-
TyCtxt, TyKind, UintTy, VariantDef,
20+
self, Const, CoroutineArgs, CoroutineArgsExt as _, FloatTy, IntTy, PolyFnSig, Ty, TyCtxt,
21+
TyKind, UintTy,
2222
};
2323
use rustc_middle::ty::{GenericArgsRef, ScalarInt};
2424
use rustc_middle::{bug, span_bug};
@@ -167,14 +167,17 @@ pub(crate) fn provide(providers: &mut Providers) {
167167

168168
fn layout_of<'tcx>(
169169
tcx: TyCtxt<'tcx>,
170-
mut key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
170+
key: ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>,
171171
) -> Result<TyAndLayout<'tcx>, &'tcx ty::layout::LayoutError<'tcx>> {
172172
// HACK(eddyb) to special-case any types at all, they must be normalized,
173173
// but when normalization would be needed, `layout_of`'s default provider
174174
// recurses (supposedly for caching reasons), i.e. its calls `layout_of`
175175
// w/ the normalized type in input, which once again reaches this hook,
176176
// without ever needing any explicit normalization here.
177-
let ty = key.value;
177+
let ty::PseudoCanonicalInput {
178+
typing_env,
179+
value: ty,
180+
} = key;
178181

179182
// HACK(eddyb) bypassing upstream `#[repr(simd)]` changes (see also
180183
// the later comment above `check_well_formed`, for more details).
@@ -183,42 +186,56 @@ pub(crate) fn provide(providers: &mut Providers) {
183186
let def: &ty::AdtDef<'tcx> = def;
184187
let args: &ty::GenericArgs<'tcx> = args;
185188

186-
let mut repr_flags = def.repr().flags;
187-
repr_flags.remove(ReprFlags::IS_SIMD);
188-
repr_flags.insert(ReprFlags::IS_C);
189-
let def_c = tcx.mk_adt_def(
190-
def.did(),
191-
def.adt_kind(),
192-
def.variants()
193-
.iter()
194-
.map(|v| {
195-
VariantDef::new(
196-
v.name,
197-
None,
198-
v.ctor,
199-
v.discr,
200-
v.fields
201-
.iter()
202-
.map(|f| FieldDef {
203-
did: f.did,
204-
name: f.name,
205-
vis: f.vis,
206-
safety: f.safety,
207-
value: f.value,
208-
})
209-
.collect(),
210-
v.def_id,
211-
None,
212-
v.is_field_list_non_exhaustive(),
213-
)
214-
})
215-
.collect(),
216-
ReprOptions {
217-
flags: repr_flags,
218-
..def.repr()
219-
},
189+
// HACK(firestar99) we don't special case SIMD anymore for glam
190+
// we now want it to behave like `#[repr(C)]`. But to not break
191+
// old versions of glam immediately, I made this hack to remap
192+
// SIMD to C.
193+
let mut repr = def.repr();
194+
repr.flags.remove(ReprFlags::IS_SIMD);
195+
repr.flags.insert(ReprFlags::IS_C);
196+
197+
// Much of the following is copied from `rustc_ty_utils::layout::layout_of_uncached` and simplified
198+
let cx = LayoutCx::new(tcx, typing_env);
199+
200+
// Cache the field layouts, copied
201+
let variants = def
202+
.variants()
203+
.iter()
204+
.map(|v| {
205+
v.fields
206+
.iter()
207+
.map(|field| cx.layout_of(field.ty(tcx, args)))
208+
.collect::<Result<IndexVec<_, _>, _>>()
209+
})
210+
.collect::<Result<IndexVec<VariantIdx, _>, _>>()?;
211+
212+
let result = cx.calc.layout_of_struct_or_enum(
213+
&repr,
214+
&variants,
215+
// no enum
216+
false,
217+
// does not contain UnsafeCell and variants
218+
false,
219+
// copied
220+
tcx.layout_scalar_valid_range(def.did()),
221+
// ignored, enum only
222+
|_, _| (Integer::I32, false),
223+
// ignored, enum only
224+
std::iter::empty(),
225+
// ignored, enum only
226+
false,
227+
// we are always sized
228+
true,
220229
);
221-
key.value = Ty::new_adt(tcx, def_c, args);
230+
231+
let layout = match result {
232+
Ok(layout_data) => tcx.mk_layout(layout_data),
233+
Err(e) => cx
234+
.tcx()
235+
.dcx()
236+
.fatal(format!("SIMD to C repr remap failed: {e:?}")),
237+
};
238+
return Ok(TyAndLayout { ty, layout });
222239
}
223240
_ => (),
224241
};

0 commit comments

Comments
 (0)