Skip to content

Commit

Permalink
Initialize string cache in context (#349)
Browse files Browse the repository at this point in the history
This PR removes the global static string cache that stores `CString` in
MLIR (C++) for each corresponding `&str` in Rust. Instead, we have a
cache in each context. And, that forces users to pass around the new
`Context` type accordingly.

Close #54.

This change is also the base of #271, #23, and #348.
  • Loading branch information
raviqqe authored Oct 17, 2023
1 parent 2b4f350 commit c15cecf
Show file tree
Hide file tree
Showing 36 changed files with 560 additions and 338 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@ module.body().append_operation(func::func(
let block = Block::new(&[(index_type, location), (index_type, location)]);

let sum = block.append_operation(arith::addi(
&context,
block.argument(0).unwrap().into(),
block.argument(1).unwrap().into(),
location
));

block.append_operation(func::r#return(&[sum.result(0).unwrap().into()], location));
block.append_operation(func::r#return(&context, &[sum.result(0).unwrap().into()], location));

let region = Region::new();
region.append_block(block);
Expand Down
20 changes: 10 additions & 10 deletions macro/src/dialect/operation/accessors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl<'a> OperationField<'a> {
let attribute =
::melior::ir::attribute::DenseI32ArrayAttribute::<'c>::try_from(
self.operation
.attribute(#attribute_name)?
.attribute(context, #attribute_name)?
)?;
let start = (0..#index)
.map(|index| attribute.element(index))
Expand Down Expand Up @@ -154,11 +154,11 @@ impl<'a> OperationField<'a> {
let name = &self.name;

Some(if constraint.is_unit()? {
quote! { self.operation.attribute(#name).is_some() }
quote! { self.operation.attribute(context, #name).is_some() }
} else {
quote! {
self.operation
.attribute(#name)?
.attribute(context, #name)?
.try_into()
.map_err(::melior::Error::from)
}
Expand All @@ -174,7 +174,7 @@ impl<'a> OperationField<'a> {

if constraint.is_unit()? || constraint.is_optional()? {
Some(quote! {
self.operation.remove_attribute(#name)
self.operation.remove_attribute(context, #name)
})
} else {
None
Expand All @@ -193,14 +193,14 @@ impl<'a> OperationField<'a> {
Ok(Some(if constraint.is_unit()? {
quote! {
if value {
self.operation.set_attribute(#name, Attribute::unit(&self.operation.context()));
self.operation.set_attribute(context, #name, Attribute::unit(&self.operation.context()));
} else {
self.operation.remove_attribute(#name)
self.operation.remove_attribute(context, #name)
}
}
} else {
quote! {
self.operation.set_attribute(#name, &value.into());
self.operation.set_attribute(context, #name, &value.into());
}
}))
}
Expand All @@ -213,7 +213,7 @@ impl<'a> OperationField<'a> {
let parameter_type = &self.kind.parameter_type()?;

quote! {
pub fn #ident(&mut self, value: #parameter_type) {
pub fn #ident(&mut self, context: &'c ::melior::Context, value: #parameter_type) {
#body
}
}
Expand All @@ -225,7 +225,7 @@ impl<'a> OperationField<'a> {
let ident = sanitize_snake_case_name(&format!("remove_{}", self.name))?;
self.remover_impl()?.map(|body| {
quote! {
pub fn #ident(&mut self) -> Result<(), ::melior::Error> {
pub fn #ident(&mut self, context: &'c ::melior::Context) -> Result<(), ::melior::Error> {
#body
}
}
Expand All @@ -236,7 +236,7 @@ impl<'a> OperationField<'a> {
let return_type = &self.kind.return_type()?;
self.getter_impl()?.map(|body| {
quote! {
pub fn #ident(&self) -> #return_type {
pub fn #ident(&self, context: &'c ::melior::Context) -> #return_type {
#body
}
}
Expand Down
17 changes: 9 additions & 8 deletions macro/src/dialect/operation/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'o> OperationBuilder<'o> {

quote! {
&[(
::melior::ir::Identifier::new(unsafe { self.context.to_ref() }, #name_string),
::melior::ir::Identifier::new(self.context, #name_string),
#name.into(),
)]
}
Expand Down Expand Up @@ -142,7 +142,7 @@ impl<'o> OperationBuilder<'o> {
#[doc = #doc]
pub struct #builder_ident <'c, #(#iter_arguments),* > {
builder: ::melior::ir::operation::OperationBuilder<'c>,
context: ::melior::ContextRef<'c>,
context: &'c ::melior::Context,
#(#phantom_fields),*
}

Expand Down Expand Up @@ -180,10 +180,10 @@ impl<'o> OperationBuilder<'o> {

quote! {
impl<'c> #builder_ident<'c, #(#arguments),*> {
pub fn new(location: ::melior::ir::Location<'c>) -> Self {
pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self {
Self {
context: location.context(),
builder: ::melior::ir::operation::OperationBuilder::new(#name, location),
context,
builder: ::melior::ir::operation::OperationBuilder::new(&context, #name, location),
#(#phantoms),*
}
}
Expand All @@ -196,9 +196,10 @@ impl<'o> OperationBuilder<'o> {
let arguments = self.type_state.arguments_all_set(false);
quote! {
pub fn builder(
context: &'c ::melior::Context,
location: ::melior::ir::Location<'c>
) -> #builder_ident<'c, #(#arguments),*> {
#builder_ident::new(location)
#builder_ident::new(context, location)
}
}
}
Expand Down Expand Up @@ -229,8 +230,8 @@ impl<'o> OperationBuilder<'o> {
Ok(quote! {
#[allow(clippy::too_many_arguments)]
#[doc = #doc]
pub fn #name<'c>(#(#arguments),*) -> #class_name<'c> {
#class_name::builder(location)#(#builder_calls)*.build()
pub fn #name<'c>(context: &'c ::melior::Context, #(#arguments),*) -> #class_name<'c> {
#class_name::builder(context, location)#(#builder_calls)*.build()
}
})
}
Expand Down
18 changes: 12 additions & 6 deletions macro/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,25 @@ pub fn generate_binary(dialect: &Ident, names: &[Ident]) -> Result<TokenStream,
stream.extend(TokenStream::from(quote! {
#[doc = #document]
pub fn #name<'c>(
context: &'c Context,
lhs: crate::ir::Value<'c, '_>,
rhs: crate::ir::Value<'c, '_>,
location: crate::ir::Location<'c>,
) -> crate::ir::Operation<'c> {
binary_operator(#operation_name, lhs, rhs, location)
binary_operator(context, #operation_name, lhs, rhs, location)
}
}));
}

stream.extend(TokenStream::from(quote! {
fn binary_operator<'c>(
context: &'c Context,
name: &str,
lhs: crate::ir::Value<'c, '_>,
rhs: crate::ir::Value<'c, '_>,
location: crate::ir::Location<'c>,
) -> crate::ir::Operation<'c> {
crate::ir::operation::OperationBuilder::new(name, location)
crate::ir::operation::OperationBuilder::new(&context, name, location)
.add_operands(&[lhs, rhs])
.enable_result_type_inference()
.build()
Expand All @@ -49,21 +51,23 @@ pub fn generate_unary(dialect: &Ident, names: &[Ident]) -> Result<TokenStream, B
stream.extend(TokenStream::from(quote! {
#[doc = #document]
pub fn #name<'c>(
context: &'c Context,
value: crate::ir::Value<'c, '_>,
location: crate::ir::Location<'c>,
) -> crate::ir::Operation<'c> {
unary_operator(#operation_name, value, location)
unary_operator(context, #operation_name, value, location)
}
}));
}

stream.extend(TokenStream::from(quote! {
fn unary_operator<'c>(
context: &'c Context,
name: &str,
value: crate::ir::Value<'c, '_>,
location: crate::ir::Location<'c>,
) -> crate::ir::Operation<'c> {
crate::ir::operation::OperationBuilder::new(name, location)
crate::ir::operation::OperationBuilder::new(&context, name, location)
.add_operands(&[value])
.enable_result_type_inference()
.build()
Expand All @@ -86,23 +90,25 @@ pub fn generate_typed_unary(
stream.extend(TokenStream::from(quote! {
#[doc = #document]
pub fn #name<'c>(
context: &'c Context,
value: crate::ir::Value<'c, '_>,
r#type: crate::ir::Type<'c>,
location: crate::ir::Location<'c>,
) -> crate::ir::Operation<'c> {
typed_unary_operator(#operation_name, value, r#type, location)
typed_unary_operator(context, #operation_name, value, r#type, location)
}
}));
}

stream.extend(TokenStream::from(quote! {
fn typed_unary_operator<'c>(
context: &'c Context,
name: &str,
value: crate::ir::Value<'c, '_>,
r#type: crate::ir::Type<'c>,
location: crate::ir::Location<'c>,
) -> crate::ir::Operation<'c> {
crate::ir::operation::OperationBuilder::new(name, location)
crate::ir::operation::OperationBuilder::new(&context, name, location)
.add_operands(&[value])
.add_results(&[r#type])
.build()
Expand Down
1 change: 0 additions & 1 deletion macro/src/type.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::utility::map_name;
use convert_case::{Case, Casing};

use proc_macro::TokenStream;
use proc_macro2::Ident;
use quote::quote;
Expand Down
23 changes: 17 additions & 6 deletions macro/tests/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ fn simple() {
let r#type = Type::parse(&context, "i32").unwrap();
let block = Block::new(&[(r#type, location), (r#type, location)]);
let op = operand_test::simple(
&context,
r#type,
block.argument(0).unwrap().into(),
block.argument(1).unwrap().into(),
location,
);

assert_eq!(op.lhs().unwrap(), block.argument(0).unwrap().into());
assert_eq!(op.rhs().unwrap(), block.argument(1).unwrap().into());
assert_eq!(op.lhs(&context).unwrap(), block.argument(0).unwrap().into());
assert_eq!(op.rhs(&context).unwrap(), block.argument(1).unwrap().into());
assert_eq!(op.operation().operand_count(), 2);
}

Expand All @@ -39,6 +40,7 @@ fn variadic_after_single() {
let r#type = Type::parse(&context, "i32").unwrap();
let block = Block::new(&[(r#type, location), (r#type, location), (r#type, location)]);
let op = operand_test::variadic(
&context,
r#type,
block.argument(0).unwrap().into(),
&[
Expand All @@ -48,9 +50,18 @@ fn variadic_after_single() {
location,
);

assert_eq!(op.first().unwrap(), block.argument(0).unwrap().into());
assert_eq!(op.others().next(), Some(block.argument(2).unwrap().into()));
assert_eq!(op.others().nth(1), Some(block.argument(1).unwrap().into()));
assert_eq!(
op.first(&context).unwrap(),
block.argument(0).unwrap().into()
);
assert_eq!(
op.others(&context).next(),
Some(block.argument(2).unwrap().into())
);
assert_eq!(
op.others(&context).nth(1),
Some(block.argument(1).unwrap().into())
);
assert_eq!(op.operation().operand_count(), 3);
assert_eq!(op.others().count(), 2);
assert_eq!(op.others(&context).count(), 2);
}
26 changes: 18 additions & 8 deletions macro/tests/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ fn single() {
let block = Block::new(&[]);
let r1 = Region::new();
r1.append_block(block);
region_test::single(r1, location)
region_test::single(&context, r1, location)
};

assert!(op.default_region().unwrap().first_block().is_some());
assert!(op.default_region(&context).unwrap().first_block().is_some());
}

#[test]
Expand All @@ -36,23 +36,33 @@ fn variadic_after_single() {
let block = Block::new(&[]);
let (r1, r2, r3) = (Region::new(), Region::new(), Region::new());
r2.append_block(block);
region_test::variadic(r1, vec![r2, r3], location)
region_test::variadic(&context, r1, vec![r2, r3], location)
};

let op2 = {
let block = Block::new(&[]);
let (r1, r2, r3) = (Region::new(), Region::new(), Region::new());
r2.append_block(block);
region_test::VariadicOp::builder(location)
region_test::VariadicOp::builder(&context, location)
.default_region(r1)
.other_regions(vec![r2, r3])
.build()
};

assert_eq!(op.operation().to_string(), op2.operation().to_string());

assert!(op.default_region().unwrap().first_block().is_none());
assert_eq!(op.other_regions().count(), 2);
assert!(op.other_regions().next().unwrap().first_block().is_some());
assert!(op.other_regions().nth(1).unwrap().first_block().is_none());
assert!(op.default_region(&context).unwrap().first_block().is_none());
assert_eq!(op.other_regions(&context).count(), 2);
assert!(op
.other_regions(&context)
.next()
.unwrap()
.first_block()
.is_some());
assert!(op
.other_regions(&context)
.nth(1)
.unwrap()
.first_block()
.is_none());
}
9 changes: 6 additions & 3 deletions melior/benches/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use criterion::{criterion_group, criterion_main, Bencher, Criterion};
use melior::StringRef;
use melior::{Context, StringRef};

const ITERATION_COUNT: usize = 1000000;

Expand All @@ -10,19 +10,22 @@ fn generate_strings() -> Vec<String> {
}

fn string_ref_create(bencher: &mut Bencher) {
let context = Context::new();
let strings = generate_strings();

bencher.iter(|| {
for string in &strings {
let _ = StringRef::from(string.as_str());
let _ = StringRef::from_str(&context, string.as_str());
}
});
}

fn string_ref_create_cached(bencher: &mut Bencher) {
let context = Context::new();

bencher.iter(|| {
for _ in 0..ITERATION_COUNT {
let _ = StringRef::from("foo");
let _ = StringRef::from_str(&context, "foo");
}
});
}
Expand Down
Loading

0 comments on commit c15cecf

Please sign in to comment.