[core] codegen/types: Refactor ProxyType

- Add alloca_type() function to obtain the type that should be passed
into a `build_alloca` call
- Provide default implementations for raw_alloca and array_alloca
- Add raw_alloca_var and array_alloca_var to distinguish alloca
instructions placed at the front of the function vs at the current
builder location
This commit is contained in:
David Mak 2024-12-17 16:48:31 +08:00
parent 90071be0a7
commit 53d09b86f7
11 changed files with 189 additions and 245 deletions

View File

@ -1108,7 +1108,7 @@ pub fn allocate_list<'ctx, G: CodeGenerator + ?Sized>(
// List structure; type { ty*, size_t } // List structure; type { ty*, size_t }
let arr_ty = ListType::new(generator, ctx.ctx, llvm_elem_ty); let arr_ty = ListType::new(generator, ctx.ctx, llvm_elem_ty);
let list = arr_ty.alloca(generator, ctx, name); let list = arr_ty.alloca_var(generator, ctx, name);
let length = ctx.builder.build_int_z_extend(length, llvm_usize, "").unwrap(); let length = ctx.builder.build_int_z_extend(length, llvm_usize, "").unwrap();
list.store_size(ctx, generator, length); list.store_size(ctx, generator, length);

View File

@ -1,13 +1,12 @@
use inkwell::{ use inkwell::{
context::Context, context::Context,
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType}, types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
values::{IntValue, PointerValue},
AddressSpace, AddressSpace,
}; };
use super::ProxyType; use super::ProxyType;
use crate::codegen::{ use crate::codegen::{
values::{ArraySliceValue, ListValue, ProxyValue}, values::{ListValue, ProxyValue},
CodeGenContext, CodeGenerator, CodeGenContext, CodeGenerator,
}; };
@ -114,14 +113,28 @@ impl<'ctx> ListType<'ctx> {
/// Allocates an instance of [`ListValue`] as if by calling `alloca` on the base type. /// Allocates an instance of [`ListValue`] as if by calling `alloca` on the base type.
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(ctx, name),
self.llvm_usize,
name,
)
}
/// Allocates an instance of [`ListValue`] as if by calling `alloca` on the base type.
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
self.llvm_usize, self.llvm_usize,
name, name,
) )
@ -162,36 +175,8 @@ impl<'ctx> ProxyType<'ctx> for ListType<'ctx> {
Self::is_representable(llvm_ty, generator.get_size_type(ctx)) Self::is_representable(llvm_ty, generator.get_size_type(ctx))
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -57,24 +57,66 @@ pub trait ProxyType<'ctx>: Into<Self::Base> {
llvm_ty: Self::Base, llvm_ty: Self::Base,
) -> Result<(), String>; ) -> Result<(), String>;
/// Creates a new value of this type by invoking `alloca`, returning a [`PointerValue`] instance /// Returns the type that should be used in `alloca` IR statements.
/// representing the allocated value. fn alloca_type(&self) -> impl BasicType<'ctx>;
fn raw_alloca<G: CodeGenerator + ?Sized>(
/// Creates a new value of this type by invoking `alloca` at the current builder location,
/// returning a [`PointerValue`] instance representing the allocated value.
fn raw_alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
ctx.builder
.build_alloca(self.alloca_type().as_basic_type_enum(), name.unwrap_or_default())
.unwrap()
}
/// Creates a new value of this type by invoking `alloca` at the beginning of the function,
/// returning a [`PointerValue`] instance representing the allocated value.
fn raw_alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> PointerValue<'ctx>; ) -> PointerValue<'ctx> {
generator.gen_var_alloc(ctx, self.alloca_type().as_basic_type_enum(), name).unwrap()
}
/// Creates a new array value of this type, returning an [`ArraySliceValue`] encapsulating the /// Creates a new array value of this type by invoking `alloca` at the current builder location,
/// resulting array. /// returning an [`ArraySliceValue`] encapsulating the resulting array.
fn array_alloca<G: CodeGenerator + ?Sized>( fn array_alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
ArraySliceValue::from_ptr_val(
ctx.builder
.build_array_alloca(
self.alloca_type().as_basic_type_enum(),
size,
name.unwrap_or_default(),
)
.unwrap(),
size,
name,
)
}
/// Creates a new array value of this type by invoking `alloca` at the beginning of the
/// function, returning an [`ArraySliceValue`] encapsulating the resulting array.
fn array_alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>, size: IntValue<'ctx>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx>; ) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(ctx, self.alloca_type().as_basic_type_enum(), size, name)
.unwrap()
}
/// Returns the [base type][Self::Base] of this proxy. /// Returns the [base type][Self::Base] of this proxy.
fn as_base_type(&self) -> Self::Base; fn as_base_type(&self) -> Self::Base;

