hugr_llvm/emit/
libc.rs

1use anyhow::Result;
2use hugr_core::{HugrView, Node};
3use inkwell::{
4    AddressSpace,
5    values::{BasicMetadataValueEnum, BasicValueEnum},
6};
7
8use crate::emit::func::EmitFuncContext;
9
10/// Emits a call to the libc `void abort()` function.
11pub fn emit_libc_abort<H: HugrView<Node = Node>>(context: &mut EmitFuncContext<H>) -> Result<()> {
12    let iw_ctx = context.typing_session().iw_context();
13    let abort_sig = iw_ctx.void_type().fn_type(&[], false);
14    let abort = context.get_extern_func("abort", abort_sig)?;
15    context.builder().build_call(abort, &[], "")?;
16    Ok(())
17}
18
19/// Emits a call to the libc `int printf(char*, ...)` function.
20pub fn emit_libc_printf<H: HugrView<Node = Node>>(
21    context: &mut EmitFuncContext<H>,
22    args: &[BasicMetadataValueEnum],
23) -> Result<()> {
24    let iw_ctx = context.typing_session().iw_context();
25    let str_ty = iw_ctx.i8_type().ptr_type(AddressSpace::default());
26    let printf_sig = iw_ctx.i32_type().fn_type(&[str_ty.into()], true);
27
28    let printf = context.get_extern_func("printf", printf_sig)?;
29    context.builder().build_call(printf, args, "")?;
30    Ok(())
31}
32
33/// Emits a call to the libc `void* malloc(size_t size)` function.
34pub fn emit_libc_malloc<'c, H: HugrView<Node = Node>>(
35    context: &mut EmitFuncContext<'c, '_, H>,
36    size: BasicMetadataValueEnum<'c>,
37) -> Result<BasicValueEnum<'c>> {
38    let iw_ctx = context.typing_session().iw_context();
39    let malloc_sig = iw_ctx
40        .i8_type()
41        .ptr_type(AddressSpace::default())
42        .fn_type(&[iw_ctx.i64_type().into()], false);
43    let malloc = context.get_extern_func("malloc", malloc_sig)?;
44    let res = context
45        .builder()
46        .build_call(malloc, &[size], "")?
47        .try_as_basic_value()
48        .unwrap_left();
49    Ok(res)
50}
51
52/// Emits a call to the libc `void free(void* ptr)` function.
53pub fn emit_libc_free<H: HugrView<Node = Node>>(
54    context: &mut EmitFuncContext<H>,
55    ptr: BasicMetadataValueEnum,
56) -> Result<()> {
57    let iw_ctx = context.typing_session().iw_context();
58    let ptr_ty = iw_ctx.i8_type().ptr_type(AddressSpace::default());
59    let ptr = context
60        .builder()
61        .build_bit_cast(ptr.into_pointer_value(), ptr_ty, "")?;
62
63    let free_sig = iw_ctx.void_type().fn_type(&[ptr_ty.into()], false);
64    let free = context.get_extern_func("free", free_sig)?;
65    context.builder().build_call(free, &[ptr.into()], "")?;
66    Ok(())
67}