forked from M-Labs/nac3
core: move Slice and RustSlice to its own file & genericize their IntKind
This commit is contained in:
parent
f698b0c1fa
commit
a6e1d354b6
|
@ -4,5 +4,6 @@ pub mod exception;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod ndarray;
|
pub mod ndarray;
|
||||||
pub mod range;
|
pub mod range;
|
||||||
|
pub mod slice;
|
||||||
pub mod str;
|
pub mod str;
|
||||||
pub mod tuple;
|
pub mod tuple;
|
||||||
|
|
|
@ -1,4 +1,9 @@
|
||||||
use crate::codegen::{irrt::call_nac3_ndarray_index, model::*, CodeGenContext, CodeGenerator};
|
use crate::codegen::{
|
||||||
|
irrt::call_nac3_ndarray_index,
|
||||||
|
model::*,
|
||||||
|
object::slice::{RustSlice, Slice},
|
||||||
|
CodeGenContext, CodeGenerator,
|
||||||
|
};
|
||||||
|
|
||||||
use super::NDArrayObject;
|
use super::NDArrayObject;
|
||||||
|
|
||||||
|
@ -23,86 +28,11 @@ impl<'ctx> StructKind<'ctx> for NDIndex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fields of [`Slice`]
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct SliceFields<'ctx, F: FieldTraversal<'ctx>> {
|
|
||||||
pub start_defined: F::Out<Int<Bool>>,
|
|
||||||
pub start: F::Out<Int<Int32>>,
|
|
||||||
pub stop_defined: F::Out<Int<Bool>>,
|
|
||||||
pub stop: F::Out<Int<Int32>>,
|
|
||||||
pub step_defined: F::Out<Int<Bool>>,
|
|
||||||
pub step: F::Out<Int<Int32>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An IRRT representation of an (unresolved) slice.
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
|
||||||
pub struct Slice;
|
|
||||||
|
|
||||||
impl<'ctx> StructKind<'ctx> for Slice {
|
|
||||||
type Fields<F: FieldTraversal<'ctx>> = SliceFields<'ctx, F>;
|
|
||||||
|
|
||||||
fn traverse_fields<F: FieldTraversal<'ctx>>(&self, traversal: &mut F) -> Self::Fields<F> {
|
|
||||||
Self::Fields {
|
|
||||||
start_defined: traversal.add_auto("start_defined"),
|
|
||||||
start: traversal.add_auto("start"),
|
|
||||||
stop_defined: traversal.add_auto("stop_defined"),
|
|
||||||
stop: traversal.add_auto("stop"),
|
|
||||||
step_defined: traversal.add_auto("step_defined"),
|
|
||||||
step: traversal.add_auto("step"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A convenience structure to prepare a [`Slice`].
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct RustSlice<'ctx> {
|
|
||||||
pub start: Option<Instance<'ctx, Int<Int32>>>,
|
|
||||||
pub stop: Option<Instance<'ctx, Int<Int32>>>,
|
|
||||||
pub step: Option<Instance<'ctx, Int<Int32>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'ctx> RustSlice<'ctx> {
|
|
||||||
/// Write the contents to an LLVM [`Slice`].
|
|
||||||
pub fn write_to_slice<G: CodeGenerator + ?Sized>(
|
|
||||||
&self,
|
|
||||||
generator: &mut G,
|
|
||||||
ctx: &CodeGenContext<'ctx, '_>,
|
|
||||||
dst_slice_ptr: Instance<'ctx, Ptr<Struct<Slice>>>,
|
|
||||||
) {
|
|
||||||
let false_ = Int(Bool).const_false(generator, ctx.ctx);
|
|
||||||
let true_ = Int(Bool).const_true(generator, ctx.ctx);
|
|
||||||
|
|
||||||
match self.start {
|
|
||||||
Some(start) => {
|
|
||||||
dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, true_);
|
|
||||||
dst_slice_ptr.gep(ctx, |f| f.start).store(ctx, start);
|
|
||||||
}
|
|
||||||
None => dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, false_),
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.stop {
|
|
||||||
Some(stop) => {
|
|
||||||
dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, true_);
|
|
||||||
dst_slice_ptr.gep(ctx, |f| f.stop).store(ctx, stop);
|
|
||||||
}
|
|
||||||
None => dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, false_),
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.step {
|
|
||||||
Some(step) => {
|
|
||||||
dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, true_);
|
|
||||||
dst_slice_ptr.gep(ctx, |f| f.step).store(ctx, step);
|
|
||||||
}
|
|
||||||
None => dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, false_),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A convenience enum to prepare an [`NDIndex`].
|
// A convenience enum to prepare an [`NDIndex`].
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum RustNDIndex<'ctx> {
|
pub enum RustNDIndex<'ctx> {
|
||||||
SingleElement(Instance<'ctx, Int<Int32>>), // TODO: To be SizeT
|
SingleElement(Instance<'ctx, Int<Int32>>), // TODO: To be SizeT
|
||||||
Slice(RustSlice<'ctx>),
|
Slice(RustSlice<'ctx, Int32>), // TODO: To be SizeT
|
||||||
NewAxis,
|
NewAxis,
|
||||||
Ellipsis,
|
Ellipsis,
|
||||||
}
|
}
|
||||||
|
@ -143,7 +73,7 @@ impl<'ctx> RustNDIndex<'ctx> {
|
||||||
.store(ctx, index_ptr.pointer_cast(generator, ctx, Int(Byte)));
|
.store(ctx, index_ptr.pointer_cast(generator, ctx, Int(Byte)));
|
||||||
}
|
}
|
||||||
RustNDIndex::Slice(in_rust_slice) => {
|
RustNDIndex::Slice(in_rust_slice) => {
|
||||||
let user_slice_ptr = Struct(Slice).alloca(generator, ctx);
|
let user_slice_ptr = Struct(Slice(Int32)).alloca(generator, ctx);
|
||||||
in_rust_slice.write_to_slice(generator, ctx, user_slice_ptr);
|
in_rust_slice.write_to_slice(generator, ctx, user_slice_ptr);
|
||||||
|
|
||||||
dst_ndindex_ptr
|
dst_ndindex_ptr
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
use crate::codegen::{model::*, CodeGenContext, CodeGenerator};
|
||||||
|
|
||||||
|
/// Fields of [`Slice`]
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct SliceFields<'ctx, F: FieldTraversal<'ctx>, N: IntKind<'ctx>> {
|
||||||
|
pub start_defined: F::Out<Int<Bool>>,
|
||||||
|
pub start: F::Out<Int<N>>,
|
||||||
|
pub stop_defined: F::Out<Int<Bool>>,
|
||||||
|
pub stop: F::Out<Int<N>>,
|
||||||
|
pub step_defined: F::Out<Int<Bool>>,
|
||||||
|
pub step: F::Out<Int<N>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An IRRT representation of an (unresolved) slice.
|
||||||
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
|
||||||
|
pub struct Slice<N>(pub N);
|
||||||
|
|
||||||
|
impl<'ctx, N: IntKind<'ctx>> StructKind<'ctx> for Slice<N> {
|
||||||
|
type Fields<F: FieldTraversal<'ctx>> = SliceFields<'ctx, F, N>;
|
||||||
|
|
||||||
|
fn traverse_fields<F: FieldTraversal<'ctx>>(&self, traversal: &mut F) -> Self::Fields<F> {
|
||||||
|
Self::Fields {
|
||||||
|
start_defined: traversal.add_auto("start_defined"),
|
||||||
|
start: traversal.add("start", Int(self.0)),
|
||||||
|
stop_defined: traversal.add_auto("stop_defined"),
|
||||||
|
stop: traversal.add("stop", Int(self.0)),
|
||||||
|
step_defined: traversal.add_auto("step_defined"),
|
||||||
|
step: traversal.add("step", Int(self.0)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Rust structure that has [`Slice`] utilities and looks like a [`Slice`] but
|
||||||
|
/// `start`, `stop` and `step` are held by LLVM registers only and possibly
|
||||||
|
/// [`Option::None`] if unspecified.
|
||||||
|
///
|
||||||
|
/// This structure exists because many implementations use [`Slice`] utilities but
|
||||||
|
/// it might not be good to alloca an actual [`Slice`] value on the stack in order
|
||||||
|
/// to perform calculations.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RustSlice<'ctx, N: IntKind<'ctx>> {
|
||||||
|
pub start: Option<Instance<'ctx, Int<N>>>,
|
||||||
|
pub stop: Option<Instance<'ctx, Int<N>>>,
|
||||||
|
pub step: Option<Instance<'ctx, Int<N>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'ctx, N: IntKind<'ctx>> RustSlice<'ctx, N> {
|
||||||
|
/// Write the contents to an LLVM [`Slice`].
|
||||||
|
pub fn write_to_slice<G: CodeGenerator + ?Sized>(
|
||||||
|
&self,
|
||||||
|
generator: &mut G,
|
||||||
|
ctx: &CodeGenContext<'ctx, '_>,
|
||||||
|
dst_slice_ptr: Instance<'ctx, Ptr<Struct<Slice<N>>>>,
|
||||||
|
) {
|
||||||
|
let false_ = Int(Bool).const_false(generator, ctx.ctx);
|
||||||
|
let true_ = Int(Bool).const_true(generator, ctx.ctx);
|
||||||
|
|
||||||
|
match self.start {
|
||||||
|
Some(start) => {
|
||||||
|
dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, true_);
|
||||||
|
dst_slice_ptr.gep(ctx, |f| f.start).store(ctx, start);
|
||||||
|
}
|
||||||
|
None => dst_slice_ptr.gep(ctx, |f| f.start_defined).store(ctx, false_),
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.stop {
|
||||||
|
Some(stop) => {
|
||||||
|
dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, true_);
|
||||||
|
dst_slice_ptr.gep(ctx, |f| f.stop).store(ctx, stop);
|
||||||
|
}
|
||||||
|
None => dst_slice_ptr.gep(ctx, |f| f.stop_defined).store(ctx, false_),
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.step {
|
||||||
|
Some(step) => {
|
||||||
|
dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, true_);
|
||||||
|
dst_slice_ptr.gep(ctx, |f| f.step).store(ctx, step);
|
||||||
|
}
|
||||||
|
None => dst_slice_ptr.gep(ctx, |f| f.step_defined).store(ctx, false_),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue