mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 08:14:12 +00:00
Implement many things
This commit is contained in:
parent
2c8c2937ad
commit
5f93702a92
@ -5,6 +5,7 @@ use rustc_target::abi::{Abi, FieldsShape, Primitive, Scalar, Size};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SpirvType {
|
||||
Void,
|
||||
Bool,
|
||||
Integer(u32, bool),
|
||||
Float(u32),
|
||||
@ -110,6 +111,7 @@ fn trans_scalar<'spv, 'tcx>(
|
||||
} else {
|
||||
// TODO: Implement this properly
|
||||
let void = cx.emit_global().type_void();
|
||||
cx.def_type(void, SpirvType::Void);
|
||||
(
|
||||
cx.emit_global()
|
||||
.type_pointer(None, StorageClass::Generic, void),
|
||||
@ -164,7 +166,16 @@ fn trans_aggregate<'spv, 'tcx>(cx: &CodegenCx<'spv, 'tcx>, ty: TyAndLayout<'tcx>
|
||||
// TODO: Is this the right thing to do?
|
||||
FieldsShape::Union(_field_count) => {
|
||||
let byte = cx.emit_global().type_int(8, 0);
|
||||
cx.emit_global().type_array(byte, ty.size.bytes() as u32)
|
||||
cx.def_type(byte, SpirvType::Integer(8, false));
|
||||
let result = cx.emit_global().type_array(byte, ty.size.bytes() as u32);
|
||||
cx.def_type(
|
||||
result,
|
||||
SpirvType::Array {
|
||||
element: byte,
|
||||
count: ty.size.bytes() as u32,
|
||||
},
|
||||
);
|
||||
result
|
||||
}
|
||||
FieldsShape::Array { stride: _, count } => {
|
||||
// TODO: Assert stride is same as spirv's stride?
|
||||
|
@ -1,14 +1,18 @@
|
||||
use super::Builder;
|
||||
use crate::abi::SpirvType;
|
||||
use crate::builder_spirv::{BuilderCursor, SpirvValueExt};
|
||||
use rspirv::spirv::StorageClass;
|
||||
use rustc_codegen_ssa::base::to_immediate;
|
||||
use rustc_codegen_ssa::common::{
|
||||
AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope,
|
||||
};
|
||||
use rustc_codegen_ssa::mir::operand::OperandRef;
|
||||
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
|
||||
use rustc_codegen_ssa::mir::place::PlaceRef;
|
||||
use rustc_codegen_ssa::traits::LayoutTypeMethods;
|
||||
use rustc_codegen_ssa::traits::{BuilderMethods, OverflowOp};
|
||||
use rustc_codegen_ssa::MemFlags;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_target::abi::{Align, Size};
|
||||
use rustc_target::abi::{Abi, Align, Size};
|
||||
use std::ops::Range;
|
||||
|
||||
impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
@ -80,26 +84,37 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
self.emit().ret_value(value.def).unwrap();
|
||||
}
|
||||
|
||||
fn br(&mut self, _dest: Self::BasicBlock) {
|
||||
todo!()
|
||||
fn br(&mut self, dest: Self::BasicBlock) {
|
||||
self.emit().branch(dest).unwrap()
|
||||
}
|
||||
|
||||
fn cond_br(
|
||||
&mut self,
|
||||
_cond: Self::Value,
|
||||
_then_llbb: Self::BasicBlock,
|
||||
_else_llbb: Self::BasicBlock,
|
||||
cond: Self::Value,
|
||||
then_llbb: Self::BasicBlock,
|
||||
else_llbb: Self::BasicBlock,
|
||||
) {
|
||||
todo!()
|
||||
self.emit()
|
||||
.branch_conditional(cond.def, then_llbb, else_llbb, &[])
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn switch(
|
||||
&mut self,
|
||||
_v: Self::Value,
|
||||
_else_llbb: Self::BasicBlock,
|
||||
_cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>,
|
||||
v: Self::Value,
|
||||
else_llbb: Self::BasicBlock,
|
||||
cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>,
|
||||
) {
|
||||
todo!()
|
||||
let cases = cases
|
||||
.map(|(i, b)| {
|
||||
if i > u32::MAX as u128 {
|
||||
panic!("Switches to values above u32::MAX not supported: {:?}", i)
|
||||
} else {
|
||||
(i as u32, b)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
self.emit().switch(v.def, else_llbb, cases).unwrap()
|
||||
}
|
||||
|
||||
fn invoke(
|
||||
@ -114,7 +129,7 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
}
|
||||
|
||||
fn unreachable(&mut self) {
|
||||
todo!()
|
||||
self.emit().unreachable().unwrap()
|
||||
}
|
||||
|
||||
fn add(&mut self, _lhs: Self::Value, _rhs: Self::Value) -> Self::Value {
|
||||
@ -268,24 +283,36 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn alloca(&mut self, _ty: Self::Type, _align: Align) -> Self::Value {
|
||||
todo!()
|
||||
fn alloca(&mut self, ty: Self::Type, _align: Align) -> Self::Value {
|
||||
let ptr_ty = self.emit().type_pointer(None, StorageClass::Function, ty);
|
||||
self.def_type(ptr_ty, SpirvType::Pointer { pointee: ty });
|
||||
self.emit()
|
||||
.variable(ptr_ty, None, StorageClass::Function, None)
|
||||
.with_type(ptr_ty)
|
||||
}
|
||||
|
||||
fn dynamic_alloca(&mut self, _ty: Self::Type, _align: Align) -> Self::Value {
|
||||
todo!()
|
||||
fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value {
|
||||
self.alloca(ty, align)
|
||||
}
|
||||
|
||||
fn array_alloca(&mut self, _ty: Self::Type, _len: Self::Value, _align: Align) -> Self::Value {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn load(&mut self, _ptr: Self::Value, _align: Align) -> Self::Value {
|
||||
todo!()
|
||||
fn load(&mut self, ptr: Self::Value, _align: Align) -> Self::Value {
|
||||
let ty = match self.lookup_type(ptr.ty) {
|
||||
SpirvType::Pointer { pointee } => pointee,
|
||||
ty => panic!("load called on variable that wasn't a pointer: {:?}", ty),
|
||||
};
|
||||
self.emit()
|
||||
.load(ty, None, ptr.def, None, [])
|
||||
.unwrap()
|
||||
.with_type(ty)
|
||||
}
|
||||
|
||||
fn volatile_load(&mut self, _ptr: Self::Value) -> Self::Value {
|
||||
todo!()
|
||||
fn volatile_load(&mut self, ptr: Self::Value) -> Self::Value {
|
||||
// TODO: Can we do something here?
|
||||
self.load(ptr, Align::from_bytes(0).unwrap())
|
||||
}
|
||||
|
||||
fn atomic_load(
|
||||
@ -299,9 +326,36 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
|
||||
fn load_operand(
|
||||
&mut self,
|
||||
_place: PlaceRef<'tcx, Self::Value>,
|
||||
place: PlaceRef<'tcx, Self::Value>,
|
||||
) -> OperandRef<'tcx, Self::Value> {
|
||||
todo!()
|
||||
if place.layout.is_zst() {
|
||||
return OperandRef::new_zst(self, place.layout);
|
||||
}
|
||||
|
||||
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);
|
||||
OperandValue::Immediate(to_immediate(self, 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 mut load = |i, align| {
|
||||
let llptr = self.struct_gep(place.llval, i as u64);
|
||||
self.load(llptr, align)
|
||||
};
|
||||
|
||||
OperandValue::Pair(
|
||||
load(0, place.align),
|
||||
load(1, place.align.restrict_for_offset(b_offset)),
|
||||
)
|
||||
} else {
|
||||
OperandValue::Ref(place.llval, None, place.align)
|
||||
};
|
||||
OperandRef {
|
||||
val,
|
||||
layout: place.layout,
|
||||
}
|
||||
}
|
||||
|
||||
/// Called for Rvalue::Repeat when the elem is neither a ZST nor optimizable using memset.
|
||||
@ -322,18 +376,24 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn store(&mut self, _val: Self::Value, _ptr: Self::Value, _align: Align) -> Self::Value {
|
||||
todo!()
|
||||
fn store(&mut self, val: Self::Value, ptr: Self::Value, _align: Align) -> Self::Value {
|
||||
let ptr_elem_ty = match self.lookup_type(ptr.ty) {
|
||||
SpirvType::Pointer { pointee } => pointee,
|
||||
ty => panic!("store called on variable that wasn't a pointer: {:?}", ty),
|
||||
};
|
||||
assert_eq!(ptr_elem_ty, val.ty);
|
||||
self.emit().store(ptr.def, val.def, None, &[]).unwrap();
|
||||
val
|
||||
}
|
||||
|
||||
fn store_with_flags(
|
||||
&mut self,
|
||||
_val: Self::Value,
|
||||
_ptr: Self::Value,
|
||||
_align: Align,
|
||||
val: Self::Value,
|
||||
ptr: Self::Value,
|
||||
align: Align,
|
||||
_flags: MemFlags,
|
||||
) -> Self::Value {
|
||||
todo!()
|
||||
self.store(val, ptr, align)
|
||||
}
|
||||
|
||||
fn atomic_store(
|
||||
@ -398,29 +458,58 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn ptrtoint(&mut self, _val: Self::Value, _dest_ty: Self::Type) -> Self::Value {
|
||||
todo!()
|
||||
fn ptrtoint(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value {
|
||||
match self.lookup_type(val.ty) {
|
||||
SpirvType::Pointer { .. } => (),
|
||||
other => panic!("ptrtoint called on non-pointer source type: {:?}", other),
|
||||
}
|
||||
self.emit()
|
||||
.bitcast(dest_ty, None, val.def)
|
||||
.unwrap()
|
||||
.with_type(dest_ty)
|
||||
}
|
||||
|
||||
fn inttoptr(&mut self, _val: Self::Value, _dest_ty: Self::Type) -> Self::Value {
|
||||
todo!()
|
||||
fn inttoptr(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value {
|
||||
match self.lookup_type(dest_ty) {
|
||||
SpirvType::Pointer { .. } => (),
|
||||
other => panic!("inttoptr called on non-pointer dest type: {:?}", other),
|
||||
}
|
||||
self.emit()
|
||||
.bitcast(dest_ty, None, val.def)
|
||||
.unwrap()
|
||||
.with_type(dest_ty)
|
||||
}
|
||||
|
||||
fn bitcast(&mut self, _val: Self::Value, _dest_ty: Self::Type) -> Self::Value {
|
||||
todo!()
|
||||
fn bitcast(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value {
|
||||
self.emit()
|
||||
.bitcast(dest_ty, None, val.def)
|
||||
.unwrap()
|
||||
.with_type(dest_ty)
|
||||
}
|
||||
|
||||
fn intcast(
|
||||
&mut self,
|
||||
_val: Self::Value,
|
||||
_dest_ty: Self::Type,
|
||||
_is_signed: bool,
|
||||
) -> Self::Value {
|
||||
todo!()
|
||||
fn intcast(&mut self, val: Self::Value, dest_ty: Self::Type, is_signed: bool) -> Self::Value {
|
||||
panic!(
|
||||
"TODO: intcast not implemented yet: val={:?} val.ty={:?} dest_ty={:?} is_signed={}",
|
||||
val,
|
||||
self.lookup_type(val.ty),
|
||||
self.lookup_type(dest_ty),
|
||||
is_signed
|
||||
);
|
||||
}
|
||||
|
||||
fn pointercast(&mut self, _val: Self::Value, _dest_ty: Self::Type) -> Self::Value {
|
||||
todo!()
|
||||
fn pointercast(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value {
|
||||
match self.lookup_type(val.ty) {
|
||||
SpirvType::Pointer { .. } => (),
|
||||
other => panic!("pointercast called on non-pointer source type: {:?}", other),
|
||||
}
|
||||
match self.lookup_type(dest_ty) {
|
||||
SpirvType::Pointer { .. } => (),
|
||||
other => panic!("pointercast called on non-pointer dest type: {:?}", other),
|
||||
}
|
||||
self.emit()
|
||||
.bitcast(dest_ty, None, val.def)
|
||||
.unwrap()
|
||||
.with_type(dest_ty)
|
||||
}
|
||||
|
||||
fn icmp(&mut self, _op: IntPredicate, _lhs: Self::Value, _rhs: Self::Value) -> Self::Value {
|
||||
@ -581,12 +670,12 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
|
||||
/// Called for `StorageLive`
|
||||
fn lifetime_start(&mut self, _ptr: Self::Value, _size: Size) {
|
||||
todo!()
|
||||
// ignore
|
||||
}
|
||||
|
||||
/// Called for `StorageDead`
|
||||
fn lifetime_end(&mut self, _ptr: Self::Value, _size: Size) {
|
||||
todo!()
|
||||
// ignore
|
||||
}
|
||||
|
||||
fn instrprof_increment(
|
||||
@ -601,11 +690,22 @@ impl<'a, 'spv, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
|
||||
fn call(
|
||||
&mut self,
|
||||
_llfn: Self::Value,
|
||||
_args: &[Self::Value],
|
||||
_funclet: Option<&Self::Funclet>,
|
||||
llfn: Self::Value,
|
||||
args: &[Self::Value],
|
||||
funclet: Option<&Self::Funclet>,
|
||||
) -> Self::Value {
|
||||
todo!()
|
||||
if funclet.is_some() {
|
||||
panic!("TODO: Funclets are not supported");
|
||||
}
|
||||
let result_type = match self.lookup_type(llfn.ty) {
|
||||
SpirvType::Function { return_type, .. } => return_type,
|
||||
ty => panic!("Calling non-function type: {:?}", ty),
|
||||
};
|
||||
let args = args.iter().map(|arg| arg.def).collect::<Vec<_>>();
|
||||
self.emit()
|
||||
.function_call(result_type, None, llfn.def, args)
|
||||
.unwrap()
|
||||
.with_type(result_type)
|
||||
}
|
||||
|
||||
fn zext(&mut self, _val: Self::Value, _dest_ty: Self::Type) -> Self::Value {
|
||||
|
@ -125,14 +125,14 @@ impl<'a, 'spv, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn arg_memory_ty(&self, _arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type {
|
||||
todo!()
|
||||
fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type {
|
||||
self.trans_type(arg_abi.layout)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'spv, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) {
|
||||
todo!()
|
||||
// TODO: Implement this?
|
||||
}
|
||||
|
||||
fn get_param(&self, index: usize) -> Self::Value {
|
||||
@ -143,14 +143,14 @@ impl<'a, 'spv, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
impl<'a, 'spv, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
fn codegen_intrinsic_call(
|
||||
&mut self,
|
||||
_instance: Instance<'tcx>,
|
||||
_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
_args: &[OperandRef<'tcx, Self::Value>],
|
||||
_llresult: Self::Value,
|
||||
_span: Span,
|
||||
_caller_instance: Instance<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
args: &[OperandRef<'tcx, Self::Value>],
|
||||
llresult: Self::Value,
|
||||
span: Span,
|
||||
caller_instance: Instance<'tcx>,
|
||||
) {
|
||||
todo!()
|
||||
println!("TODO: codegen_intrinsic_call unimplemented: instance={:?} fn_abi={:?} args={:?} llresult={:?} span={:?} caller_instance={:?}", instance, fn_abi, args, llresult, span, caller_instance);
|
||||
}
|
||||
|
||||
fn is_codegen_intrinsic(
|
||||
@ -160,7 +160,7 @@ impl<'a, 'spv, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'spv, 'tcx> {
|
||||
_caller_instance: Instance<'tcx>,
|
||||
) -> bool {
|
||||
// TODO
|
||||
false
|
||||
true
|
||||
}
|
||||
|
||||
fn abort(&mut self) {
|
||||
|
@ -35,7 +35,7 @@ pub struct CodegenCx<'spv, 'tcx> {
|
||||
pub codegen_unit: &'tcx CodegenUnit<'tcx>,
|
||||
pub spirv_module: &'spv ModuleSpirv,
|
||||
pub builder: BuilderSpirv,
|
||||
pub function_defs: RefCell<HashMap<Instance<'tcx>, Word>>,
|
||||
pub function_defs: RefCell<HashMap<Instance<'tcx>, SpirvValue>>,
|
||||
pub function_parameter_values: RefCell<HashMap<Word, Vec<SpirvValue>>>,
|
||||
pub type_defs: RefCell<HashMap<Word, SpirvType>>,
|
||||
}
|
||||
@ -302,21 +302,30 @@ impl<'spv, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
}
|
||||
|
||||
/// Returns the number of elements in `self` if it is a LLVM vector type.
|
||||
fn vector_length(&self, _ty: Self::Type) -> usize {
|
||||
todo!()
|
||||
fn vector_length(&self, ty: Self::Type) -> usize {
|
||||
match self.lookup_type(ty) {
|
||||
SpirvType::Vector { count, .. } => count as usize,
|
||||
ty => panic!("vector_length called on non-vector type: {:?}", ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn float_width(&self, _ty: Self::Type) -> usize {
|
||||
todo!()
|
||||
fn float_width(&self, ty: Self::Type) -> usize {
|
||||
match self.lookup_type(ty) {
|
||||
SpirvType::Float(width) => width as usize,
|
||||
ty => panic!("float_width called on non-float type: {:?}", ty),
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves the bit width of the integer type `self`.
|
||||
fn int_width(&self, _ty: Self::Type) -> u64 {
|
||||
todo!()
|
||||
fn int_width(&self, ty: Self::Type) -> u64 {
|
||||
match self.lookup_type(ty) {
|
||||
SpirvType::Integer(width, _) => width as u64,
|
||||
ty => panic!("int_width called on non-integer type: {:?}", ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn val_ty(&self, _v: Self::Value) -> Self::Type {
|
||||
todo!()
|
||||
fn val_ty(&self, v: Self::Value) -> Self::Type {
|
||||
v.ty
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,11 +360,11 @@ impl<'spv, 'tcx> MiscMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
}
|
||||
|
||||
fn get_fn(&self, instance: Instance<'tcx>) -> Self::Function {
|
||||
self.function_defs.borrow()[&instance]
|
||||
self.function_defs.borrow()[&instance].def
|
||||
}
|
||||
|
||||
fn get_fn_addr(&self, _instance: Instance<'tcx>) -> Self::Value {
|
||||
todo!()
|
||||
fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value {
|
||||
self.function_defs.borrow()[&instance]
|
||||
}
|
||||
|
||||
fn eh_personality(&self) -> Self::Value {
|
||||
@ -406,29 +415,51 @@ impl<'spv, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
_symbol_name: &str,
|
||||
) {
|
||||
let fn_abi = FnAbi::of_instance(self, instance, &[]);
|
||||
let mut argument_types = fn_abi
|
||||
.args
|
||||
.iter()
|
||||
.map(|arg| match arg.mode {
|
||||
let mut argument_types = Vec::new();
|
||||
for arg in fn_abi.args {
|
||||
let arg_type = match arg.mode {
|
||||
PassMode::Ignore => panic!(
|
||||
"TODO: Argument PassMode::Ignore not supported yet: {:?}",
|
||||
arg
|
||||
),
|
||||
PassMode::Direct(_arg_attributes) => self.trans_type(arg.layout),
|
||||
PassMode::Pair(_arg_attributes_1, _arg_attributes_2) => self.trans_type(arg.layout),
|
||||
PassMode::Pair(_arg_attributes_1, _arg_attributes_2) => {
|
||||
// TODO: Make this more efficient, don't generate struct
|
||||
let tuple = self.lookup_type(self.trans_type(arg.layout));
|
||||
let (left, right) = match tuple {
|
||||
SpirvType::Adt { ref field_types } => {
|
||||
if let [left, right] = *field_types.as_slice() {
|
||||
(left, right)
|
||||
} else {
|
||||
panic!("PassMode::Pair did not produce tuple: {:?}", tuple)
|
||||
}
|
||||
}
|
||||
_ => panic!("PassMode::Pair did not produce tuple: {:?}", tuple),
|
||||
};
|
||||
argument_types.push(left);
|
||||
argument_types.push(right);
|
||||
continue;
|
||||
}
|
||||
PassMode::Cast(_cast_target) => self.trans_type(arg.layout),
|
||||
// TODO: Deal with wide ptr?
|
||||
PassMode::Indirect(_arg_attributes, _wide_ptr_attrs) => {
|
||||
let pointee = self.trans_type(arg.layout);
|
||||
self.emit_global()
|
||||
.type_pointer(None, StorageClass::Generic, pointee)
|
||||
let ptr_type =
|
||||
self.emit_global()
|
||||
.type_pointer(None, StorageClass::Generic, pointee);
|
||||
self.def_type(ptr_type, SpirvType::Pointer { pointee });
|
||||
ptr_type
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
// TODO: Do we register types created here in the type tracker?
|
||||
};
|
||||
argument_types.push(arg_type);
|
||||
}
|
||||
// TODO: Other modes
|
||||
let return_type = match fn_abi.ret.mode {
|
||||
PassMode::Ignore => self.emit_global().type_void(),
|
||||
PassMode::Ignore => {
|
||||
let void = self.emit_global().type_void();
|
||||
self.def_type(void, SpirvType::Void);
|
||||
void
|
||||
}
|
||||
PassMode::Direct(_arg_attributes) => self.trans_type(fn_abi.ret.layout),
|
||||
PassMode::Pair(_arg_attributes_1, _arg_attributes_2) => {
|
||||
self.trans_type(fn_abi.ret.layout)
|
||||
@ -438,12 +469,14 @@ impl<'spv, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
// TODO: Deal with wide ptr?
|
||||
PassMode::Indirect(_arg_attributes, _wide_ptr_attrs) => {
|
||||
let pointee = self.trans_type(fn_abi.ret.layout);
|
||||
argument_types.push(self.emit_global().type_pointer(
|
||||
None,
|
||||
StorageClass::Generic,
|
||||
pointee,
|
||||
));
|
||||
self.emit_global().type_void()
|
||||
let pointer = self
|
||||
.emit_global()
|
||||
.type_pointer(None, StorageClass::Generic, pointee);
|
||||
self.def_type(pointer, SpirvType::Pointer { pointee });
|
||||
argument_types.push(pointer);
|
||||
let void = self.emit_global().type_void();
|
||||
self.def_type(void, SpirvType::Void);
|
||||
void
|
||||
}
|
||||
};
|
||||
let mut emit = self.emit_global();
|
||||
@ -460,10 +493,19 @@ impl<'spv, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'spv, 'tcx> {
|
||||
.collect::<Vec<_>>();
|
||||
emit.end_function().unwrap();
|
||||
|
||||
self.function_defs.borrow_mut().insert(instance, fn_id);
|
||||
self.function_defs
|
||||
.borrow_mut()
|
||||
.insert(instance, fn_id.with_type(function_type));
|
||||
self.function_parameter_values
|
||||
.borrow_mut()
|
||||
.insert(fn_id, parameter_values);
|
||||
self.def_type(
|
||||
function_type,
|
||||
SpirvType::Function {
|
||||
return_type,
|
||||
arguments: argument_types,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,9 @@ use rustc_data_structures::sync::MetadataRef;
|
||||
use rustc_errors::{ErrorReported, FatalError, Handler};
|
||||
use rustc_middle::dep_graph::{DepGraph, WorkProduct};
|
||||
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader, MetadataLoaderDyn};
|
||||
use rustc_middle::mir::mono::MonoItem;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::{Instance, TyCtxt};
|
||||
use rustc_session::config::{OptLevel, OutputFilenames, OutputType};
|
||||
use rustc_session::Session;
|
||||
use rustc_span::Symbol;
|
||||
@ -52,14 +53,12 @@ use std::path::Path;
|
||||
use std::{fs::File, io::Write, sync::Arc};
|
||||
use things::{SpirvModuleBuffer, SprivThinBuffer};
|
||||
|
||||
/*
|
||||
fn dump_mir<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
|
||||
let mut mir = ::std::io::Cursor::new(Vec::new());
|
||||
rustc_mir::util::write_mir_pretty(tcx, Some(instance.def_id()), &mut mir).unwrap();
|
||||
let s = String::from_utf8(mir.into_inner()).unwrap();
|
||||
println!("{}", s);
|
||||
}
|
||||
*/
|
||||
|
||||
struct NoLlvmMetadataLoader;
|
||||
|
||||
@ -279,19 +278,16 @@ impl ExtraBackendMethods for SsaBackend {
|
||||
let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
|
||||
|
||||
for &(mono_item, (linkage, visibility)) in &mono_items {
|
||||
// if let MonoItem::Fn(instance) = mono_item {
|
||||
// dump_mir(tcx, instance);
|
||||
// }
|
||||
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, linkage, visibility);
|
||||
}
|
||||
|
||||
println!("Done predefining");
|
||||
|
||||
// ... and now that we have everything pre-defined, fill out those definitions.
|
||||
for &(mono_item, _) in &mono_items {
|
||||
// if let MonoItem::Fn(instance) = mono_item {
|
||||
// dump_mir(tcx, instance);
|
||||
// }
|
||||
if option_env!("DUMP_MIR").is_some() {
|
||||
if let MonoItem::Fn(instance) = mono_item {
|
||||
dump_mir(tcx, instance);
|
||||
}
|
||||
}
|
||||
mono_item.define::<Builder<'_, '_, '_>>(&cx);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user