Skip to content

Commit 24201f6

Browse files
committed
Port backend internals and ABI plumbing to latest nightly
1 parent 7db643c commit 24201f6

12 files changed

Lines changed: 105 additions & 67 deletions

File tree

crates/rustc_codegen_spirv/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ mod maybe_pqp_cg_ssa;
329329
fs::write(out_dir.join("pqp_cg_ssa.rs"), pqp_cg_ssa_top_level)?;
330330

331331
println!("cargo::rustc-check-cfg=cfg(rustc_codegen_spirv_disable_pqp_cg_ssa)");
332+
println!("cargo::rustc-check-cfg=cfg(bootstrap)");
332333

333334
// HACK(eddyb) `if cfg!(llvm_enzyme)` added upstream for autodiff support.
334335
println!("cargo::rustc-check-cfg=cfg(llvm_enzyme)");

crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use rustc_abi::{
1313
use rustc_data_structures::fx::FxHashMap;
1414
use rustc_errors::ErrorGuaranteed;
1515
use rustc_index::Idx;
16-
use rustc_middle::query::Providers;
1716
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
1817
use rustc_middle::ty::{
1918
self, Const, CoroutineArgs, CoroutineArgsExt as _, FloatTy, IntTy, PolyFnSig, Ty, TyCtxt,
20-
TyKind, UintTy,
19+
TyKind, UintTy, ValTreeKindExt,
2120
};
2221
use rustc_middle::ty::{GenericArgsRef, ScalarInt};
22+
use rustc_middle::util::Providers;
2323
use rustc_middle::{bug, span_bug};
2424
use rustc_span::DUMMY_SP;
2525
use rustc_span::def_id::DefId;
@@ -29,6 +29,19 @@ use std::cell::RefCell;
2929
use std::collections::hash_map::Entry;
3030
use std::fmt;
3131

32+
fn rewrite_c_abi_to_rust<'tcx>(
33+
fn_sig: ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>>,
34+
) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
35+
fn_sig.map_bound(|outer| {
36+
outer.map_bound(|mut inner| {
37+
if let Abi::C { .. } = inner.abi {
38+
inner.abi = Abi::Rust;
39+
}
40+
inner
41+
})
42+
})
43+
}
44+
3245
pub(crate) fn provide(providers: &mut Providers) {
3346
// This is a lil weird: so, we obviously don't support C ABIs at all. However, libcore does declare some extern
3447
// C functions:
@@ -44,18 +57,19 @@ pub(crate) fn provide(providers: &mut Providers) {
4457
// NOTE: this used to rewrite to `extern "unadjusted"`, but rustc now
4558
// validates `#[rustc_pass_indirectly_in_non_rustic_abis]` for non-Rust ABIs,
4659
// and `Unadjusted` does not satisfy that requirement.
47-
providers.fn_sig = |tcx, def_id| {
60+
providers.queries.fn_sig = |tcx, def_id| {
4861
// We can't capture the old fn_sig and just call that, because fn_sig is a `fn`, not a `Fn`, i.e. it can't
4962
// capture variables. Fortunately, the defaults are exposed (thanks rustdoc), so use that instead.
50-
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS.fn_sig)(tcx, def_id);
51-
result.map_bound(|outer| {
52-
outer.map_bound(|mut inner| {
53-
if let Abi::C { .. } = inner.abi {
54-
inner.abi = Abi::Rust;
55-
}
56-
inner
57-
})
58-
})
63+
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS.queries.fn_sig)(tcx, def_id);
64+
rewrite_c_abi_to_rust(result)
65+
};
66+
providers.extern_queries.fn_sig = |tcx, def_id| {
67+
// We can't capture the old fn_sig and just call that, because fn_sig is a `fn`, not a `Fn`, i.e. it can't
68+
// capture variables. Fortunately, the defaults are exposed (thanks rustdoc), so use that instead.
69+
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS
70+
.extern_queries
71+
.fn_sig)(tcx, def_id);
72+
rewrite_c_abi_to_rust(result)
5973
};
6074

6175
// For the Rust ABI, `FnAbi` adjustments are backend-agnostic, but they will
@@ -67,7 +81,7 @@ pub(crate) fn provide(providers: &mut Providers) {
6781
fn_abi: &'tcx FnAbi<'tcx, Ty<'tcx>>,
6882
) -> &'tcx FnAbi<'tcx, Ty<'tcx>> {
6983
let readjust_arg_abi = |arg: &ArgAbi<'tcx, Ty<'tcx>>| {
70-
let mut arg = ArgAbi::new(&tcx, arg.layout, |_, _, _| ArgAttributes::new());
84+
let mut arg = ArgAbi::new(&tcx, arg.layout, |_, _| ArgAttributes::new());
7185
// FIXME: this is bad! https://github.com/rust-lang/rust/issues/115666
7286
// <https://github.com/rust-lang/rust/commit/eaaa03faf77b157907894a4207d8378ecaec7b45>
7387
arg.make_direct_deprecated();
@@ -86,6 +100,12 @@ pub(crate) fn provide(providers: &mut Providers) {
86100
arg.mode = PassMode::Ignore;
87101
}
88102

103+
// SPIR-V backend lowers arguments by-value and cannot handle
104+
// backend-specific indirection/casts at this layer.
105+
if matches!(arg.mode, PassMode::Cast { .. } | PassMode::Indirect { .. }) {
106+
arg.mode = PassMode::Direct(ArgAttributes::new());
107+
}
108+
89109
arg
90110
};
91111
tcx.arena.alloc(FnAbi {
@@ -101,12 +121,22 @@ pub(crate) fn provide(providers: &mut Providers) {
101121
can_unwind: fn_abi.can_unwind,
102122
})
103123
}
104-
providers.fn_abi_of_fn_ptr = |tcx, key| {
105-
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS.fn_abi_of_fn_ptr)(tcx, key);
124+
providers.queries.fn_abi_of_fn_ptr = |tcx, key| {
125+
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS
126+
.queries
127+
.fn_abi_of_fn_ptr)(tcx, key);
128+
Ok(readjust_fn_abi(tcx, result?))
129+
};
130+
providers.queries.fn_abi_of_instance_no_deduced_attrs = |tcx, key| {
131+
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS
132+
.queries
133+
.fn_abi_of_instance_no_deduced_attrs)(tcx, key);
106134
Ok(readjust_fn_abi(tcx, result?))
107135
};
108-
providers.fn_abi_of_instance = |tcx, key| {
109-
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS.fn_abi_of_instance)(tcx, key);
136+
providers.queries.fn_abi_of_instance_raw = |tcx, key| {
137+
let result = (rustc_interface::DEFAULT_QUERY_PROVIDERS
138+
.queries
139+
.fn_abi_of_instance_raw)(tcx, key);
110140
Ok(readjust_fn_abi(tcx, result?))
111141
};
112142

@@ -116,7 +146,7 @@ pub(crate) fn provide(providers: &mut Providers) {
116146
//
117147
// FIXME(eddyb) same as the FIXME comment on `check_well_formed`:
118148
// need to migrate away from `#[repr(simd)]` ASAP.
119-
providers.check_mono_item = |_, _| {};
149+
providers.queries.check_mono_item = |_, _| {};
120150
}
121151

122152
/// If a struct contains a pointer to itself, even indirectly, then doing a naiive recursive walk
@@ -291,6 +321,7 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> {
291321
span = cx.tcx.def_span(adt.did());
292322
}
293323

324+
#[allow(deprecated)]
294325
let attrs = AggregatedSpirvAttributes::parse(cx, cx.tcx.get_all_attrs(adt.did()));
295326

