Implement abstractions over Structs and NDArray #554
|
@ -55,6 +55,19 @@ impl<'ctx> ListType<'ctx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an LLVM type corresponding to the expected structure of a `List`.
|
||||||
|
#[must_use]
|
||||||
|
fn llvm_type(
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
element_type: BasicTypeEnum<'ctx>,
|
||||||
|
llvm_usize: IntType<'ctx>,
|
||||||
|
) -> PointerType<'ctx> {
|
||||||
|
// struct List { data: T*, size: size_t }
|
||||||
|
let field_tys = [element_type.ptr_type(AddressSpace::default()).into(), llvm_usize.into()];
|
||||||
|
|
||||||
|
ctx.struct_type(&field_tys, false).ptr_type(AddressSpace::default())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates an instance of [`ListType`].
|
/// Creates an instance of [`ListType`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new<G: CodeGenerator + ?Sized>(
|
pub fn new<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -63,12 +76,7 @@ impl<'ctx> ListType<'ctx> {
|
||||||
element_type: BasicTypeEnum<'ctx>,
|
element_type: BasicTypeEnum<'ctx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let llvm_usize = generator.get_size_type(ctx);
|
let llvm_usize = generator.get_size_type(ctx);
|
||||||
let llvm_list = ctx
|
let llvm_list = Self::llvm_type(ctx, element_type, llvm_usize);
|
||||||
.struct_type(
|
|
||||||
&[element_type.ptr_type(AddressSpace::default()).into(), llvm_usize.into()],
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.ptr_type(AddressSpace::default());
|
|
||||||
|
|
||||||
ListType::from_type(llvm_list, llvm_usize)
|
ListType::from_type(llvm_list, llvm_usize)
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,27 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an LLVM type corresponding to the expected structure of an `NDArray`.
|
||||||
|
#[must_use]
|
||||||
|
fn llvm_type(
|
||||||
|
ctx: &'ctx Context,
|
||||||
|
dtype: BasicTypeEnum<'ctx>,
|
||||||
|
llvm_usize: IntType<'ctx>,
|
||||||
|
) -> PointerType<'ctx> {
|
||||||
|
// struct NDArray { num_dims: size_t, dims: size_t*, data: T* }
|
||||||
|
//
|
||||||
|
// * num_dims: Number of dimensions in the array
|
||||||
|
// * dims: Pointer to an array containing the size of each dimension
|
||||||
|
// * data: Pointer to an array containing the array data
|
||||||
|
let field_tys = [
|
||||||
|
llvm_usize.into(),
|
||||||
|
llvm_usize.ptr_type(AddressSpace::default()).into(),
|
||||||
|
dtype.ptr_type(AddressSpace::default()).into(),
|
||||||
|
];
|
||||||
|
|
||||||
|
ctx.struct_type(&field_tys, false).ptr_type(AddressSpace::default())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates an instance of [`ListType`].
|
/// Creates an instance of [`ListType`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new<G: CodeGenerator + ?Sized>(
|
pub fn new<G: CodeGenerator + ?Sized>(
|
||||||
|
@ -81,22 +102,7 @@ impl<'ctx> NDArrayType<'ctx> {
|
||||||
dtype: BasicTypeEnum<'ctx>,
|
dtype: BasicTypeEnum<'ctx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let llvm_usize = generator.get_size_type(ctx);
|
let llvm_usize = generator.get_size_type(ctx);
|
||||||
|
let llvm_ndarray = Self::llvm_type(ctx, dtype, llvm_usize);
|
||||||
// struct NDArray { num_dims: size_t, dims: size_t*, data: T* }
|
|
||||||
//
|
|
||||||
// * num_dims: Number of dimensions in the array
|
|
||||||
// * dims: Pointer to an array containing the size of each dimension
|
|
||||||
// * data: Pointer to an array containing the array data
|
|
||||||
let llvm_ndarray = ctx
|
|
||||||
.struct_type(
|
|
||||||
&[
|
|
||||||
llvm_usize.into(),
|
|
||||||
llvm_usize.ptr_type(AddressSpace::default()).into(),
|
|
||||||
dtype.ptr_type(AddressSpace::default()).into(),
|
|
||||||
],
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.ptr_type(AddressSpace::default());
|
|
||||||
|
|
||||||
NDArrayType::from_type(llvm_ndarray, llvm_usize)
|
NDArrayType::from_type(llvm_ndarray, llvm_usize)
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,18 @@ impl<'ctx> RangeType<'ctx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates an LLVM type corresponding to the expected structure of a `Range`.
|
||||||
|
#[must_use]
|
||||||
|
fn llvm_type(ctx: &'ctx Context) -> PointerType<'ctx> {
|
||||||
|
// typedef int32_t Range[3];
|
||||||
|
let llvm_i32 = ctx.i32_type();
|
||||||
|
llvm_i32.array_type(3).ptr_type(AddressSpace::default())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates an instance of [`RangeType`].
|
/// Creates an instance of [`RangeType`].
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(ctx: &'ctx Context) -> Self {
|
pub fn new(ctx: &'ctx Context) -> Self {
|
||||||
let llvm_i32 = ctx.i32_type();
|
let llvm_range = Self::llvm_type(ctx);
|
||||||
let llvm_range = llvm_i32.array_type(3).ptr_type(AddressSpace::default());
|
|
||||||
|
|
||||||
RangeType::from_type(llvm_range)
|
RangeType::from_type(llvm_range)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue