Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions crates/rustc_codegen_spirv/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -488,13 +488,8 @@ fn check_mod_attrs(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
module_def_id,
&mut check_spirv_attr_visitor.as_deep_visitor(),
);
// FIXME(eddyb) use `tcx.hir().visit_exported_macros_in_krate(...)` after rustup.
for id in tcx.hir().krate().exported_macros {
check_spirv_attr_visitor.visit_macro_def(match tcx.hir().find(id.hir_id()) {
Some(hir::Node::MacroDef(macro_def)) => macro_def,
_ => unreachable!(),
});
}
tcx.hir()
.visit_exported_macros_in_krate(check_spirv_attr_visitor);
check_invalid_macro_level_spirv_attr(
tcx,
&check_spirv_attr_visitor.sym,
Expand Down
88 changes: 63 additions & 25 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::Builder;
use crate::abi::ConvSpirvType;
use crate::builder_spirv::{BuilderCursor, SpirvConst, SpirvValue, SpirvValueExt, SpirvValueKind};
use crate::spirv_type::SpirvType;
use rspirv::dr::{InsertPoint, Instruction, Operand};
Expand Down Expand Up @@ -313,7 +314,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} else {
for index in 0..count {
let const_index = self.constant_u32(self.span(), index as u32);
let gep_ptr = self.gep(ptr, &[const_index]);
let gep_ptr = self.gep(pat.ty, ptr, &[const_index]);
self.store(pat, gep_ptr, Align::from_bytes(0).unwrap());
}
}
Expand All @@ -339,11 +340,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
self.store(zero, index, zero_align);
self.br(header.llbb());

let current_index = header.load(index, zero_align);
let current_index = header.load(count.ty, index, zero_align);
let cond = header.icmp(IntPredicate::IntULT, current_index, count);
header.cond_br(cond, body.llbb(), exit.llbb());

let gep_ptr = body.gep(ptr, &[current_index]);
let gep_ptr = body.gep(pat.ty, ptr, &[current_index]);
body.store(pat, gep_ptr, zero_align);
let current_index_plus_1 = body.add(current_index, one);
body.store(current_index_plus_1, index, zero_align);
Expand Down Expand Up @@ -623,14 +624,15 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {

fn invoke(
&mut self,
llty: Self::Type,
llfn: Self::Value,
args: &[Self::Value],
then: Self::BasicBlock,
_catch: Self::BasicBlock,
funclet: Option<&Self::Funclet>,
) -> Self::Value {
// Exceptions don't exist, jump directly to then block
let result = self.call(llfn, args, funclet);
let result = self.call(llty, llfn, args, funclet);
self.emit().branch(then).unwrap();
result
}
Expand Down Expand Up @@ -842,12 +844,15 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
self.fatal("array alloca not supported yet")
}

