Skip to content

Commit

Permalink
feat: Lower collections extension (#1720)
Browse files Browse the repository at this point in the history
Closes #1701 and fixes #1645.

Note that destructors and ref-counting hooks are still missing. These
will follow in a future PR once they are available in hugr-llvm.
  • Loading branch information
mark-koch authored Nov 27, 2024
1 parent fc609a2 commit c87d4f3
Show file tree
Hide file tree
Showing 19 changed files with 943 additions and 2 deletions.
10 changes: 10 additions & 0 deletions hugr-core/src/std_extensions/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ impl ListValue {
pub fn custom_type(&self) -> CustomType {
list_custom_type(self.1.clone())
}

/// Returns the type of values inside the `[ListValue]`.
pub fn get_element_type(&self) -> &Type {
&self.1
}

/// Returns the values contained inside the `[ListValue]`.
pub fn get_contents(&self) -> &[Value] {
&self.0
}
}

impl TryHash for ListValue {
Expand Down
36 changes: 35 additions & 1 deletion hugr-llvm/src/emit/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::{collections::HashMap, rc::Rc};

use anyhow::{anyhow, Result};
use hugr_core::{
extension::prelude::{either_type, option_type},
ops::{constant::CustomConst, ExtensionOp, FuncDecl, FuncDefn},
types::Type,
HugrView, NodeIndex, PortIndex, Wire,
Expand All @@ -12,7 +13,7 @@ use inkwell::{
context::Context,
module::Module,
types::{BasicType, BasicTypeEnum, FunctionType},
values::{BasicValueEnum, FunctionValue, GlobalValue},
values::{BasicValueEnum, FunctionValue, GlobalValue, IntValue},
};
use itertools::zip_eq;

Expand Down Expand Up @@ -314,3 +315,36 @@ impl<'c, 'a, H: HugrView> EmitFuncContext<'c, 'a, H> {
Ok((self.emit_context, self.todo))
}
}

/// Builds an optional value wrapping `some_value` conditioned on the provided `is_some` flag.
pub fn build_option<'c, H: HugrView>(
ctx: &mut EmitFuncContext<'c, '_, H>,
is_some: IntValue<'c>,
some_value: BasicValueEnum<'c>,
hugr_ty: HugrType,
) -> Result<BasicValueEnum<'c>> {
let option_ty = ctx.llvm_sum_type(option_type(hugr_ty))?;
let builder = ctx.builder();
let some = option_ty.build_tag(builder, 1, vec![some_value])?;
let none = option_ty.build_tag(builder, 0, vec![])?;
let option = builder.build_select(is_some, some, none, "")?;
Ok(option)
}

/// Builds a result value wrapping either `ok_value` or `else_value` depending on the provided
/// `is_ok` flag.
pub fn build_ok_or_else<'c, H: HugrView>(
ctx: &mut EmitFuncContext<'c, '_, H>,
is_ok: IntValue<'c>,
ok_value: BasicValueEnum<'c>,
ok_hugr_ty: HugrType,
else_value: BasicValueEnum<'c>,
else_hugr_ty: HugrType,
) -> Result<BasicValueEnum<'c>> {
let either_ty = ctx.llvm_sum_type(either_type(else_hugr_ty, ok_hugr_ty))?;
let builder = ctx.builder();
let left = either_ty.build_tag(builder, 0, vec![else_value])?;
let right = either_ty.build_tag(builder, 1, vec![ok_value])?;
let either = builder.build_select(is_ok, right, left, "")?;
Ok(either)
}
3 changes: 2 additions & 1 deletion hugr-llvm/src/emit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use hugr_core::ops::handle::FuncID;
use hugr_core::std_extensions::arithmetic::{
conversions, float_ops, float_types, int_ops, int_types,
};
use hugr_core::std_extensions::logic;
use hugr_core::std_extensions::{collections, logic};
use hugr_core::types::TypeRow;
use hugr_core::{Hugr, HugrView};
use inkwell::module::Module;
Expand Down Expand Up @@ -153,6 +153,7 @@ impl SimpleHugrConfig {
float_ops::EXTENSION_ID,
conversions::EXTENSION_ID,
logic::EXTENSION_ID,
collections::EXTENSION_ID,
]),
),
)
Expand Down
1 change: 1 addition & 0 deletions hugr-llvm/src/extension.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod collections;
pub mod conversions;
pub mod float;
pub mod int;
Expand Down
Loading

0 comments on commit c87d4f3

Please sign in to comment.