diff --git a/melior/src/ir/block.rs b/melior/src/ir/block.rs index d0d61c532a..4944454b0e 100644 --- a/melior/src/ir/block.rs +++ b/melior/src/ir/block.rs @@ -5,17 +5,10 @@ mod block_like; pub use self::argument::BlockArgument; pub use self::block_like::BlockLike; -use super::{ - operation::OperationRefMut, Location, Operation, OperationRef, RegionRef, Type, TypeLike, Value, -}; -use crate::{context::Context, utility::print_callback, Error}; +use super::{Location, Type, TypeLike, Value}; +use crate::{context::Context, utility::print_callback}; use mlir_sys::{ - mlirBlockAddArgument, mlirBlockAppendOwnedOperation, mlirBlockCreate, mlirBlockDestroy, - mlirBlockDetach, mlirBlockEqual, mlirBlockGetArgument, mlirBlockGetFirstOperation, - mlirBlockGetNextInRegion, mlirBlockGetNumArguments, mlirBlockGetParentOperation, - mlirBlockGetParentRegion, mlirBlockGetTerminator, mlirBlockInsertOwnedOperation, - mlirBlockInsertOwnedOperationAfter, mlirBlockInsertOwnedOperationBefore, mlirBlockPrint, - MlirBlock, + mlirBlockCreate, mlirBlockDestroy, mlirBlockDetach, mlirBlockEqual, mlirBlockPrint, MlirBlock, }; use std::{ ffi::c_void, @@ -96,112 +89,9 @@ impl<'c> Block<'c> { } } -impl<'c, 'a> BlockLike<'c, 'a> for Block<'c> { - fn argument(&self, index: usize) -> Result, Error> { - unsafe { - if index < self.argument_count() { - Ok(BlockArgument::from_raw(mlirBlockGetArgument( - self.raw, - index as isize, - ))) - } else { - Err(Error::PositionOutOfBounds { - name: "block argument", - value: self.to_string(), - index, - }) - } - } - } - - fn argument_count(&self) -> usize { - unsafe { mlirBlockGetNumArguments(self.raw) as usize } - } - - fn first_operation(&self) -> Option> { - unsafe { OperationRef::from_option_raw(mlirBlockGetFirstOperation(self.raw)) } - } - - fn first_operation_mut(&mut self) -> Option> { - unsafe { OperationRefMut::from_option_raw(mlirBlockGetFirstOperation(self.raw)) } - } - - fn terminator(&self) -> Option> { - unsafe { OperationRef::from_option_raw(mlirBlockGetTerminator(self.raw)) } - } - - fn terminator_mut(&mut self) -> Option> { - unsafe { OperationRefMut::from_option_raw(mlirBlockGetTerminator(self.raw)) } - } - - fn parent_region(&self) -> Option> { - unsafe { RegionRef::from_option_raw(mlirBlockGetParentRegion(self.raw)) } - } - - fn parent_operation(&self) -> Option> { - unsafe { OperationRef::from_option_raw(mlirBlockGetParentOperation(self.raw)) } - } - - fn add_argument(&self, r#type: Type<'c>, location: Location<'c>) -> Value<'c, 'a> { - unsafe { - Value::from_raw(mlirBlockAddArgument( - self.raw, - r#type.to_raw(), - location.to_raw(), - )) - } - } - - fn append_operation(&self, operation: Operation<'c>) -> OperationRef<'c, 'a> { - unsafe { - let operation = operation.into_raw(); - - mlirBlockAppendOwnedOperation(self.raw, operation); - - OperationRef::from_raw(operation) - } - } - - fn insert_operation(&self, position: usize, operation: Operation<'c>) -> OperationRef<'c, 'a> { - unsafe { - let operation = operation.into_raw(); - - mlirBlockInsertOwnedOperation(self.raw, position as isize, operation); - - OperationRef::from_raw(operation) - } - } - - fn insert_operation_after( - &self, - one: OperationRef<'c, 'a>, - other: Operation<'c>, - ) -> OperationRef<'c, 'a> { - unsafe { - let other = other.into_raw(); - - mlirBlockInsertOwnedOperationAfter(self.raw, one.to_raw(), other); - - OperationRef::from_raw(other) - } - } - - fn insert_operation_before( - &self, - one: OperationRef<'c, 'a>, - other: Operation<'c>, - ) -> OperationRef<'c, 'a> { - unsafe { - let other = other.into_raw(); - - mlirBlockInsertOwnedOperationBefore(self.raw, one.to_raw(), other); - - OperationRef::from_raw(other) - } - } - - fn next_in_region(&self) -> Option> { - unsafe { BlockRef::from_option_raw(mlirBlockGetNextInRegion(self.raw)) } +impl<'c, 'a> BlockLike<'c, 'a> for &'a Block<'c> { + fn to_raw(self) -> MlirBlock { + self.raw } } @@ -278,110 +168,8 @@ impl BlockRef<'_, '_> { } impl<'c, 'a> BlockLike<'c, 'a> for BlockRef<'c, 'a> { - fn argument(&self, index: usize) -> Result, Error> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.argument(index); - Block::into_raw(block); - result - } - - fn argument_count(&self) -> usize { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.argument_count(); - Block::into_raw(block); - result - } - - fn first_operation(&self) -> Option> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.first_operation(); - Block::into_raw(block); - result - } - - fn first_operation_mut(&mut self) -> Option> { - let mut block = unsafe { Block::from_raw(self.raw) }; - let result = block.first_operation_mut(); - Block::into_raw(block); - result - } - - fn terminator(&self) -> Option> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.terminator(); - Block::into_raw(block); - result - } - - fn terminator_mut(&mut self) -> Option> { - let mut block = unsafe { Block::from_raw(self.raw) }; - let result = block.terminator_mut(); - Block::into_raw(block); - result - } - - fn parent_region(&self) -> Option> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.parent_region(); - Block::into_raw(block); - result - } - - fn parent_operation(&self) -> Option> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.parent_operation(); - Block::into_raw(block); - result - } - - fn add_argument(&self, r#type: Type<'c>, location: Location<'c>) -> Value<'c, 'a> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.add_argument(r#type, location); - Block::into_raw(block); - result - } - - fn append_operation(&self, operation: Operation<'c>) -> OperationRef<'c, 'a> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.append_operation(operation); - Block::into_raw(block); - result - } - - fn insert_operation(&self, position: usize, operation: Operation<'c>) -> OperationRef<'c, 'a> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.insert_operation(position, operation); - Block::into_raw(block); - result - } - - fn insert_operation_after( - &self, - one: OperationRef<'c, 'a>, - other: Operation<'c>, - ) -> OperationRef<'c, 'a> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.insert_operation_after(one, other); - Block::into_raw(block); - result - } - - fn insert_operation_before( - &self, - one: OperationRef<'c, 'a>, - other: Operation<'c>, - ) -> OperationRef<'c, 'a> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.insert_operation_before(one, other); - Block::into_raw(block); - result - } - - fn next_in_region(&self) -> Option> { - let block = unsafe { Block::from_raw(self.raw) }; - let result = block.next_in_region(); - Block::into_raw(block); - result + fn to_raw(self) -> MlirBlock { + self.raw } } diff --git a/melior/src/ir/block/block_like.rs b/melior/src/ir/block/block_like.rs index 46db987315..8495bfc905 100644 --- a/melior/src/ir/block/block_like.rs +++ b/melior/src/ir/block/block_like.rs @@ -1,60 +1,142 @@ -use super::{BlockArgument, BlockRef}; +use super::{BlockArgument, BlockRef, TypeLike}; use crate::{ ir::{operation::OperationRefMut, Location, Operation, OperationRef, RegionRef, Type, Value}, Error, }; +use core::fmt::Display; +use mlir_sys::{ + mlirBlockAddArgument, mlirBlockAppendOwnedOperation, mlirBlockGetArgument, + mlirBlockGetFirstOperation, mlirBlockGetNextInRegion, mlirBlockGetNumArguments, + mlirBlockGetParentOperation, mlirBlockGetParentRegion, mlirBlockGetTerminator, + mlirBlockInsertOwnedOperation, mlirBlockInsertOwnedOperationAfter, + mlirBlockInsertOwnedOperationBefore, MlirBlock, +}; + +pub trait BlockLike<'c, 'a>: Copy + Display { + /// Converts a block into a raw object. + fn to_raw(self) -> MlirBlock; -pub trait BlockLike<'c, 'a> { /// Returns an argument at a position. - fn argument(&self, index: usize) -> Result, Error>; + fn argument(self, index: usize) -> Result, Error> { + unsafe { + if index < self.argument_count() { + Ok(BlockArgument::from_raw(mlirBlockGetArgument( + self.to_raw(), + index as isize, + ))) + } else { + Err(Error::PositionOutOfBounds { + name: "block argument", + value: self.to_string(), + index, + }) + } + } + } /// Returns a number of arguments. - fn argument_count(&self) -> usize; + fn argument_count(self) -> usize { + unsafe { mlirBlockGetNumArguments(self.to_raw()) as usize } + } /// Returns a reference to the first operation. - fn first_operation(&self) -> Option>; + fn first_operation(self) -> Option> { + unsafe { OperationRef::from_option_raw(mlirBlockGetFirstOperation(self.to_raw())) } + } + /// Returns a mutable reference to the first operation. - fn first_operation_mut(&mut self) -> Option>; + fn first_operation_mut(self) -> Option> { + unsafe { OperationRefMut::from_option_raw(mlirBlockGetFirstOperation(self.to_raw())) } + } /// Returns a reference to a terminator operation. - fn terminator(&self) -> Option>; + fn terminator(self) -> Option> { + unsafe { OperationRef::from_option_raw(mlirBlockGetTerminator(self.to_raw())) } + } /// Returns a mutable reference to a terminator operation. - fn terminator_mut(&mut self) -> Option>; + fn terminator_mut(self) -> Option> { + unsafe { OperationRefMut::from_option_raw(mlirBlockGetTerminator(self.to_raw())) } + } /// Returns a parent region. - // TODO Store lifetime of regions in blocks, or create another type like - // `InsertedBlockRef`? - fn parent_region(&self) -> Option>; + // TODO Store lifetime of regions in blocks, or create another type like `InsertedBlockRef`? + fn parent_region(self) -> Option> { + unsafe { RegionRef::from_option_raw(mlirBlockGetParentRegion(self.to_raw())) } + } /// Returns a parent operation. - fn parent_operation(&self) -> Option>; + fn parent_operation(self) -> Option> { + unsafe { OperationRef::from_option_raw(mlirBlockGetParentOperation(self.to_raw())) } + } /// Adds an argument. - fn add_argument(&self, r#type: Type<'c>, location: Location<'c>) -> Value<'c, 'a>; + fn add_argument(self, r#type: Type<'c>, location: Location<'c>) -> Value<'c, 'a> { + unsafe { + Value::from_raw(mlirBlockAddArgument( + self.to_raw(), + r#type.to_raw(), + location.to_raw(), + )) + } + } /// Appends an operation. - fn append_operation(&self, operation: Operation<'c>) -> OperationRef<'c, 'a>; + fn append_operation(self, operation: Operation<'c>) -> OperationRef<'c, 'a> { + unsafe { + let operation = operation.into_raw(); + + mlirBlockAppendOwnedOperation(self.to_raw(), operation); + + OperationRef::from_raw(operation) + } + } /// Inserts an operation. // TODO How can we make those update functions take `&mut self`? // TODO Use cells? - fn insert_operation(&self, position: usize, operation: Operation<'c>) -> OperationRef<'c, 'a>; + fn insert_operation(self, position: usize, operation: Operation<'c>) -> OperationRef<'c, 'a> { + unsafe { + let operation = operation.into_raw(); + + mlirBlockInsertOwnedOperation(self.to_raw(), position as isize, operation); + + OperationRef::from_raw(operation) + } + } /// Inserts an operation after another. fn insert_operation_after( - &self, + self, one: OperationRef<'c, 'a>, other: Operation<'c>, - ) -> OperationRef<'c, 'a>; + ) -> OperationRef<'c, 'a> { + unsafe { + let other = other.into_raw(); + + mlirBlockInsertOwnedOperationAfter(self.to_raw(), one.to_raw(), other); + + OperationRef::from_raw(other) + } + } /// Inserts an operation before another. fn insert_operation_before( - &self, + self, one: OperationRef<'c, 'a>, other: Operation<'c>, - ) -> OperationRef<'c, 'a>; + ) -> OperationRef<'c, 'a> { + unsafe { + let other = other.into_raw(); + + mlirBlockInsertOwnedOperationBefore(self.to_raw(), one.to_raw(), other); + + OperationRef::from_raw(other) + } + } /// Returns a next block in a region. - fn next_in_region(&self) -> Option>; + fn next_in_region(self) -> Option> { + unsafe { BlockRef::from_option_raw(mlirBlockGetNextInRegion(self.to_raw())) } + } }