[core] codegen: Add Self::llvm_type to all type abstractions

This commit is contained in:
David Mak 2024-11-08 15:35:45 +08:00
parent d3fb4204e7
commit 3a5e7a98b1
3 changed files with 45 additions and 24 deletions

View File

@ -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)
} }

View File

@ -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)
} }

View File

@ -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)
} }