View File

@ -16,7 +16,7 @@ use crate::{
}, },
ProxyType, ProxyType,
}, },
values::{ndarray::ContiguousNDArrayValue, ArraySliceValue, ProxyValue}, values::{ndarray::ContiguousNDArrayValue, ProxyValue},
CodeGenContext, CodeGenerator, CodeGenContext, CodeGenerator,
}, },
toplevel::numpy::unpack_ndarray_var_tys, toplevel::numpy::unpack_ndarray_var_tys,
@ -159,14 +159,29 @@ impl<'ctx> ContiguousNDArrayType<'ctx> {
/// Allocates an instance of [`ContiguousNDArrayValue`] as if by calling `alloca` on the base type. /// Allocates an instance of [`ContiguousNDArrayValue`] as if by calling `alloca` on the base type.
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(ctx, name),
self.item,
self.llvm_usize,
name,
)
}
/// Allocates an instance of [`ContiguousNDArrayValue`] as if by calling `alloca` on the base type.
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
self.item, self.item,
self.llvm_usize, self.llvm_usize,
name, name,
@ -213,36 +228,8 @@ impl<'ctx> ProxyType<'ctx> for ContiguousNDArrayType<'ctx> {
Self::is_representable(llvm_ty, generator.get_size_type(ctx)) Self::is_representable(llvm_ty, generator.get_size_type(ctx))
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -91,14 +91,27 @@ impl<'ctx> NDIndexType<'ctx> {
} }
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(ctx, name),
self.llvm_usize,
name,
)
}
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
self.llvm_usize, self.llvm_usize,
name, name,
) )
@ -114,7 +127,7 @@ impl<'ctx> NDIndexType<'ctx> {
) -> ArraySliceValue<'ctx> { ) -> ArraySliceValue<'ctx> {
// Allocate the LLVM ndindices. // Allocate the LLVM ndindices.
let num_ndindices = self.llvm_usize.const_int(in_ndindices.len() as u64, false); let num_ndindices = self.llvm_usize.const_int(in_ndindices.len() as u64, false);
let ndindices = self.array_alloca(generator, ctx, num_ndindices, None); let ndindices = self.array_alloca_var(generator, ctx, num_ndindices, None);
// Initialize all of them. // Initialize all of them.
for (i, in_ndindex) in in_ndindices.iter().enumerate() { for (i, in_ndindex) in in_ndindices.iter().enumerate() {
@ -171,36 +184,8 @@ impl<'ctx> ProxyType<'ctx> for NDIndexType<'ctx> {
Self::is_representable(llvm_ty, generator.get_size_type(ctx)) Self::is_representable(llvm_ty, generator.get_size_type(ctx))
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -14,7 +14,7 @@ use super::{
}; };
use crate::{ use crate::{
codegen::{ codegen::{
values::{ndarray::NDArrayValue, ArraySliceValue, ProxyValue, TypedArrayLikeMutator}, values::{ndarray::NDArrayValue, ProxyValue, TypedArrayLikeMutator},
{CodeGenContext, CodeGenerator}, {CodeGenContext, CodeGenerator},
}, },
toplevel::{helper::extract_ndims, numpy::unpack_ndarray_var_tys}, toplevel::{helper::extract_ndims, numpy::unpack_ndarray_var_tys},
@ -183,14 +183,30 @@ impl<'ctx> NDArrayType<'ctx> {
/// Allocates an instance of [`NDArrayValue`] as if by calling `alloca` on the base type. /// Allocates an instance of [`NDArrayValue`] as if by calling `alloca` on the base type.
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(ctx, name),
self.dtype,
self.ndims,
self.llvm_usize,
name,
)
}
/// Allocates an instance of [`NDArrayValue`] as if by calling `alloca` on the base type.
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
self.dtype, self.dtype,
self.ndims, self.ndims,
self.llvm_usize, self.llvm_usize,
@ -214,7 +230,7 @@ impl<'ctx> NDArrayType<'ctx> {
ndims: IntValue<'ctx>, ndims: IntValue<'ctx>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
let ndarray = self.alloca(generator, ctx, name); let ndarray = self.alloca_var(generator, ctx, name);
let itemsize = ctx let itemsize = ctx
.builder .builder
@ -425,36 +441,8 @@ impl<'ctx> ProxyType<'ctx> for NDArrayType<'ctx> {
Self::is_representable(llvm_ty, generator.get_size_type(ctx)) Self::is_representable(llvm_ty, generator.get_size_type(ctx))
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -110,7 +110,24 @@ impl<'ctx> NDIterType<'ctx> {
} }
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
parent: NDArrayValue<'ctx>,
indices: ArraySliceValue<'ctx>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(ctx, name),
parent,
indices,
self.llvm_usize,
name,
)
}
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
@ -119,7 +136,7 @@ impl<'ctx> NDIterType<'ctx> {
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
parent, parent,
indices, indices,
self.llvm_usize, self.llvm_usize,
@ -140,7 +157,7 @@ impl<'ctx> NDIterType<'ctx> {
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
ndarray: NDArrayValue<'ctx>, ndarray: NDArrayValue<'ctx>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
let nditer = self.raw_alloca(generator, ctx, None); let nditer = self.raw_alloca_var(generator, ctx, None);
let ndims = ndarray.load_ndims(ctx); let ndims = ndarray.load_ndims(ctx);
// The caller has the responsibility to allocate 'indices' for `NDIter`. // The caller has the responsibility to allocate 'indices' for `NDIter`.
@ -198,36 +215,8 @@ impl<'ctx> ProxyType<'ctx> for NDIterType<'ctx> {
Self::is_representable(llvm_ty, generator.get_size_type(ctx)) Self::is_representable(llvm_ty, generator.get_size_type(ctx))
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -1,13 +1,12 @@
use inkwell::{ use inkwell::{
context::Context, context::Context,
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType}, types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
values::{IntValue, PointerValue},
AddressSpace, AddressSpace,
}; };
use super::ProxyType; use super::ProxyType;
use crate::codegen::{ use crate::codegen::{
values::{ArraySliceValue, ProxyValue, RangeValue}, values::{ProxyValue, RangeValue},
{CodeGenContext, CodeGenerator}, {CodeGenContext, CodeGenerator},
}; };
@ -80,13 +79,23 @@ impl<'ctx> RangeType<'ctx> {
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type. /// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca<G: CodeGenerator + ?Sized>(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(self.raw_alloca(ctx, name), name)
}
/// Allocates an instance of [`RangeValue`] as if by calling `alloca` on the base type.
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
name, name,
) )
} }
@ -126,36 +135,8 @@ impl<'ctx> ProxyType<'ctx> for RangeType<'ctx> {
Self::is_representable(llvm_ty) Self::is_representable(llvm_ty)
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -1,7 +1,7 @@
use inkwell::{ use inkwell::{
context::{AsContextRef, Context, ContextRef}, context::{AsContextRef, Context, ContextRef},
types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType}, types::{AnyTypeEnum, BasicType, BasicTypeEnum, IntType, PointerType},
values::{IntValue, PointerValue}, values::IntValue,
AddressSpace, AddressSpace,
}; };
use itertools::Itertools; use itertools::Itertools;
@ -15,7 +15,7 @@ use crate::codegen::{
}, },
ProxyType, ProxyType,
}, },
values::{utils::SliceValue, ArraySliceValue, ProxyValue}, values::{utils::SliceValue, ProxyValue},
CodeGenContext, CodeGenerator, CodeGenContext, CodeGenerator,
}; };
@ -156,14 +156,29 @@ impl<'ctx> SliceType<'ctx> {
/// Allocates an instance of [`ContiguousNDArrayValue`] as if by calling `alloca` on the base type. /// Allocates an instance of [`ContiguousNDArrayValue`] as if by calling `alloca` on the base type.
#[must_use] #[must_use]
pub fn alloca<G: CodeGenerator + ?Sized>( pub fn alloca(
&self,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(ctx, name),
self.int_ty,
self.llvm_usize,
name,
)
}
/// Allocates an instance of [`ContiguousNDArrayValue`] as if by calling `alloca` on the base type.
#[must_use]
pub fn alloca_var<G: CodeGenerator + ?Sized>(
&self, &self,
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>, name: Option<&'ctx str>,
) -> <Self as ProxyType<'ctx>>::Value { ) -> <Self as ProxyType<'ctx>>::Value {
<Self as ProxyType<'ctx>>::Value::from_pointer_value( <Self as ProxyType<'ctx>>::Value::from_pointer_value(
self.raw_alloca(generator, ctx, name), self.raw_alloca_var(generator, ctx, name),
self.int_ty, self.int_ty,
self.llvm_usize, self.llvm_usize,
name, name,
@ -210,36 +225,8 @@ impl<'ctx> ProxyType<'ctx> for SliceType<'ctx> {
Self::is_representable(llvm_ty, generator.get_size_type(ctx)) Self::is_representable(llvm_ty, generator.get_size_type(ctx))
} }
fn raw_alloca<G: CodeGenerator + ?Sized>( fn alloca_type(&self) -> impl BasicType<'ctx> {
&self, self.as_base_type().get_element_type().into_struct_type()
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
name: Option<&'ctx str>,
) -> PointerValue<'ctx> {
generator
.gen_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
name,
)
.unwrap()
}
fn array_alloca<G: CodeGenerator + ?Sized>(
&self,
generator: &mut G,
ctx: &mut CodeGenContext<'ctx, '_>,
size: IntValue<'ctx>,
name: Option<&'ctx str>,
) -> ArraySliceValue<'ctx> {
generator
.gen_array_var_alloc(
ctx,
self.as_base_type().get_element_type().into_struct_type().into(),
size,
name,
)
.unwrap()
} }
fn as_base_type(&self) -> Self::Base { fn as_base_type(&self) -> Self::Base {

View File

@ -118,7 +118,7 @@ impl<'ctx> NDArrayValue<'ctx> {
ctx: &mut CodeGenContext<'ctx, '_>, ctx: &mut CodeGenContext<'ctx, '_>,
) -> ContiguousNDArrayValue<'ctx> { ) -> ContiguousNDArrayValue<'ctx> {
let result = ContiguousNDArrayType::new(generator, ctx.ctx, self.dtype) let result = ContiguousNDArrayType::new(generator, ctx.ctx, self.dtype)
.alloca(generator, ctx, self.name); .alloca_var(generator, ctx, self.name);
// Set ndims and shape. // Set ndims and shape.
let ndims = self let ndims = self

View File

@ -248,7 +248,7 @@ impl<'ctx> RustNDIndex<'ctx> {
RustNDIndex::Slice(in_rust_slice) => { RustNDIndex::Slice(in_rust_slice) => {
let user_slice_ptr = let user_slice_ptr =
SliceType::new(ctx.ctx, ctx.ctx.i32_type(), generator.get_size_type(ctx.ctx)) SliceType::new(ctx.ctx, ctx.ctx.i32_type(), generator.get_size_type(ctx.ctx))
.alloca(generator, ctx, None); .alloca_var(generator, ctx, None);
in_rust_slice.write_to_slice(ctx, user_slice_ptr); in_rust_slice.write_to_slice(ctx, user_slice_ptr);
dst_ndindex.store_data( dst_ndindex.store_data(