296327
if let Some(intrinsic_type_attr) = attrs.intrinsic_type.map(|attr| attr.value)
@@ -395,6 +426,10 @@ impl<'tcx> ConvSpirvType<'tcx> for TyAndLayout<'tcx> {
395426
}
396427
.def(span, cx)
397428
}
429+
BackendRepr::ScalableVector { .. } => cx
430+
.tcx
431+
.dcx()
432+
.fatal("scalable vectors are not supported in SPIR-V backend"),
398433
BackendRepr::Memory { sized: _ } => trans_aggregate(cx, span, *self),
399434
}
400435
}
@@ -614,22 +649,11 @@ fn trans_aggregate<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>
614649
.def(span, cx)
615650
}
616651
}
617-
FieldsShape::Arbitrary {
618-
offsets: _,
619-
memory_index: _,
620-
} => trans_struct_or_union(cx, span, ty, None),
652+
FieldsShape::Arbitrary { .. } => trans_struct_or_union(cx, span, ty, None),
621653
}
622654
}
623655

624-
#[cfg_attr(
625-
not(rustc_codegen_spirv_disable_pqp_cg_ssa),
626-
expect(
627-
unused,
628-
reason = "actually used from \
629-
`<rustc_codegen_ssa::traits::ConstCodegenMethods for CodegenCx<'_>>::const_struct`, \
630-
but `rustc_codegen_ssa` being `pqp_cg_ssa` makes that trait unexported"
631-
)
632-
)]
656+
#[cfg_attr(not(rustc_codegen_spirv_disable_pqp_cg_ssa), allow(unused))]
633657
// returns (field_offsets, size, align)
634658
pub fn auto_struct_layout(
635659
cx: &CodegenCx<'_>,
@@ -866,7 +890,8 @@ fn trans_intrinsic_type<'tcx>(
866890
} = const_.to_value();
867891
assert!(const_ty.is_integral());
868892
const_val
869-
.try_to_scalar_int()
893+
.try_to_scalar()
894+
.and_then(|scalar| scalar.try_to_scalar_int().ok())
870895
.and_then(P::from_scalar_int)
871896
.ok_or_else(|| {
872897
cx.tcx

crates/rustc_codegen_spirv/src/attr.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,9 @@ pub(crate) fn provide(providers: &mut Providers) {
514514
*providers = Providers {
515515
check_mod_attrs: |tcx, module_def_id| {
516516
// Run both the default checks, and our `#[spirv(...)]` ones.
517-
(rustc_interface::DEFAULT_QUERY_PROVIDERS.check_mod_attrs)(tcx, module_def_id);
517+
(rustc_interface::DEFAULT_QUERY_PROVIDERS
518+
.queries
519+
.check_mod_attrs)(tcx, module_def_id);
518520
check_mod_attrs(tcx, module_def_id);
519521
},
520522
..*providers
@@ -537,10 +539,10 @@ fn parse_attrs_for_checking<'a>(
537539
Attribute::Unparsed(item) => {
538540
// #[...]
539541
let s = &item.path.segments;
540-
if let Some(rust_gpu) = s.get(0) && rust_gpu.name == sym.rust_gpu {
542+
if let Some(rust_gpu) = s.get(0) && *rust_gpu == sym.rust_gpu {
541543
// #[rust_gpu ...]
542544
match s.get(1) {
543-
Some(command) if command.name == sym.spirv_attr_with_version => {
545+
Some(command) if *command == sym.spirv_attr_with_version => {
544546
// #[rust_gpu::spirv ...]
545547
if let Some(args) = attr.meta_item_list() {
546548
// #[rust_gpu::spirv(...)]
@@ -554,11 +556,11 @@ fn parse_attrs_for_checking<'a>(
554556
))
555557
}
556558
}
557-
Some(command) if command.name == sym.vector => {
559+
Some(command) if *command == sym.vector => {
558560
// #[rust_gpu::vector ...]
559561
match s.get(2) {
560562
// #[rust_gpu::vector::v1]
561-
Some(version) if version.name == sym.v1 => {
563+
Some(version) if *version == sym.v1 => {
562564
Ok(SmallVec::from_iter([
563565
Ok((attr.span(), SpirvAttribute::IntrinsicType(IntrinsicType::Vector)))
564566
]))

crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,8 +1826,8 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
18261826
}
18271827

18281828
fn scalable_alloca(&mut self, elt: u64, align: Align, element_ty: Ty<'_>) -> Self::Value {
1829-
let element = self.layout_of(element_ty).spirv_type(self.span(), self);
1830-
self.declare_func_local_var(self.type_array(element, elt), align)
1829+
let _ = (elt, align, element_ty);
1830+
self.fatal("scalable alloca is not supported in SPIR-V backend")
18311831
}
18321832

18331833
fn load(&mut self, ty: Self::Type, ptr: Self::Value, _align: Align) -> Self::Value {

crates/rustc_codegen_spirv/src/builder/intrinsics.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,15 @@ impl<'a, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'tcx> {
400400
todo!()
401401
}
402402

403-
fn va_start(&mut self, _val: Self::Value) -> Self::Value {
404-
todo!()
403+
fn va_start(&mut self, val: Self::Value) -> Self::Value {
404+
// SPIR-V backend has no variadic ABI support; keep the placeholder
405+
// operand unchanged so MIR lowering can proceed without crashing.
406+
val
405407
}
406408

407-
fn va_end(&mut self, _val: Self::Value) -> Self::Value {
408-
todo!()
409+
fn va_end(&mut self, val: Self::Value) -> Self::Value {
410+
// See `va_start` above.
411+
val
409412
}
410413
}
411414

crates/rustc_codegen_spirv/src/codegen_cx/constant.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,9 @@ impl<'tcx> CodegenCx<'tcx> {
343343
&& let Some(SpirvConst::ConstDataFromAlloc(alloc)) =
344344
self.builder.lookup_const_by_id(pointee)
345345
&& let SpirvType::Pointer { pointee } = self.lookup_type(ty)
346-
&& self.try_read_from_const_alloc(alloc, pointee).is_some()
346+
&& let Some(init) = self.try_read_from_const_alloc(alloc, pointee)
347347
{
348-
return self.static_addr_of(alloc, None);
348+
return self.static_addr_of_constant(init);
349349
}
350350

351351
if val.ty == ty {

crates/rustc_codegen_spirv/src/codegen_cx/declare.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ fn attrs_to_spirv(attrs: &CodegenFnAttrs) -> FunctionControl {
3939
}
4040

4141
impl<'tcx> CodegenCx<'tcx> {
42+
pub(crate) fn static_addr_of_constant(&self, cv: SpirvValue) -> SpirvValue {
43+
self.def_constant(
44+
self.type_ptr_to(cv.ty),
45+
SpirvConst::PtrTo {
46+
pointee: cv.def_cx(self),
47+
},
48+
)
49+
}
50+
4251
/// Returns a function if it already exists, or declares a header if it doesn't.
4352
pub fn get_fn_ext(&self, instance: Instance<'tcx>) -> SpirvFunctionCursor {
4453
assert!(!instance.args.has_infer());
@@ -133,6 +142,7 @@ impl<'tcx> CodegenCx<'tcx> {
133142
self.set_linkage(fn_id, symbol_name.to_owned(), linkage);
134143
}
135144

145+
#[allow(deprecated)]
136146
let attrs = AggregatedSpirvAttributes::parse(self, self.tcx.get_all_attrs(def_id));
137147
if let Some(entry) = attrs.entry.map(|attr| attr.value) {
138148
// HACK(eddyb) early insert to let `shader_entry_stub` call this
@@ -212,11 +222,14 @@ impl<'tcx> CodegenCx<'tcx> {
212222

213223
// HACK(eddyb) there is no good way to identify these definitions
214224
// (e.g. no `#[lang = "..."]` attribute), but this works well enough.
215-
if let Some("panic_nounwind_fmt" | "panic_explicit") =
216-
demangled_symbol_name.strip_prefix("core::panicking::")
225+
if let Some(name) = demangled_symbol_name.strip_prefix("core::panicking::")
226+
&& (name == "panic_explicit" || name.starts_with("panic_"))
217227
{
218228
self.panic_entry_points.borrow_mut().insert(def_id);
219229
}
230+
if demangled_symbol_name.ends_with("::precondition_check") {
231+
self.panic_entry_points.borrow_mut().insert(def_id);
232+
}
220233
if let Some(pieces_len) = demangled_symbol_name
221234
.strip_prefix("<core::fmt::Arguments>::new_const::<")
222235
.and_then(|s| s.strip_suffix(">"))
@@ -369,13 +382,7 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'tcx> {
369382

370383
impl<'tcx> StaticCodegenMethods for CodegenCx<'tcx> {
371384
fn static_addr_of(&self, alloc: ConstAllocation<'_>, _kind: Option<&str>) -> Self::Value {
372-
let cv = self.const_data_from_alloc(alloc);
373-
self.def_constant(
374-
self.type_ptr_to(cv.ty),
375-
SpirvConst::PtrTo {
376-
pointee: cv.def_cx(self),
377-
},
378-
)
385+
self.static_addr_of_constant(self.const_data_from_alloc(alloc))
379386
}
380387

381388
fn codegen_static(&mut self, def_id: DefId) {

crates/rustc_codegen_spirv/src/codegen_cx/type_.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ impl<'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'tcx> {
9797

9898
fn is_backend_immediate(&self, layout: TyAndLayout<'tcx>) -> bool {
9999
match layout.backend_repr {
100-
BackendRepr::Scalar(_) | BackendRepr::SimdVector { .. } => true,
100+
BackendRepr::Scalar(_)
101+
| BackendRepr::ScalableVector { .. }
102+
| BackendRepr::SimdVector { .. } => true,
101103
BackendRepr::ScalarPair(..) => false,
102104
BackendRepr::Memory { .. } => layout.is_zst(),
103105
}
@@ -107,6 +109,7 @@ impl<'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'tcx> {
107109
match layout.backend_repr {
108110
BackendRepr::ScalarPair(..) => true,
109111
BackendRepr::Scalar(_)
112+
| BackendRepr::ScalableVector { .. }
110113
| BackendRepr::SimdVector { .. }
111114
| BackendRepr::Memory { .. } => false,
112115
}

crates/rustc_codegen_spirv/src/custom_decorations.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use rustc_span::{Span, source_map::SourceMap};
1212
use smallvec::SmallVec;
1313
use std::borrow::Cow;
1414
use std::marker::PhantomData;
15-
use std::path::PathBuf;
1615
use std::sync::Arc;
1716
use std::{fmt, iter, slice, str};
1817

@@ -447,7 +446,7 @@ impl<'a> SpanRegenerator<'a> {
447446

448447
// HACK(eddyb) in case the file has changed, and because `SourceMap`
449448
// is strictly monotonic, we need to come up with some other name.
450-
let mut sm_file_name_candidates = [PathBuf::from(file_name).into()]
449+
let mut sm_file_name_candidates = [FileName::Custom(file_name.to_string())]
451450
.into_iter()
452451
.chain((0..).map(|i| FileName::Custom(format!("outdated({i}) {file_name}"))));
453452

crates/rustc_codegen_spirv/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,10 +228,10 @@ impl CodegenBackend for SpirvCodegenBackend {
228228
// FIXME(eddyb) this is currently only passed back to us, specifically
229229
// into `target_machine_factory` (which is a noop), but it might make
230230
// sense to move some of the target feature parsing into here.
231-
providers.global_backend_features = |_tcx, ()| vec![];
231+
providers.queries.global_backend_features = |_tcx, ()| vec![];
232232

233233
crate::abi::provide(providers);
234-
crate::attr::provide(providers);
234+
crate::attr::provide(&mut providers.queries);
235235
}
236236

237237
fn target_cpu(&self, sess: &Session) -> String {
@@ -324,7 +324,7 @@ impl WriteBackendMethods for SpirvCodegenBackend {
324324
_opt_level: config::OptLevel,
325325
_target_features: &[String],
326326
) -> TargetMachineFactoryFn<Self> {
327-
Arc::new(|_| Ok(()))
327+
Arc::new(|_, _| ())
328328
}
329329

330330
// FIXME(eddyb) reuse the "merge" stage of `crate::linker` for this, or even

0 commit comments

Comments
 (0)