remir_llvm 1.0.0

The LLVM binding for the Remir library
use std::hint::unreachable_unchecked;

use remir::{block::BlockInstruction, insts::Instruction};

use crate::{LLVMBridge, llvm_to_base, llvm_to_base_returnless, utils::LLVMBasicValue};

pub fn bridge_llvm_struct_instruction(
    instruction: BlockInstruction,
    bridge: &mut LLVMBridge,
) -> Result<Option<LLVMBasicValue>, ()> {
    let res = match &instruction.instruction {
        Instruction::ExtractValue { struct_val, index } => {
            let struct_val = bridge.values[&struct_val.base.inst_ind].into_struct_value();

            let res = llvm_to_base!(bridge.builder.build_extract_value(
                struct_val,
                *index as u32,
                ""
            ));

            Some(res.into())
        }

        Instruction::InsertValue {
            struct_val,
            index,
            val,
        } => {
            let struct_val = bridge.values[&struct_val.base.inst_ind].into_struct_value();
            let val = bridge.values[&val.inst_ind].inner;

            llvm_to_base_returnless!(bridge.builder.build_insert_value(
                struct_val,
                val,
                *index as u32,
                ""
            ));

            None
        }

        Instruction::Switch {
            value,
            else_block,
            cases,
        } => {
            let value = bridge.values[&value.base.inst_ind].into_int_value();
            let else_block = bridge.blocks[else_block].inner.clone();

            let mut llvm_cases = vec![];

            for case in cases {
                let case_val = bridge.values[&case.0.base.inst_ind].into_int_value();
                let block = bridge.blocks[&case.1].inner.clone();

                llvm_cases.push((case_val, block));
            }

            llvm_to_base_returnless!(bridge.builder.build_switch(value, else_block, &llvm_cases));

            None
        }

        Instruction::Select {
            cond,
            true_val,
            false_val,
        } => {
            let cond = bridge.values[&cond.base.inst_ind].into_int_value();
            let true_val = bridge.values[&true_val.inst_ind].inner.clone();
            let false_val = bridge.values[&false_val.inst_ind].inner.clone();

            let res = llvm_to_base!(bridge.builder.build_select(cond, true_val, false_val, ""));

            Some(res)
        }

        _ => unsafe { unreachable_unchecked() },
    };

    if res.is_some() {
        return Ok(Some(LLVMBasicValue::new(res.unwrap(), &bridge.ctx)));
    }

    return Ok(None);
}