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