fn load(&mut self, ptr: Self::Value, _align: Align) -> Self::Value {
fn load(&mut self, ty: Self::Type, ptr: Self::Value, _align: Align) -> Self::Value {
if let Some(value) = ptr.const_fold_load(self) {
return value;
}
let ty = match self.lookup_type(ptr.ty) {
SpirvType::Pointer { pointee } => pointee,
SpirvType::Pointer { pointee } => {
assert_ty_eq!(self, ty, pointee);
pointee
}
ty => self.fatal(&format!(
"load called on variable that wasn't a pointer: {:?}",
ty
Expand All @@ -859,16 +864,25 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
.with_type(ty)
}

fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value {
fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value {
// TODO: Implement this
let result = self.load(ptr, Align::from_bytes(0).unwrap());
let result = self.load(ty, ptr, Align::from_bytes(0).unwrap());
self.zombie(result.def(self), "volatile load is not supported yet");
result
}

fn atomic_load(&mut self, ptr: Self::Value, order: AtomicOrdering, _size: Size) -> Self::Value {
fn atomic_load(
&mut self,
ty: Self::Type,
ptr: Self::Value,
order: AtomicOrdering,
_size: Size,
) -> Self::Value {
let ty = match self.lookup_type(ptr.ty) {
SpirvType::Pointer { pointee } => pointee,
SpirvType::Pointer { pointee } => {
assert_ty_eq!(self, ty, pointee);
pointee
}
ty => self.fatal(&format!(
"atomic_load called on variable that wasn't a pointer: {:?}",
ty
Expand Down Expand Up @@ -903,14 +917,23 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
let val = if let Some(llextra) = place.llextra {
OperandValue::Ref(place.llval, Some(llextra), place.align)
} else if self.cx.is_backend_immediate(place.layout) {
let llval = self.load(place.llval, place.align);
let llval = self.load(
place.layout.spirv_type(self.span(), self),
place.llval,
place.align,
);
OperandValue::Immediate(self.to_immediate(llval, place.layout))
} else if let Abi::ScalarPair(ref a, ref b) = place.layout.abi {
let b_offset = a.value.size(self).align_to(b.value.align(self).abi);

let pair_ty = place.layout.spirv_type(self.span(), self);
let mut load = |i, scalar: &Scalar, align| {
let llptr = self.struct_gep(place.llval, i as u64);
let load = self.load(llptr, align);
let llptr = self.struct_gep(pair_ty, place.llval, i as u64);
let load = self.load(
self.scalar_pair_element_backend_type(place.layout, i, false),
llptr,
align,
);
// WARN! This does not go through to_immediate due to only having a Scalar, not a Ty, but it still does
// whatever to_immediate does!
if scalar.is_bool() {
Expand Down Expand Up @@ -943,12 +966,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
let zero = self.const_usize(0);
let start = dest.project_index(&mut self, zero).llval;

let align = dest
.align
.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
let elem_layout = dest.layout.field(self.cx(), 0);
let elem_ty = elem_layout.spirv_type(self.span(), &self);
let align = dest.align.restrict_for_offset(elem_layout.size);

for i in 0..count {
let current = self.inbounds_gep(start, &[self.const_usize(i)]);
let current = self.inbounds_gep(elem_ty, start, &[self.const_usize(i)]);
cg_elem.val.store(
&mut self,
PlaceRef::new_sized_aligned(current, cg_elem.layout, align),
Expand Down Expand Up @@ -1026,17 +1049,25 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
.unwrap();
}

fn gep(&mut self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value {
self.gep_help(ptr, indices, false)
fn gep(&mut self, ty: Self::Type, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value {
self.gep_help(ty, ptr, indices, false)
}

fn inbounds_gep(&mut self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value {
self.gep_help(ptr, indices, true)
fn inbounds_gep(
&mut self,
ty: Self::Type,
ptr: Self::Value,
indices: &[Self::Value],
) -> Self::Value {
self.gep_help(ty, ptr, indices, true)
}

fn struct_gep(&mut self, ptr: Self::Value, idx: u64) -> Self::Value {
fn struct_gep(&mut self, ty: Self::Type, ptr: Self::Value, idx: u64) -> Self::Value {
let pointee = match self.lookup_type(ptr.ty) {
SpirvType::Pointer { pointee } => pointee,
SpirvType::Pointer { pointee } => {
assert_ty_eq!(self, ty, pointee);
pointee
}
other => self.fatal(&format!(
"struct_gep not on pointer type: {:?}, index {}",
other, idx
Expand Down Expand Up @@ -2087,6 +2118,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {

fn call(
&mut self,
callee_ty: Self::Type,
callee: Self::Value,
args: &[Self::Value],
funclet: Option<&Self::Funclet>,
Expand All @@ -2104,15 +2136,21 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
SpirvType::Function {
return_type,
arguments,
} => (callee.def(self), return_type, arguments),
} => {
assert_ty_eq!(self, callee_ty, callee.ty);
(callee.def(self), return_type, arguments)
}

SpirvType::Pointer { pointee } => match self.lookup_type(pointee) {
SpirvType::Function {
return_type,
arguments,
} => (
match callee.kind {
SpirvValueKind::FnAddr { function } => function,
SpirvValueKind::FnAddr { function } => {
assert_ty_eq!(self, callee_ty, pointee);
function
}

// Truly indirect call.
_ => {
Expand Down
12 changes: 7 additions & 5 deletions crates/rustc_codegen_spirv/src/builder/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,17 @@ impl<'a, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'tcx> {
}

sym::volatile_load | sym::unaligned_volatile_load => {
let tp_ty = substs.type_at(0);
let mut 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);
ptr = self.pointercast(ptr, pointer);
let ptr = self.pointercast(ptr, pointer);
self.volatile_load(pointee, ptr)
} else {
let layout = self.layout_of(substs.type_at(0));
let load = self.volatile_load(layout.spirv_type(self.span(), self), ptr);
self.to_immediate(load, layout)
}
let load = self.volatile_load(ptr);
self.to_immediate(load, self.layout_of(tp_ty))
}

sym::prefetch_read_data
Expand Down
6 changes: 5 additions & 1 deletion crates/rustc_codegen_spirv/src/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {

pub fn gep_help(
&self,
ty: Word,
ptr: SpirvValue,
indices: &[SpirvValue],
is_inbounds: bool,
Expand All @@ -105,7 +106,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// https://github.com/gpuweb/gpuweb/issues/33
let mut result_indices = Vec::with_capacity(indices.len() - 1);
let mut result_pointee_type = match self.lookup_type(ptr.ty) {
SpirvType::Pointer { pointee } => pointee,
SpirvType::Pointer { pointee } => {
assert_ty_eq!(self, ty, pointee);
pointee
}
other_type => self.fatal(&format!(
"GEP first deref not implemented for type {:?}",
other_type
Expand Down
1 change: 1 addition & 0 deletions crates/rustc_codegen_spirv/src/builder_spirv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_middle::bug;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
use std::assert_matches::assert_matches;
use std::cell::{RefCell, RefMut};
use std::rc::Rc;
use std::{fs::File, io::Write, path::Path};
Expand Down
16 changes: 12 additions & 4 deletions crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,9 @@ impl<'tcx> ConstMethods<'tcx> for CodegenCx<'tcx> {
}
}
}
Scalar::Ptr(ptr) => {
let (base_addr, _base_addr_space) = match self.tcx.global_alloc(ptr.alloc_id) {
Scalar::Ptr(ptr, _) => {
let (alloc_id, offset) = ptr.into_parts();
let (base_addr, _base_addr_space) = match self.tcx.global_alloc(alloc_id) {
GlobalAlloc::Memory(alloc) => {
let pointee = match self.lookup_type(ty) {
SpirvType::Pointer { pointee } => pointee,
Expand All @@ -286,12 +287,12 @@ impl<'tcx> ConstMethods<'tcx> for CodegenCx<'tcx> {
(self.get_static(def_id), AddressSpace::DATA)
}
};
let value = if ptr.offset.bytes() == 0 {
let value = if offset.bytes() == 0 {
base_addr
} else {
self.tcx
.sess
.fatal("Non-constant scalar_to_backend ptr.offset not supported")
.fatal("Non-zero scalar_to_backend ptr.offset not supported")
// let offset = self.constant_u64(ptr.offset.bytes());
// self.gep(base_addr, once(offset))
};
Expand All @@ -307,6 +308,13 @@ impl<'tcx> ConstMethods<'tcx> for CodegenCx<'tcx> {
}
}
}
// FIXME(eddyb) this shouldn't exist, and is only used by vtable creation,
// see https://github.com/rust-lang/rust/pull/86475#discussion_r680792727.
fn const_data_from_alloc(&self, _alloc: &Allocation) -> Self::Value {
let undef = self.undef(SpirvType::Void.def(DUMMY_SP, self));
self.zombie_no_span(undef.def_cx(self), "const_data_from_alloc");
undef
}
fn from_const_alloc(
&self,
layout: TyAndLayout<'tcx>,
Expand Down
21 changes: 12 additions & 9 deletions crates/rustc_codegen_spirv/src/codegen_cx/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ impl<'tcx> CodegenCx<'tcx> {
);
}
bx.set_span(span);
bx.call(entry_func, &call_args, None);
bx.call(entry_func.ty, entry_func, &call_args, None);
bx.ret_void();

let stub_fn_id = stub_fn.def_cx(self);
Expand Down Expand Up @@ -307,14 +307,13 @@ impl<'tcx> CodegenCx<'tcx> {
let var_ptr_spirv_type;
let (value_ptr, value_len) = match storage_class {
StorageClass::PushConstant | StorageClass::Uniform | StorageClass::StorageBuffer => {
var_ptr_spirv_type = self.type_ptr_to(
SpirvType::InterfaceBlock {
inner_type: value_spirv_type,
}
.def(hir_param.span, self),
);
let var_spirv_type = SpirvType::InterfaceBlock {
inner_type: value_spirv_type,
}
.def(hir_param.span, self);
var_ptr_spirv_type = self.type_ptr_to(var_spirv_type);

let value_ptr = bx.struct_gep(var.with_type(var_ptr_spirv_type), 0);
let value_ptr = bx.struct_gep(var_spirv_type, var.with_type(var_ptr_spirv_type), 0);

let value_len = if is_unsized_with_len {
match self.lookup_type(value_spirv_type) {
Expand Down Expand Up @@ -409,7 +408,11 @@ impl<'tcx> CodegenCx<'tcx> {

call_args.push(match entry_arg_abi.mode {
PassMode::Indirect { .. } => value_ptr,
PassMode::Direct(_) => bx.load(value_ptr, entry_arg_abi.layout.align.abi),
PassMode::Direct(_) => bx.load(
entry_arg_abi.layout.spirv_type(hir_param.ty_span, bx),
value_ptr,
entry_arg_abi.layout.align.abi,
),
_ => unreachable!(),
});
assert_eq!(value_len, None);
Expand Down
2 changes: 1 addition & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@ impl<'tcx> MiscMethods<'tcx> for CodegenCx<'tcx> {
todo!()
}

fn set_frame_pointer_elimination(&self, _llfn: Self::Function) {
fn set_frame_pointer_type(&self, _llfn: Self::Function) {
todo!()
}

Expand Down
6 changes: 5 additions & 1 deletion crates/rustc_codegen_spirv/src/codegen_cx/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,14 @@ impl<'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'tcx> {
ty.spirv_type(DUMMY_SP, self)
}

fn fn_ptr_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 {
fn_abi.spirv_type(DUMMY_SP, self)
}

fn fn_ptr_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Type {
self.type_ptr_to(self.fn_decl_backend_type(fn_abi))
}

fn reg_backend_type(&self, ty: &Reg) -> Self::Type {
ty.spirv_type(DUMMY_SP, self)
}
Expand Down
6 changes: 2 additions & 4 deletions crates/rustc_codegen_spirv/src/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,7 @@ fn add_upstream_rust_crates(
.iter()
.find(|(ty, _)| *ty == crate_type)
.expect("failed to find crate type in dependency format list");
let deps = &codegen_results.crate_info.used_crates_dynamic;
for &(cnum, _) in deps.iter() {
for &cnum in &codegen_results.crate_info.used_crates {
let src = &codegen_results.crate_info.used_crate_source[&cnum];
match data[cnum.as_usize() - 1] {
Linkage::NotLinked | Linkage::IncludedFromDylib => {}
Expand All @@ -391,8 +390,7 @@ fn add_upstream_native_libraries(
.find(|(ty, _)| *ty == crate_type)
.expect("failed to find crate type in dependency format list");

let crates = &codegen_results.crate_info.used_crates_static;
for &(cnum, _) in crates {
for &cnum in &codegen_results.crate_info.used_crates {
for lib in codegen_results.crate_info.native_libraries[&cnum].iter() {
let name = match lib.name {
Some(l) => l,
Expand Down
Loading