From d7523e7666012629e1c0bc4921f4027a9675282e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 12:41:17 -0300 Subject: [PATCH 01/14] Add ArrayInit variant on finding expression type --- crates/concrete_ir/src/lowering.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index c0bf5c7..a12faa7 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -739,7 +739,31 @@ fn find_expression_type(builder: &mut FnBodyBuilder, info: &Expression) -> Optio }) } Expression::Cast(_, _, _) => todo!(), - Expression::ArrayInit(_) => todo!(), + Expression::ArrayInit(info) => { + let Some(first_element) = info.values.get(0) else { + return None; + }; + + let Some(first_type) = find_expression_type(builder, first_element) else { + return None; + }; + + let length = info.values.len() as u64; + + Some(Ty { + span: Some(info.span), + kind: TyKind::Array( + Box::new(first_type), + Box::new(ConstData { + ty: Ty { + span: None, + kind: TyKind::Uint(UintTy::U64), + }, + data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64(length))), + }), + ), + }) + } } } From 502ca74daa0007ae2da3f74bf5ed23a321c3701f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 14:49:35 -0300 Subject: [PATCH 02/14] Add lowering for ArrayInit --- crates/concrete_ir/src/lowering.rs | 67 +++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index a12faa7..1fbeba9 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -938,7 +938,72 @@ fn lower_expression( (rvalue, new_ty, *span) } - Expression::ArrayInit(_) => todo!(), + Expression::ArrayInit(info) => { + let element_type_hint = match type_hint.clone() { + Some(type_hint) => match type_hint.kind { + TyKind::Array(type_hint, _) => Some(*type_hint), + _ => None, + }, + None => None, + }; + + let mut values = info.values.iter().enumerate(); + + let (first_idx, first_element) = values.next().expect("array init cannot be empty"); + let (first_value, element_type, _element_span) = + lower_expression(builder, first_element, element_type_hint)?; + + let length = info.values.len() as u64; + + let ty = Ty { + span: Some(info.span), + kind: TyKind::Array( + Box::new(element_type.clone()), + Box::new(ConstData { + ty: Ty { + span: None, + kind: TyKind::Uint(UintTy::U64), + }, + data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64(length))), + }), + ), + }; + + let array_local = builder.add_local(Local::temp(ty.clone())); + + let place = Place { + local: array_local, + projection: Default::default(), + }; + + builder.statements.push(Statement { + span: None, + kind: StatementKind::StorageLive(array_local), + }); + + let mut first_place = place.clone(); + first_place.projection.push(PlaceElem::Index(first_idx)); + + builder.statements.push(Statement { + span: Some(info.span), + kind: StatementKind::Assign(first_place, first_value), + }); + + for (idx, element) in info.values.iter().enumerate() { + let mut element_place = place.clone(); + element_place.projection.push(PlaceElem::Index(idx)); + + let (value, _value_ty, _field_span) = + lower_expression(builder, &element, Some(element_type.clone()))?; + + builder.statements.push(Statement { + span: Some(info.span), + kind: StatementKind::Assign(element_place, value), + }); + } + + (Rvalue::Use(Operand::Place(place)), ty, info.span) + } }) } From 0601ba579f07da8b9b4c677ac858dfc22fde6351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 14:59:23 -0300 Subject: [PATCH 03/14] Add array example --- examples/arrays.con | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 examples/arrays.con diff --git a/examples/arrays.con b/examples/arrays.con new file mode 100644 index 0000000..f59460a --- /dev/null +++ b/examples/arrays.con @@ -0,0 +1,8 @@ +mod Example { + fn main() -> i64 { + let array: [i32; 4] = [1, 2, 3, 4]; + let nested_array: [[i32; 2]; 2] = [[1, 2], [3, 4]]; + + return 0; + } +} From 0e60c11c58ff17bb33e688b5dbf7a16c6caa26d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 15:10:44 -0300 Subject: [PATCH 04/14] Fix error --- crates/concrete_ir/src/lowering.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 1fbeba9..21be736 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -989,7 +989,7 @@ fn lower_expression( kind: StatementKind::Assign(first_place, first_value), }); - for (idx, element) in info.values.iter().enumerate() { + for (idx, element) in values { let mut element_place = place.clone(); element_place.projection.push(PlaceElem::Index(idx)); From 9c7404fd0c588768f1449892579cdcf419710e16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 15:29:56 -0300 Subject: [PATCH 05/14] Add lowering for ArrayIndex --- crates/concrete_ir/src/lowering.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 21be736..cd1b068 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -1395,7 +1395,35 @@ pub fn lower_path( ty = struct_body.variants[idx].ty.clone(); } } - PathSegment::ArrayIndex(_, _) => todo!(), + PathSegment::ArrayIndex(expression, _) => { + while let TyKind::Ref(inner, _) = ty.kind { + projection.push(PlaceElem::Deref); + ty = *inner; + } + + if let TyKind::Array(element_type, _) = ty.kind { + let (index, index_ty) = lower_value_expr(builder, expression, None)?; + + let index_local = builder.add_temp_local(index_ty.kind); + let index_place = Place { + local: index_local, + projection: vec![], + }; + + builder.statements.push(Statement { + span: None, + kind: StatementKind::StorageLive(index_local), + }); + builder.statements.push(Statement { + span: None, + kind: StatementKind::Assign(index_place.clone(), index), + }); + + projection.push(PlaceElem::Index(index_local)); + + ty = *element_type; + } + } } } From 541aa1ec3d78008f65267c06862222f110ad4d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 15:42:46 -0300 Subject: [PATCH 06/14] Add accessing in array example --- examples/arrays.con | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/arrays.con b/examples/arrays.con index f59460a..9721fd7 100644 --- a/examples/arrays.con +++ b/examples/arrays.con @@ -1,8 +1,11 @@ mod Example { - fn main() -> i64 { + fn main() -> i32 { let array: [i32; 4] = [1, 2, 3, 4]; let nested_array: [[i32; 2]; 2] = [[1, 2], [3, 4]]; - return 0; + let a: i32 = array[1]; + let b: i32 = nested_array[1][0]; + + return a + b; } } From 0656ccc889e97980722d9d4bafb750590c1099b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 16:42:12 -0300 Subject: [PATCH 07/14] Fix clippy --- crates/concrete_ir/src/lowering.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index cd1b068..ea70baf 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -740,13 +740,9 @@ fn find_expression_type(builder: &mut FnBodyBuilder, info: &Expression) -> Optio } Expression::Cast(_, _, _) => todo!(), Expression::ArrayInit(info) => { - let Some(first_element) = info.values.get(0) else { - return None; - }; + let first_element = info.values.first()?; - let Some(first_type) = find_expression_type(builder, first_element) else { - return None; - }; + let first_type = find_expression_type(builder, first_element)?; let length = info.values.len() as u64; @@ -994,7 +990,7 @@ fn lower_expression( element_place.projection.push(PlaceElem::Index(idx)); let (value, _value_ty, _field_span) = - lower_expression(builder, &element, Some(element_type.clone()))?; + lower_expression(builder, element, Some(element_type.clone()))?; builder.statements.push(Statement { span: Some(info.span), From d7ae83ea83695ffdc7a60a6cd51c1a47597131f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Mon, 22 Apr 2024 17:04:02 -0300 Subject: [PATCH 08/14] Refactor for more idiomatic --- crates/concrete_ir/src/lowering.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index ea70baf..1fcf72d 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -935,13 +935,10 @@ fn lower_expression( (rvalue, new_ty, *span) } Expression::ArrayInit(info) => { - let element_type_hint = match type_hint.clone() { - Some(type_hint) => match type_hint.kind { - TyKind::Array(type_hint, _) => Some(*type_hint), - _ => None, - }, - None => None, - }; + let element_type_hint = type_hint.and_then(|type_hint| match type_hint.kind { + TyKind::Array(type_hint, _) => Some(*type_hint), + _ => None, + }); let mut values = info.values.iter().enumerate(); From 308010cf5b429d10e2fcf3d5499a2e9325268194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 24 Apr 2024 10:49:28 -0300 Subject: [PATCH 09/14] Add temporary local for array creation The local is used as the array index, although is constant --- crates/concrete_ir/src/lowering.rs | 72 +++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 1fcf72d..424c685 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -974,8 +974,43 @@ fn lower_expression( kind: StatementKind::StorageLive(array_local), }); + let first_idx_local = { + let idx_kind = TyKind::Uint(UintTy::U64); + + let first_idx_local = builder.add_temp_local(idx_kind.clone()); + builder.statements.push(Statement { + span: None, + kind: StatementKind::StorageLive(first_idx_local), + }); + + let first_idx_place = Place { + local: first_idx_local, + projection: Default::default(), + }; + + builder.statements.push(Statement { + span: None, + kind: StatementKind::Assign( + first_idx_place, + Rvalue::Use(Operand::Const(ConstData { + ty: Ty { + span: None, + kind: idx_kind, + }, + data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64( + first_idx as u64, + ))), + })), + ), + }); + + first_idx_local + }; + let mut first_place = place.clone(); - first_place.projection.push(PlaceElem::Index(first_idx)); + first_place + .projection + .push(PlaceElem::Index(first_idx_local)); builder.statements.push(Statement { span: Some(info.span), @@ -983,8 +1018,41 @@ fn lower_expression( }); for (idx, element) in values { + let idx_local = { + let idx_kind = TyKind::Uint(UintTy::U64); + + let idx_local = builder.add_temp_local(idx_kind.clone()); + builder.statements.push(Statement { + span: None, + kind: StatementKind::StorageLive(first_idx_local), + }); + + let idx_place = Place { + local: first_idx_local, + projection: Default::default(), + }; + + builder.statements.push(Statement { + span: None, + kind: StatementKind::Assign( + idx_place, + Rvalue::Use(Operand::Const(ConstData { + ty: Ty { + span: None, + kind: idx_kind, + }, + data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64( + idx as u64, + ))), + })), + ), + }); + + idx_local + }; + let mut element_place = place.clone(); - element_place.projection.push(PlaceElem::Index(idx)); + element_place.projection.push(PlaceElem::Index(idx_local)); let (value, _value_ty, _field_span) = lower_expression(builder, element, Some(element_type.clone()))?; From f8377ae97808b39dfac950efd94b70f6bdc0e78d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 24 Apr 2024 11:12:30 -0300 Subject: [PATCH 10/14] Revert "Add temporary local for array creation" This reverts commit 308010cf5b429d10e2fcf3d5499a2e9325268194. --- crates/concrete_ir/src/lowering.rs | 72 +----------------------------- 1 file changed, 2 insertions(+), 70 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 424c685..1fcf72d 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -974,43 +974,8 @@ fn lower_expression( kind: StatementKind::StorageLive(array_local), }); - let first_idx_local = { - let idx_kind = TyKind::Uint(UintTy::U64); - - let first_idx_local = builder.add_temp_local(idx_kind.clone()); - builder.statements.push(Statement { - span: None, - kind: StatementKind::StorageLive(first_idx_local), - }); - - let first_idx_place = Place { - local: first_idx_local, - projection: Default::default(), - }; - - builder.statements.push(Statement { - span: None, - kind: StatementKind::Assign( - first_idx_place, - Rvalue::Use(Operand::Const(ConstData { - ty: Ty { - span: None, - kind: idx_kind, - }, - data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64( - first_idx as u64, - ))), - })), - ), - }); - - first_idx_local - }; - let mut first_place = place.clone(); - first_place - .projection - .push(PlaceElem::Index(first_idx_local)); + first_place.projection.push(PlaceElem::Index(first_idx)); builder.statements.push(Statement { span: Some(info.span), @@ -1018,41 +983,8 @@ fn lower_expression( }); for (idx, element) in values { - let idx_local = { - let idx_kind = TyKind::Uint(UintTy::U64); - - let idx_local = builder.add_temp_local(idx_kind.clone()); - builder.statements.push(Statement { - span: None, - kind: StatementKind::StorageLive(first_idx_local), - }); - - let idx_place = Place { - local: first_idx_local, - projection: Default::default(), - }; - - builder.statements.push(Statement { - span: None, - kind: StatementKind::Assign( - idx_place, - Rvalue::Use(Operand::Const(ConstData { - ty: Ty { - span: None, - kind: idx_kind, - }, - data: ConstKind::Value(ValueTree::Leaf(ConstValue::U64( - idx as u64, - ))), - })), - ), - }); - - idx_local - }; - let mut element_place = place.clone(); - element_place.projection.push(PlaceElem::Index(idx_local)); + element_place.projection.push(PlaceElem::Index(idx)); let (value, _value_ty, _field_span) = lower_expression(builder, element, Some(element_type.clone()))?; From 18c15b80d1e23ddcef9046e3ef65aaa4f1110a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 24 Apr 2024 11:47:01 -0300 Subject: [PATCH 11/14] Add ConstatIndex to PlaceElem --- crates/concrete_codegen_mlir/src/codegen.rs | 3 +++ crates/concrete_ir/src/lib.rs | 2 ++ 2 files changed, 5 insertions(+) diff --git a/crates/concrete_codegen_mlir/src/codegen.rs b/crates/concrete_codegen_mlir/src/codegen.rs index faa1c33..8e5f8c0 100644 --- a/crates/concrete_codegen_mlir/src/codegen.rs +++ b/crates/concrete_codegen_mlir/src/codegen.rs @@ -500,6 +500,7 @@ fn compile_rvalue<'c: 'b, 'b>( } PlaceElem::Field(_) => todo!(), PlaceElem::Index(_) => todo!(), + PlaceElem::ConstantIndex(_) => todo!(), } } @@ -1012,6 +1013,7 @@ fn compile_store_place<'c: 'b, 'b>( } } PlaceElem::Index(_) => todo!(), + PlaceElem::ConstantIndex(_) => todo!(), } } @@ -1083,6 +1085,7 @@ fn compile_load_place<'c: 'b, 'b>( } } PlaceElem::Index(_) => todo!(), + PlaceElem::ConstantIndex(_) => todo!(), } } diff --git a/crates/concrete_ir/src/lib.rs b/crates/concrete_ir/src/lib.rs index c015940..3470912 100644 --- a/crates/concrete_ir/src/lib.rs +++ b/crates/concrete_ir/src/lib.rs @@ -201,6 +201,8 @@ pub enum PlaceElem { Field(FieldIndex), /// array index Index(LocalIndex), + /// constant array index + ConstantIndex(u64), } /// A local, akin to a variable, it can be user defined or compiler-introduced. From e657ebb49528deb61aa510abfd6b9960fd6c5f52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Wed, 24 Apr 2024 11:52:02 -0300 Subject: [PATCH 12/14] Use ConstantIndex on array creation --- crates/concrete_ir/src/lowering.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 1fcf72d..5d0f8fb 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -975,7 +975,9 @@ fn lower_expression( }); let mut first_place = place.clone(); - first_place.projection.push(PlaceElem::Index(first_idx)); + first_place + .projection + .push(PlaceElem::ConstantIndex(first_idx as u64)); builder.statements.push(Statement { span: Some(info.span), @@ -984,7 +986,9 @@ fn lower_expression( for (idx, element) in values { let mut element_place = place.clone(); - element_place.projection.push(PlaceElem::Index(idx)); + element_place + .projection + .push(PlaceElem::ConstantIndex(idx as u64)); let (value, _value_ty, _field_span) = lower_expression(builder, element, Some(element_type.clone()))?; From 62d12574f27a0d5f0797ec03f2bd3bec7ddd0bf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 26 Apr 2024 15:55:11 -0300 Subject: [PATCH 13/14] Add simple comments explaining the array init --- crates/concrete_ir/src/lowering.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 27a45c1..56183a6 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -1064,6 +1064,7 @@ fn lower_expression( let mut values = info.values.iter().enumerate(); + // Extract the first value from the array init. It's type will be used as type hint for the following elements. let (first_idx, first_element) = values.next().expect("array init cannot be empty"); let (first_value, element_type, _element_span) = lower_expression(builder, first_element, element_type_hint)?; @@ -1084,28 +1085,28 @@ fn lower_expression( ), }; + // Create and init local for the array init expression. let array_local = builder.add_local(Local::temp(ty.clone())); - let place = Place { local: array_local, projection: Default::default(), }; - builder.statements.push(Statement { span: None, kind: StatementKind::StorageLive(array_local), }); + // Assign the first value of the expression let mut first_place = place.clone(); first_place .projection .push(PlaceElem::ConstantIndex(first_idx as u64)); - builder.statements.push(Statement { span: Some(info.span), kind: StatementKind::Assign(first_place, first_value), }); + // Loop over the remaining values and assign them for (idx, element) in values { let mut element_place = place.clone(); element_place From 955f3f8c7dfa10637c21ea90f51515d6b4c50d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Gonz=C3=A1lez=20Calder=C3=B3n?= Date: Fri, 26 Apr 2024 15:55:11 -0300 Subject: [PATCH 14/14] Add simple comments explaining the array index --- crates/concrete_ir/src/lowering.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/concrete_ir/src/lowering.rs b/crates/concrete_ir/src/lowering.rs index 56183a6..9cee0ba 100644 --- a/crates/concrete_ir/src/lowering.rs +++ b/crates/concrete_ir/src/lowering.rs @@ -1522,14 +1522,13 @@ pub fn lower_path( } if let TyKind::Array(element_type, _) = ty.kind { + // Assign the index expression to a temporary local let (index, index_ty) = lower_value_expr(builder, expression, None)?; - let index_local = builder.add_temp_local(index_ty.kind); let index_place = Place { local: index_local, projection: vec![], }; - builder.statements.push(Statement { span: None, kind: StatementKind::StorageLive(index_local), @@ -1539,6 +1538,7 @@ pub fn lower_path( kind: StatementKind::Assign(index_place.clone(), index), }); + // Use the local's value as index of the array projection.push(PlaceElem::Index(index_local)); ty = *element_type;