Compare commits
16 Commits
b2994ff90a
...
d2ce0679ed
Author | SHA1 | Date |
---|---|---|
David Mak | d2ce0679ed | |
David Mak | aa673fce4e | |
David Mak | ddfd19d00c | |
David Mak | 4887cd8007 | |
David Mak | 876e850d71 | |
David Mak | 1de2e9a4be | |
David Mak | 2b0beea8c0 | |
David Mak | 5778de02fc | |
David Mak | 13f06f3e29 | |
David Mak | f0da9c0283 | |
David Mak | 2c4bf3ce59 | |
David Mak | e980f19c93 | |
David Mak | cfbc37c1ed | |
David Mak | 50264e8750 | |
David Mak | 1b77e62901 | |
David Mak | fd44ee6887 |
|
@ -1,12 +1,12 @@
|
||||||
use inkwell::{
|
use inkwell::{
|
||||||
IntPredicate,
|
IntPredicate,
|
||||||
types::{AnyTypeEnum, BasicTypeEnum, IntType, PointerType},
|
types::{AnyTypeEnum, BasicTypeEnum, IntType, PointerType},
|
||||||
values::{ArrayValue, BasicValueEnum, IntValue, PointerValue},
|
values::{BasicValueEnum, IntValue, PointerValue},
|
||||||
};
|
};
|
||||||
use crate::codegen::{
|
use crate::codegen::{
|
||||||
CodeGenContext,
|
CodeGenContext,
|
||||||
CodeGenerator,
|
CodeGenerator,
|
||||||
irrt::{call_ndarray_calc_size, call_ndarray_flatten_index, call_ndarray_flatten_index_const},
|
irrt::{call_ndarray_calc_size, call_ndarray_flatten_index},
|
||||||
llvm_intrinsics::call_int_umin,
|
llvm_intrinsics::call_int_umin,
|
||||||
stmt::gen_for_callback_incrementing,
|
stmt::gen_for_callback_incrementing,
|
||||||
};
|
};
|
||||||
|
@ -200,8 +200,7 @@ type ValueDowncastFn<'ctx, T> = Box<dyn Fn(&mut CodeGenContext<'ctx, '_>, BasicV
|
||||||
type ValueUpcastFn<'ctx, T> = Box<dyn Fn(&mut CodeGenContext<'ctx, '_>, T) -> BasicValueEnum<'ctx>>;
|
type ValueUpcastFn<'ctx, T> = Box<dyn Fn(&mut CodeGenContext<'ctx, '_>, T) -> BasicValueEnum<'ctx>>;
|
||||||
|
|
||||||
/// An adapter for constraining untyped array values as typed values.
|
/// An adapter for constraining untyped array values as typed values.
|
||||||
#[allow(clippy::type_complexity)]
|
pub struct TypedArrayLikeAdapter<'ctx, T, Adapted: ArrayLikeValue<'ctx> = ArraySliceValue<'ctx>> {
|
||||||
pub struct TypedArrayLikeAdapter<'ctx, T, Adapted: ArrayLikeValue<'ctx>> {
|
|
||||||
adapted: Adapted,
|
adapted: Adapted,
|
||||||
downcast_fn: ValueDowncastFn<'ctx, T>,
|
downcast_fn: ValueDowncastFn<'ctx, T>,
|
||||||
upcast_fn: ValueUpcastFn<'ctx, T>,
|
upcast_fn: ValueUpcastFn<'ctx, T>,
|
||||||
|
@ -214,7 +213,7 @@ impl<'ctx, T, Adapted> TypedArrayLikeAdapter<'ctx, T, Adapted>
|
||||||
/// * `adapted` - The value to be adapted.
|
/// * `adapted` - The value to be adapted.
|
||||||
/// * `downcast_fn` - The function converting a [`BasicValueEnum`] into a `T`.
|
/// * `downcast_fn` - The function converting a [`BasicValueEnum`] into a `T`.
|
||||||
/// * `upcast_fn` - The function converting a T into a [`BasicValueEnum`].
|
/// * `upcast_fn` - The function converting a T into a [`BasicValueEnum`].
|
||||||
fn from(
|
pub fn from(
|
||||||
adapted: Adapted,
|
adapted: Adapted,
|
||||||
downcast_fn: ValueDowncastFn<'ctx, T>,
|
downcast_fn: ValueDowncastFn<'ctx, T>,
|
||||||
upcast_fn: ValueUpcastFn<'ctx, T>,
|
upcast_fn: ValueUpcastFn<'ctx, T>,
|
||||||
|
@ -498,8 +497,8 @@ impl<'ctx> ListValue<'ctx> {
|
||||||
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
||||||
/// on the field.
|
/// on the field.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn data(&self) -> ListDataProxy<'ctx> {
|
pub fn data(&self) -> ListDataProxy<'ctx, '_> {
|
||||||
ListDataProxy(*self)
|
ListDataProxy(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stores the `size` of this `list` into this instance.
|
/// Stores the `size` of this `list` into this instance.
|
||||||
|
@ -537,9 +536,9 @@ impl<'ctx> From<ListValue<'ctx>> for PointerValue<'ctx> {
|
||||||
|
|
||||||
/// Proxy type for accessing the `data` array of an `list` instance in LLVM.
|
/// Proxy type for accessing the `data` array of an `list` instance in LLVM.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct ListDataProxy<'ctx>(ListValue<'ctx>);
|
pub struct ListDataProxy<'ctx, 'a>(&'a ListValue<'ctx>);
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx> {
|
impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx, '_> {
|
||||||
fn element_type<G: CodeGenerator + ?Sized>(
|
fn element_type<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
_: &CodeGenContext<'ctx, '_>,
|
_: &CodeGenContext<'ctx, '_>,
|
||||||
|
@ -569,7 +568,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for ListDataProxy<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeIndexer<'ctx> for ListDataProxy<'ctx> {
|
impl<'ctx> ArrayLikeIndexer<'ctx> for ListDataProxy<'ctx, '_> {
|
||||||
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -614,8 +613,8 @@ impl<'ctx> ArrayLikeIndexer<'ctx> for ListDataProxy<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> UntypedArrayLikeAccessor<'ctx> for ListDataProxy<'ctx> {}
|
impl<'ctx> UntypedArrayLikeAccessor<'ctx> for ListDataProxy<'ctx, '_> {}
|
||||||
impl<'ctx> UntypedArrayLikeMutator<'ctx> for ListDataProxy<'ctx> {}
|
impl<'ctx> UntypedArrayLikeMutator<'ctx> for ListDataProxy<'ctx, '_> {}
|
||||||
|
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
pub fn assert_is_range(_value: PointerValue) {}
|
pub fn assert_is_range(_value: PointerValue) {}
|
||||||
|
@ -929,8 +928,8 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||||
|
|
||||||
/// Returns a proxy object to the field storing the size of each dimension of this `NDArray`.
|
/// Returns a proxy object to the field storing the size of each dimension of this `NDArray`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn dim_sizes(&self) -> NDArrayDimsProxy<'ctx> {
|
pub fn dim_sizes(&self) -> NDArrayDimsProxy<'ctx, '_> {
|
||||||
NDArrayDimsProxy(*self)
|
NDArrayDimsProxy(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
/// Returns the double-indirection pointer to the `data` array, as if by calling `getelementptr`
|
||||||
|
@ -966,8 +965,8 @@ impl<'ctx> NDArrayValue<'ctx> {
|
||||||
|
|
||||||
/// Returns a proxy object to the field storing the data of this `NDArray`.
|
/// Returns a proxy object to the field storing the data of this `NDArray`.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn data(&self) -> NDArrayDataProxy<'ctx> {
|
pub fn data(&self) -> NDArrayDataProxy<'ctx, '_> {
|
||||||
NDArrayDataProxy(*self)
|
NDArrayDataProxy(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -979,9 +978,9 @@ impl<'ctx> From<NDArrayValue<'ctx>> for PointerValue<'ctx> {
|
||||||
|
|
||||||
/// Proxy type for accessing the `dims` array of an `NDArray` instance in LLVM.
|
/// Proxy type for accessing the `dims` array of an `NDArray` instance in LLVM.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct NDArrayDimsProxy<'ctx>(NDArrayValue<'ctx>);
|
pub struct NDArrayDimsProxy<'ctx, 'a>(&'a NDArrayValue<'ctx>);
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDimsProxy<'ctx> {
|
impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDimsProxy<'ctx, '_> {
|
||||||
fn element_type<G: CodeGenerator + ?Sized>(
|
fn element_type<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &CodeGenContext<'ctx, '_>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1011,7 +1010,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDimsProxy<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx> {
|
impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx, '_> {
|
||||||
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1059,10 +1058,10 @@ impl<'ctx> ArrayLikeIndexer<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> UntypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx> {}
|
impl<'ctx> UntypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx, '_> {}
|
||||||
impl<'ctx> UntypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx> {}
|
impl<'ctx> UntypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx, '_> {}
|
||||||
|
|
||||||
impl<'ctx> TypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx> {
|
impl<'ctx> TypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx, '_> {
|
||||||
fn downcast_to_type(
|
fn downcast_to_type(
|
||||||
&self,
|
&self,
|
||||||
_: &mut CodeGenContext<'ctx, '_>,
|
_: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1072,7 +1071,7 @@ impl<'ctx> TypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> TypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx> {
|
impl<'ctx> TypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx, '_> {
|
||||||
fn upcast_from_type(
|
fn upcast_from_type(
|
||||||
&self,
|
&self,
|
||||||
_: &mut CodeGenContext<'ctx, '_>,
|
_: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1084,9 +1083,9 @@ impl<'ctx> TypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDimsProxy<'ctx
|
||||||
|
|
||||||
/// Proxy type for accessing the `data` array of an `NDArray` instance in LLVM.
|
/// Proxy type for accessing the `data` array of an `NDArray` instance in LLVM.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct NDArrayDataProxy<'ctx>(NDArrayValue<'ctx>);
|
pub struct NDArrayDataProxy<'ctx, 'a>(&'a NDArrayValue<'ctx>);
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDataProxy<'ctx> {
|
impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDataProxy<'ctx, '_> {
|
||||||
fn element_type<G: CodeGenerator + ?Sized>(
|
fn element_type<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &CodeGenContext<'ctx, '_>,
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1116,7 +1115,7 @@ impl<'ctx> ArrayLikeValue<'ctx> for NDArrayDataProxy<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeIndexer<'ctx> for NDArrayDataProxy<'ctx> {
|
impl<'ctx> ArrayLikeIndexer<'ctx> for NDArrayDataProxy<'ctx, '_> {
|
||||||
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1160,102 +1159,10 @@ impl<'ctx> ArrayLikeIndexer<'ctx> for NDArrayDataProxy<'ctx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> UntypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDataProxy<'ctx> {}
|
impl<'ctx> UntypedArrayLikeAccessor<'ctx, IntValue<'ctx>> for NDArrayDataProxy<'ctx, '_> {}
|
||||||
impl<'ctx> UntypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDataProxy<'ctx> {}
|
impl<'ctx> UntypedArrayLikeMutator<'ctx, IntValue<'ctx>> for NDArrayDataProxy<'ctx, '_> {}
|
||||||
|
|
||||||
impl<'ctx> ArrayLikeIndexer<'ctx, ArrayValue<'ctx>> for NDArrayDataProxy<'ctx> {
|
impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> ArrayLikeIndexer<'ctx, Index> for NDArrayDataProxy<'ctx, '_> {
|
||||||
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
|
||||||
&self,
|
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
|
||||||
generator: &mut G,
|
|
||||||
indices: ArrayValue<'ctx>,
|
|
||||||
name: Option<&str>,
|
|
||||||
) -> PointerValue<'ctx> {
|
|
||||||
let index = call_ndarray_flatten_index_const(
|
|
||||||
generator,
|
|
||||||
ctx,
|
|
||||||
self.0,
|
|
||||||
indices,
|
|
||||||
);
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
ctx.builder.build_in_bounds_gep(
|
|
||||||
self.base_ptr(ctx, generator),
|
|
||||||
&[index],
|
|
||||||
name.unwrap_or_default(),
|
|
||||||
)
|
|
||||||
}.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ptr_offset<G: CodeGenerator + ?Sized>(
|
|
||||||
&self,
|
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
|
||||||
generator: &mut G,
|
|
||||||
indices: ArrayValue<'ctx>,
|
|
||||||
name: Option<&str>,
|
|
||||||
) -> PointerValue<'ctx> {
|
|
||||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
|
||||||
|
|
||||||
let indices_elem_ty = indices.get_type().get_element_type();
|
|
||||||
let Ok(indices_elem_ty) = IntType::try_from(indices_elem_ty) else {
|
|
||||||
panic!("Expected [int32] but got [{indices_elem_ty}]")
|
|
||||||
};
|
|
||||||
assert_eq!(indices_elem_ty.get_bit_width(), 32, "Expected [int32] but got [{indices_elem_ty}]");
|
|
||||||
|
|
||||||
let nidx_leq_ndims = ctx.builder.build_int_compare(
|
|
||||||
IntPredicate::SLE,
|
|
||||||
llvm_usize.const_int(indices.get_type().len() as u64, false),
|
|
||||||
self.0.load_ndims(ctx),
|
|
||||||
""
|
|
||||||
).unwrap();
|
|
||||||
ctx.make_assert(
|
|
||||||
generator,
|
|
||||||
nidx_leq_ndims,
|
|
||||||
"0:IndexError",
|
|
||||||
"invalid index to scalar variable",
|
|
||||||
[None, None, None],
|
|
||||||
ctx.current_loc,
|
|
||||||
);
|
|
||||||
|
|
||||||
for idx in 0..indices.get_type().len() {
|
|
||||||
let i = llvm_usize.const_int(idx as u64, false);
|
|
||||||
|
|
||||||
let dim_idx = ctx.builder
|
|
||||||
.build_extract_value(indices, idx, "")
|
|
||||||
.map(BasicValueEnum::into_int_value)
|
|
||||||
.map(|v| ctx.builder.build_int_z_extend_or_bit_cast(v, llvm_usize, "").unwrap())
|
|
||||||
.unwrap();
|
|
||||||
let dim_sz = unsafe {
|
|
||||||
self.0.dim_sizes().get_typed_unchecked(ctx, generator, i, None)
|
|
||||||
};
|
|
||||||
|
|
||||||
let dim_lt = ctx.builder.build_int_compare(
|
|
||||||
IntPredicate::SLT,
|
|
||||||
dim_idx,
|
|
||||||
dim_sz,
|
|
||||||
""
|
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
ctx.make_assert(
|
|
||||||
generator,
|
|
||||||
dim_lt,
|
|
||||||
"0:IndexError",
|
|
||||||
"index {0} is out of bounds for axis 0 with size {1}",
|
|
||||||
[Some(dim_idx), Some(dim_sz), None],
|
|
||||||
ctx.current_loc,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
self.ptr_offset_unchecked(ctx, generator, indices, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> UntypedArrayLikeAccessor<'ctx, ArrayValue<'ctx>> for NDArrayDataProxy<'ctx> {}
|
|
||||||
impl<'ctx> UntypedArrayLikeMutator<'ctx, ArrayValue<'ctx>> for NDArrayDataProxy<'ctx> {}
|
|
||||||
|
|
||||||
impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> ArrayLikeIndexer<'ctx, Index> for NDArrayDataProxy<'ctx> {
|
|
||||||
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
unsafe fn ptr_offset_unchecked<G: CodeGenerator + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
|
@ -1269,12 +1176,12 @@ impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> ArrayLikeIndexer<'ctx, Index>
|
||||||
let Ok(indices_elem_ty) = IntType::try_from(indices_elem_ty) else {
|
let Ok(indices_elem_ty) = IntType::try_from(indices_elem_ty) else {
|
||||||
panic!("Expected list[int32] but got {indices_elem_ty}")
|
panic!("Expected list[int32] but got {indices_elem_ty}")
|
||||||
};
|
};
|
||||||
assert_eq!(indices_elem_ty.get_bit_width(), 32, "Expected list[int32] but got {indices_elem_ty}");
|
assert_eq!(indices_elem_ty.get_bit_width(), 32, "Expected list[int32] but got list[int{}]", indices_elem_ty.get_bit_width());
|
||||||
|
|
||||||
let index = call_ndarray_flatten_index(
|
let index = call_ndarray_flatten_index(
|
||||||
generator,
|
generator,
|
||||||
ctx,
|
ctx,
|
||||||
self.0,
|
*self.0,
|
||||||
&indices,
|
&indices,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1327,6 +1234,9 @@ impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> ArrayLikeIndexer<'ctx, Index>
|
||||||
self.0.dim_sizes().get_typed_unchecked(ctx, generator, i, None),
|
self.0.dim_sizes().get_typed_unchecked(ctx, generator, i, None),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
let dim_idx = ctx.builder
|
||||||
|
.build_int_z_extend_or_bit_cast(dim_idx, dim_sz.get_type(), "")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let dim_lt = ctx.builder.build_int_compare(
|
let dim_lt = ctx.builder.build_int_compare(
|
||||||
IntPredicate::SLT,
|
IntPredicate::SLT,
|
||||||
|
@ -1355,5 +1265,5 @@ impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> ArrayLikeIndexer<'ctx, Index>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> UntypedArrayLikeAccessor<'ctx, Index> for NDArrayDataProxy<'ctx> {}
|
impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> UntypedArrayLikeAccessor<'ctx, Index> for NDArrayDataProxy<'ctx, '_> {}
|
||||||
impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> UntypedArrayLikeMutator<'ctx, Index> for NDArrayDataProxy<'ctx> {}
|
impl<'ctx, Index: UntypedArrayLikeAccessor<'ctx>> UntypedArrayLikeMutator<'ctx, Index> for NDArrayDataProxy<'ctx, '_> {}
|
||||||
|
|
|
@ -43,6 +43,7 @@ use itertools::{chain, izip, Itertools, Either};
|
||||||
use nac3parser::ast::{
|
use nac3parser::ast::{
|
||||||
self, Boolop, Comprehension, Constant, Expr, ExprKind, Location, Operator, StrRef,
|
self, Boolop, Comprehension, Constant, Expr, ExprKind, Location, Operator, StrRef,
|
||||||
};
|
};
|
||||||
|
use crate::codegen::classes::ArraySliceValue;
|
||||||
|
|
||||||
use super::{CodeGenerator, llvm_intrinsics::call_memcpy_generic, need_sret};
|
use super::{CodeGenerator, llvm_intrinsics::call_memcpy_generic, need_sret};
|
||||||
|
|
||||||
|
@ -1330,12 +1331,14 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
|
||||||
} else {
|
} else {
|
||||||
return Ok(None)
|
return Ok(None)
|
||||||
};
|
};
|
||||||
|
let index_addr = generator.gen_var_alloc(ctx, index.get_type().into(), None)?;
|
||||||
|
ctx.builder.build_store(index_addr, index).unwrap();
|
||||||
|
|
||||||
Ok(Some(v.data()
|
Ok(Some(v.data()
|
||||||
.get(
|
.get(
|
||||||
ctx,
|
ctx,
|
||||||
generator,
|
generator,
|
||||||
ctx.ctx.i32_type().const_array(&[index]),
|
ArraySliceValue::from_ptr_val(index_addr, llvm_usize.const_int(1, false), None),
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.into()))
|
.into()))
|
||||||
|
@ -1351,6 +1354,8 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
|
||||||
} else {
|
} else {
|
||||||
return Ok(None)
|
return Ok(None)
|
||||||
};
|
};
|
||||||
|
let index_addr = generator.gen_var_alloc(ctx, index.get_type().into(), None)?;
|
||||||
|
ctx.builder.build_store(index_addr, index).unwrap();
|
||||||
|
|
||||||
// Create a new array, remove the top dimension from the dimension-size-list, and copy the
|
// Create a new array, remove the top dimension from the dimension-size-list, and copy the
|
||||||
// elements over
|
// elements over
|
||||||
|
@ -1405,7 +1410,7 @@ fn gen_ndarray_subscript_expr<'ctx, G: CodeGenerator>(
|
||||||
let v_data_src_ptr = v.data().ptr_offset(
|
let v_data_src_ptr = v.data().ptr_offset(
|
||||||
ctx,
|
ctx,
|
||||||
generator,
|
generator,
|
||||||
ctx.ctx.i32_type().const_array(&[index]),
|
ArraySliceValue::from_ptr_val(index_addr, llvm_usize.const_int(1, false), None),
|
||||||
None
|
None
|
||||||
);
|
);
|
||||||
call_memcpy_generic(
|
call_memcpy_generic(
|
||||||
|
|
|
@ -245,13 +245,13 @@ void __nac3_ndarray_calc_nd_indices64(
|
||||||
uint64_t index,
|
uint64_t index,
|
||||||
const uint64_t* dims,
|
const uint64_t* dims,
|
||||||
uint64_t num_dims,
|
uint64_t num_dims,
|
||||||
uint64_t* idxs
|
uint32_t* idxs
|
||||||
) {
|
) {
|
||||||
uint64_t stride = 1;
|
uint64_t stride = 1;
|
||||||
for (uint64_t dim = 0; dim < num_dims; dim++) {
|
for (uint64_t dim = 0; dim < num_dims; dim++) {
|
||||||
uint64_t i = num_dims - dim - 1;
|
uint64_t i = num_dims - dim - 1;
|
||||||
__builtin_assume(dims[i] > 0);
|
__builtin_assume(dims[i] > 0);
|
||||||
idxs[i] = (index / stride) % dims[i];
|
idxs[i] = (uint32_t) ((index / stride) % dims[i]);
|
||||||
stride *= dims[i];
|
stride *= dims[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,11 +371,11 @@ void __nac3_ndarray_calc_broadcast_idx(
|
||||||
void __nac3_ndarray_calc_broadcast_idx64(
|
void __nac3_ndarray_calc_broadcast_idx64(
|
||||||
const uint64_t *src_dims,
|
const uint64_t *src_dims,
|
||||||
uint64_t src_ndims,
|
uint64_t src_ndims,
|
||||||
const uint64_t *in_idx,
|
const uint32_t *in_idx,
|
||||||
uint64_t *out_idx
|
uint32_t *out_idx
|
||||||
) {
|
) {
|
||||||
for (uint64_t i = 0; i < src_ndims; ++i) {
|
for (uint64_t i = 0; i < src_ndims; ++i) {
|
||||||
uint64_t src_i = src_ndims - i - 1;
|
uint64_t src_i = src_ndims - i - 1;
|
||||||
out_idx[src_i] = src_dims[src_i] == 1 ? 0 : in_idx[src_i];
|
out_idx[src_i] = src_dims[src_i] == 1 ? 0 : (uint32_t) in_idx[src_i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ use crate::typecheck::typedef::Type;
|
||||||
use super::{
|
use super::{
|
||||||
classes::{
|
classes::{
|
||||||
ArrayLikeIndexer,
|
ArrayLikeIndexer,
|
||||||
ArraySliceValue,
|
|
||||||
ArrayLikeValue,
|
ArrayLikeValue,
|
||||||
|
ArraySliceValue,
|
||||||
ListValue,
|
ListValue,
|
||||||
NDArrayValue,
|
NDArrayValue,
|
||||||
|
TypedArrayLikeAdapter,
|
||||||
UntypedArrayLikeAccessor,
|
UntypedArrayLikeAccessor,
|
||||||
UntypedArrayLikeMutator,
|
|
||||||
},
|
},
|
||||||
CodeGenContext,
|
CodeGenContext,
|
||||||
CodeGenerator,
|
CodeGenerator,
|
||||||
|
@ -20,7 +20,7 @@ use inkwell::{
|
||||||
memory_buffer::MemoryBuffer,
|
memory_buffer::MemoryBuffer,
|
||||||
module::Module,
|
module::Module,
|
||||||
types::{BasicTypeEnum, IntType},
|
types::{BasicTypeEnum, IntType},
|
||||||
values::{ArrayValue, BasicValueEnum, CallSiteValue, FloatValue, IntValue, PointerValue},
|
values::{BasicValueEnum, CallSiteValue, FloatValue, IntValue},
|
||||||
AddressSpace, IntPredicate,
|
AddressSpace, IntPredicate,
|
||||||
};
|
};
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
|
@ -628,7 +628,8 @@ pub fn call_ndarray_calc_size<'ctx, G, Dims>(
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `__nac3_ndarray_calc_nd_indices`.
|
/// Generates a call to `__nac3_ndarray_calc_nd_indices`. Returns a [`TypeArrayLikeAdpater`]
|
||||||
|
/// containing `i32` indices of the flattened index.
|
||||||
///
|
///
|
||||||
/// * `index` - The index to compute the multidimensional index for.
|
/// * `index` - The index to compute the multidimensional index for.
|
||||||
/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an
|
/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an
|
||||||
|
@ -638,10 +639,11 @@ pub fn call_ndarray_calc_nd_indices<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
index: IntValue<'ctx>,
|
index: IntValue<'ctx>,
|
||||||
ndarray: NDArrayValue<'ctx>,
|
ndarray: NDArrayValue<'ctx>,
|
||||||
) -> ArraySliceValue<'ctx> {
|
) -> TypedArrayLikeAdapter<'ctx, IntValue<'ctx>> {
|
||||||
let llvm_void = ctx.ctx.void_type();
|
let llvm_void = ctx.ctx.void_type();
|
||||||
|
let llvm_i32 = ctx.ctx.i32_type();
|
||||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
let llvm_usize = generator.get_size_type(ctx.ctx);
|
||||||
|
let llvm_pi32 = llvm_i32.ptr_type(AddressSpace::default());
|
||||||
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
||||||
|
|
||||||
let ndarray_calc_nd_indices_fn_name = match llvm_usize.get_bit_width() {
|
let ndarray_calc_nd_indices_fn_name = match llvm_usize.get_bit_width() {
|
||||||
|
@ -655,7 +657,7 @@ pub fn call_ndarray_calc_nd_indices<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
llvm_usize.into(),
|
llvm_usize.into(),
|
||||||
llvm_pusize.into(),
|
llvm_pusize.into(),
|
||||||
llvm_usize.into(),
|
llvm_usize.into(),
|
||||||
llvm_pusize.into(),
|
llvm_pi32.into(),
|
||||||
],
|
],
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
@ -667,7 +669,7 @@ pub fn call_ndarray_calc_nd_indices<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
let ndarray_dims = ndarray.dim_sizes();
|
let ndarray_dims = ndarray.dim_sizes();
|
||||||
|
|
||||||
let indices = ctx.builder.build_array_alloca(
|
let indices = ctx.builder.build_array_alloca(
|
||||||
llvm_usize,
|
llvm_i32,
|
||||||
ndarray_num_dims,
|
ndarray_num_dims,
|
||||||
"",
|
"",
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
@ -685,7 +687,11 @@ pub fn call_ndarray_calc_nd_indices<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
ArraySliceValue::from_ptr_val(indices, ndarray_num_dims, None)
|
TypedArrayLikeAdapter::from(
|
||||||
|
ArraySliceValue::from_ptr_val(indices, ndarray_num_dims, None),
|
||||||
|
Box::new(|_, v| v.into_int_value()),
|
||||||
|
Box::new(|_, v| v.into()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_ndarray_flatten_index_impl<'ctx, G, Indices>(
|
fn call_ndarray_flatten_index_impl<'ctx, G, Indices>(
|
||||||
|
@ -780,49 +786,6 @@ pub fn call_ndarray_flatten_index<'ctx, G, Index>(
|
||||||
indices,
|
indices,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/// Generates a call to `__nac3_ndarray_flatten_index`. Returns the flattened index for the
|
|
||||||
/// multidimensional index.
|
|
||||||
///
|
|
||||||
/// * `ndarray` - LLVM pointer to the `NDArray`. This value must be the LLVM representation of an
|
|
||||||
/// `NDArray`.
|
|
||||||
/// * `indices` - The multidimensional index to compute the flattened index for.
|
|
||||||
pub fn call_ndarray_flatten_index_const<'ctx, G: CodeGenerator + ?Sized>(
|
|
||||||
generator: &mut G,
|
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
|
||||||
ndarray: NDArrayValue<'ctx>,
|
|
||||||
indices: ArrayValue<'ctx>,
|
|
||||||
) -> IntValue<'ctx> {
|
|
||||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
|
||||||
|
|
||||||
let indices_size = indices.get_type().len();
|
|
||||||
let indices_alloca = generator.gen_array_var_alloc(
|
|
||||||
ctx,
|
|
||||||
indices.get_type().get_element_type(),
|
|
||||||
llvm_usize.const_int(indices_size as u64, false),
|
|
||||||
None,
|
|
||||||
).unwrap();
|
|
||||||
for i in 0..indices_size {
|
|
||||||
let v = ctx.builder.build_extract_value(indices, i, "")
|
|
||||||
.unwrap()
|
|
||||||
.into_int_value();
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
indices_alloca.set_unchecked(
|
|
||||||
ctx,
|
|
||||||
generator,
|
|
||||||
ctx.ctx.i32_type().const_int(i as u64, false),
|
|
||||||
v.into(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
call_ndarray_flatten_index_impl(
|
|
||||||
generator,
|
|
||||||
ctx,
|
|
||||||
ndarray,
|
|
||||||
&indices_alloca,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Generates a call to `__nac3_ndarray_calc_broadcast`. Returns a tuple containing the number of
|
/// Generates a call to `__nac3_ndarray_calc_broadcast`. Returns a tuple containing the number of
|
||||||
/// dimension and size of each dimension of the resultant `ndarray`.
|
/// dimension and size of each dimension of the resultant `ndarray`.
|
||||||
|
@ -831,7 +794,7 @@ pub fn call_ndarray_calc_broadcast<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
lhs: NDArrayValue<'ctx>,
|
lhs: NDArrayValue<'ctx>,
|
||||||
rhs: NDArrayValue<'ctx>,
|
rhs: NDArrayValue<'ctx>,
|
||||||
) -> (IntValue<'ctx>, PointerValue<'ctx>) {
|
) -> TypedArrayLikeAdapter<'ctx, IntValue<'ctx>> {
|
||||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
let llvm_usize = generator.get_size_type(ctx.ctx);
|
||||||
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
||||||
|
|
||||||
|
@ -881,6 +844,7 @@ pub fn call_ndarray_calc_broadcast<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
let rhs_dims = rhs.dim_sizes().base_ptr(ctx, generator);
|
let rhs_dims = rhs.dim_sizes().base_ptr(ctx, generator);
|
||||||
let rhs_ndims = rhs.load_ndims(ctx);
|
let rhs_ndims = rhs.load_ndims(ctx);
|
||||||
let out_dims = ctx.builder.build_array_alloca(llvm_usize, max_ndims, "").unwrap();
|
let out_dims = ctx.builder.build_array_alloca(llvm_usize, max_ndims, "").unwrap();
|
||||||
|
let out_dims = ArraySliceValue::from_ptr_val(out_dims, max_ndims, None);
|
||||||
|
|
||||||
ctx.builder
|
ctx.builder
|
||||||
.build_call(
|
.build_call(
|
||||||
|
@ -890,24 +854,31 @@ pub fn call_ndarray_calc_broadcast<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
lhs_ndims.into(),
|
lhs_ndims.into(),
|
||||||
rhs_dims.into(),
|
rhs_dims.into(),
|
||||||
rhs_ndims.into(),
|
rhs_ndims.into(),
|
||||||
out_dims.into(),
|
out_dims.base_ptr(ctx, generator).into(),
|
||||||
],
|
],
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
(max_ndims, out_dims)
|
TypedArrayLikeAdapter::from(
|
||||||
|
out_dims,
|
||||||
|
Box::new(|_, v| v.into_int_value()),
|
||||||
|
Box::new(|_, v| v.into()),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a call to `__nac3_ndarray_calc_broadcast_idx`. Returns an [`ArrayAllocaValue`]
|
/// Generates a call to `__nac3_ndarray_calc_broadcast_idx`. Returns an [`ArrayAllocaValue`]
|
||||||
/// containing the indices used for accessing `array` corresponding to the `broadcast_idx`.
|
/// containing the indices used for accessing `array` corresponding to the index of the broadcasted
|
||||||
|
/// array `broadcast_idx`.
|
||||||
pub fn call_ndarray_calc_broadcast_index<'ctx, G: CodeGenerator + ?Sized, BroadcastIdx: UntypedArrayLikeAccessor<'ctx>>(
|
pub fn call_ndarray_calc_broadcast_index<'ctx, G: CodeGenerator + ?Sized, BroadcastIdx: UntypedArrayLikeAccessor<'ctx>>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
array: NDArrayValue<'ctx>,
|
array: NDArrayValue<'ctx>,
|
||||||
broadcast_idx: &BroadcastIdx,
|
broadcast_idx: &BroadcastIdx,
|
||||||
) -> ArraySliceValue<'ctx> {
|
) -> TypedArrayLikeAdapter<'ctx, IntValue<'ctx>> {
|
||||||
|
let llvm_i32 = ctx.ctx.i32_type();
|
||||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
let llvm_usize = generator.get_size_type(ctx.ctx);
|
||||||
|
let llvm_pi32 = llvm_i32.ptr_type(AddressSpace::default());
|
||||||
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
let llvm_pusize = llvm_usize.ptr_type(AddressSpace::default());
|
||||||
|
|
||||||
let ndarray_calc_broadcast_fn_name = match llvm_usize.get_bit_width() {
|
let ndarray_calc_broadcast_fn_name = match llvm_usize.get_bit_width() {
|
||||||
|
@ -920,8 +891,8 @@ pub fn call_ndarray_calc_broadcast_index<'ctx, G: CodeGenerator + ?Sized, Broadc
|
||||||
&[
|
&[
|
||||||
llvm_pusize.into(),
|
llvm_pusize.into(),
|
||||||
llvm_usize.into(),
|
llvm_usize.into(),
|
||||||
llvm_pusize.into(),
|
llvm_pi32.into(),
|
||||||
llvm_usize.into(),
|
llvm_pi32.into(),
|
||||||
],
|
],
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
@ -932,8 +903,7 @@ pub fn call_ndarray_calc_broadcast_index<'ctx, G: CodeGenerator + ?Sized, Broadc
|
||||||
// TODO: Assertions
|
// TODO: Assertions
|
||||||
|
|
||||||
let broadcast_size = broadcast_idx.size(ctx, generator);
|
let broadcast_size = broadcast_idx.size(ctx, generator);
|
||||||
let out_idx = ctx.builder.build_array_alloca(llvm_usize, broadcast_size, "").unwrap();
|
let out_idx = ctx.builder.build_array_alloca(llvm_i32, broadcast_size, "").unwrap();
|
||||||
let out_idx = ArraySliceValue::from_ptr_val(out_idx, broadcast_size, None);
|
|
||||||
|
|
||||||
let array_dims = array.dim_sizes().base_ptr(ctx, generator);
|
let array_dims = array.dim_sizes().base_ptr(ctx, generator);
|
||||||
let array_ndims = array.load_ndims(ctx);
|
let array_ndims = array.load_ndims(ctx);
|
||||||
|
@ -953,11 +923,15 @@ pub fn call_ndarray_calc_broadcast_index<'ctx, G: CodeGenerator + ?Sized, Broadc
|
||||||
array_dims.into(),
|
array_dims.into(),
|
||||||
array_ndims.into(),
|
array_ndims.into(),
|
||||||
broadcast_idx_ptr.into(),
|
broadcast_idx_ptr.into(),
|
||||||
out_idx.base_ptr(ctx, generator).into(),
|
out_idx.into(),
|
||||||
],
|
],
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
out_idx
|
TypedArrayLikeAdapter::from(
|
||||||
|
ArraySliceValue::from_ptr_val(out_idx, broadcast_size, None),
|
||||||
|
Box::new(|_, v| v.into_int_value()),
|
||||||
|
Box::new(|_, v| v.into()),
|
||||||
|
)
|
||||||
}
|
}
|
|
@ -8,17 +8,18 @@ use crate::{
|
||||||
codegen::{
|
codegen::{
|
||||||
classes::{
|
classes::{
|
||||||
ArrayLikeIndexer,
|
ArrayLikeIndexer,
|
||||||
ArraySliceValue,
|
|
||||||
ArrayLikeValue,
|
ArrayLikeValue,
|
||||||
ListValue,
|
ListValue,
|
||||||
NDArrayValue,
|
NDArrayValue,
|
||||||
TypedArrayLikeAccessor,
|
TypedArrayLikeAccessor,
|
||||||
|
TypedArrayLikeAdapter,
|
||||||
UntypedArrayLikeAccessor,
|
UntypedArrayLikeAccessor,
|
||||||
},
|
},
|
||||||
CodeGenContext,
|
CodeGenContext,
|
||||||
CodeGenerator,
|
CodeGenerator,
|
||||||
irrt::{
|
irrt::{
|
||||||
call_ndarray_calc_broadcast,
|
call_ndarray_calc_broadcast,
|
||||||
|
call_ndarray_calc_broadcast_index,
|
||||||
call_ndarray_calc_nd_indices,
|
call_ndarray_calc_nd_indices,
|
||||||
call_ndarray_calc_size,
|
call_ndarray_calc_size,
|
||||||
},
|
},
|
||||||
|
@ -326,7 +327,7 @@ fn ndarray_fill_indexed<'ctx, G, ValueFn>(
|
||||||
) -> Result<(), String>
|
) -> Result<(), String>
|
||||||
where
|
where
|
||||||
G: CodeGenerator + ?Sized,
|
G: CodeGenerator + ?Sized,
|
||||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, ArraySliceValue<'ctx>) -> Result<BasicValueEnum<'ctx>, String>,
|
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, TypedArrayLikeAdapter<'ctx, IntValue<'ctx>>) -> Result<BasicValueEnum<'ctx>, String>,
|
||||||
{
|
{
|
||||||
ndarray_fill_flattened(
|
ndarray_fill_flattened(
|
||||||
generator,
|
generator,
|
||||||
|
@ -347,7 +348,7 @@ fn ndarray_fill_indexed<'ctx, G, ValueFn>(
|
||||||
|
|
||||||
/// Generates the LLVM IR for populating the entire `NDArray` using a lambda with the same-indexed
|
/// Generates the LLVM IR for populating the entire `NDArray` using a lambda with the same-indexed
|
||||||
/// element from two other `NDArray` as its input.
|
/// element from two other `NDArray` as its input.
|
||||||
fn ndarray_broadcast_fill_flattened<'ctx, G, ValueFn>(
|
fn ndarray_broadcast_fill<'ctx, G, ValueFn>(
|
||||||
generator: &mut G,
|
generator: &mut G,
|
||||||
ctx: &mut CodeGenContext<'ctx, '_>,
|
ctx: &mut CodeGenContext<'ctx, '_>,
|
||||||
elem_ty: Type,
|
elem_ty: Type,
|
||||||
|
@ -360,15 +361,18 @@ fn ndarray_broadcast_fill_flattened<'ctx, G, ValueFn>(
|
||||||
G: CodeGenerator + ?Sized,
|
G: CodeGenerator + ?Sized,
|
||||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, Type, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, Type, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
||||||
{
|
{
|
||||||
ndarray_fill_flattened(
|
ndarray_fill_indexed(
|
||||||
generator,
|
generator,
|
||||||
ctx,
|
ctx,
|
||||||
res,
|
res,
|
||||||
|generator, ctx, idx| {
|
|generator, ctx, idx| {
|
||||||
|
let lhs_idx = call_ndarray_calc_broadcast_index(generator, ctx, lhs, &idx);
|
||||||
|
let rhs_idx = call_ndarray_calc_broadcast_index(generator, ctx, rhs, &idx);
|
||||||
|
|
||||||
let elem = unsafe {
|
let elem = unsafe {
|
||||||
(
|
(
|
||||||
lhs.data().get_unchecked(ctx, generator, idx, None),
|
lhs.data().get_unchecked(ctx, generator, lhs_idx, None),
|
||||||
rhs.data().get_unchecked(ctx, generator, idx, None),
|
rhs.data().get_unchecked(ctx, generator, rhs_idx, None),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -508,6 +512,7 @@ fn call_ndarray_eye_impl<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
ncols: IntValue<'ctx>,
|
ncols: IntValue<'ctx>,
|
||||||
offset: IntValue<'ctx>,
|
offset: IntValue<'ctx>,
|
||||||
) -> Result<NDArrayValue<'ctx>, String> {
|
) -> Result<NDArrayValue<'ctx>, String> {
|
||||||
|
let llvm_i32 = ctx.ctx.i32_type();
|
||||||
let llvm_usize = generator.get_size_type(ctx.ctx);
|
let llvm_usize = generator.get_size_type(ctx.ctx);
|
||||||
let llvm_usize_2 = llvm_usize.array_type(2);
|
let llvm_usize_2 = llvm_usize.array_type(2);
|
||||||
|
|
||||||
|
@ -538,15 +543,15 @@ fn call_ndarray_eye_impl<'ctx, G: CodeGenerator + ?Sized>(
|
||||||
|generator, ctx, indices| {
|
|generator, ctx, indices| {
|
||||||
let (row, col) = unsafe {
|
let (row, col) = unsafe {
|
||||||
(
|
(
|
||||||
indices.get_unchecked(ctx, generator, llvm_usize.const_int(0, false), None).into_int_value(),
|
indices.get_typed_unchecked(ctx, generator, llvm_usize.const_zero(), None),
|
||||||
indices.get_unchecked(ctx, generator, llvm_usize.const_int(1, false), None).into_int_value(),
|
indices.get_typed_unchecked(ctx, generator, llvm_usize.const_int(1, false), None),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let col_with_offset = ctx.builder
|
let col_with_offset = ctx.builder
|
||||||
.build_int_add(
|
.build_int_add(
|
||||||
col,
|
col,
|
||||||
ctx.builder.build_int_s_extend_or_bit_cast(offset, llvm_usize, "").unwrap(),
|
ctx.builder.build_int_s_extend_or_bit_cast(offset, llvm_i32, "").unwrap(),
|
||||||
"",
|
"",
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -629,7 +634,7 @@ pub fn ndarray_elementwise_binop_impl<'ctx, G, ValueFn>(
|
||||||
this: NDArrayValue<'ctx>,
|
this: NDArrayValue<'ctx>,
|
||||||
other: NDArrayValue<'ctx>,
|
other: NDArrayValue<'ctx>,
|
||||||
value_fn: ValueFn,
|
value_fn: ValueFn,
|
||||||
) -> Result<NDArrayValue<'ctx>, String>
|
) -> Result<NDArrayValue<'ctx>, String>
|
||||||
where
|
where
|
||||||
G: CodeGenerator,
|
G: CodeGenerator,
|
||||||
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, Type, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
ValueFn: Fn(&mut G, &mut CodeGenContext<'ctx, '_>, Type, (BasicValueEnum<'ctx>, BasicValueEnum<'ctx>)) -> Result<BasicValueEnum<'ctx>, String>,
|
||||||
|
@ -641,23 +646,18 @@ pub fn ndarray_elementwise_binop_impl<'ctx, G, ValueFn>(
|
||||||
ctx,
|
ctx,
|
||||||
elem_ty,
|
elem_ty,
|
||||||
&ndarray_dims,
|
&ndarray_dims,
|
||||||
|_, _, v| {
|
|generator, ctx, v| {
|
||||||
Ok(v.0)
|
Ok(v.size(ctx, generator))
|
||||||
},
|
},
|
||||||
|_, ctx, v, idx| {
|
|generator, ctx, v, idx| {
|
||||||
unsafe {
|
unsafe {
|
||||||
let data_ptr = ctx.builder.build_in_bounds_gep(v.1, &[idx], "")
|
Ok(v.get_typed_unchecked(ctx, generator, idx, None))
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
ctx.builder.build_load(data_ptr, "")
|
|
||||||
.map(BasicValueEnum::into_int_value)
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
).unwrap()
|
).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
ndarray_broadcast_fill_flattened(
|
ndarray_broadcast_fill(
|
||||||
generator,
|
generator,
|
||||||
ctx,
|
ctx,
|
||||||
elem_ty,
|
elem_ty,
|
||||||
|
|
|
@ -696,7 +696,7 @@ impl Unifier {
|
||||||
self.set_a_to_b(a, x);
|
self.set_a_to_b(a, x);
|
||||||
}
|
}
|
||||||
(TVar { fields: Some(fields), range, is_const_generic: false, .. }, TTuple { ty }) => {
|
(TVar { fields: Some(fields), range, is_const_generic: false, .. }, TTuple { ty }) => {
|
||||||
let len = ty.len() as i32;
|
let len = i32::try_from(ty.len()).unwrap();
|
||||||
for (k, v) in fields {
|
for (k, v) in fields {
|
||||||
match *k {
|
match *k {
|
||||||
RecordKey::Int(i) => {
|
RecordKey::Int(i) => {
|
||||||
|
|
|
@ -74,7 +74,8 @@ impl SymbolResolver for Resolver {
|
||||||
if let Some(id) = str_store.get(s) {
|
if let Some(id) = str_store.get(s) {
|
||||||
*id
|
*id
|
||||||
} else {
|
} else {
|
||||||
let id = str_store.len() as i32;
|
let id = i32::try_from(str_store.len())
|
||||||
|
.expect("Symbol resolver string store size exceeds max capacity (i32::MAX)");
|
||||||
str_store.insert(s.to_string(), id);
|
str_store.insert(s.to_string(), id);
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,6 +247,8 @@ fn handle_assignment_pattern(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
const SIZE_T: u32 = usize::BITS;
|
||||||
|
|
||||||
let cli = CommandLineArgs::parse();
|
let cli = CommandLineArgs::parse();
|
||||||
let CommandLineArgs {
|
let CommandLineArgs {
|
||||||
file_name,
|
file_name,
|
||||||
|
@ -287,7 +289,6 @@ fn main() {
|
||||||
// The default behavior for -O<n> where n>3 defaults to O3 for both Clang and GCC
|
// The default behavior for -O<n> where n>3 defaults to O3 for both Clang and GCC
|
||||||
_ => OptimizationLevel::Aggressive,
|
_ => OptimizationLevel::Aggressive,
|
||||||
};
|
};
|
||||||
const SIZE_T: u32 = 64;
|
|
||||||
|
|
||||||
let program = match fs::read_to_string(file_name.clone()) {
|
let program = match fs::read_to_string(file_name.clone()) {
|
||||||
Ok(program) => program,
|
Ok(program) => program,
|
||||||
|
|
Loading…
Reference in New Issue