vicis 0.1.0

Manipulate LLVM-IR in Pure Rust
Documentation
pub mod basic_block;
pub mod data;
pub mod instruction;
pub mod layout;
pub mod slot;

use super::{call_conv::CallConvKind, isa::TargetIsa, register::VRegs};
use crate::ir::{
    function::{Parameter, UnresolvedAttributeId},
    module::{attributes::Attribute, preemption_specifier::PreemptionSpecifier},
    types::{TypeId, Types},
};
use either::Either;
use instruction::InstructionId;
use std::fmt;

pub struct Function<T: TargetIsa> {
    pub name: String,
    pub is_var_arg: bool,
    pub result_ty: TypeId,
    pub params: Vec<Parameter>,
    pub preemption_specifier: PreemptionSpecifier,
    pub attributes: Vec<Either<Attribute, UnresolvedAttributeId>>,
    pub data: data::Data<T::InstData>,
    pub layout: layout::Layout<T::InstData>,
    pub slots: slot::Slots<T>,
    pub vregs: VRegs,
    pub types: Types,
    pub is_prototype: bool,
    pub call_conv: CallConvKind,
    pub isa: T,
}

impl<T: TargetIsa> Function<T> {
    pub fn remove_inst(&mut self, inst: InstructionId<T::InstData>) -> Option<()> {
        self.layout.remove_inst(inst)
    }
}

impl<T: TargetIsa> fmt::Debug for Function<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        if self.is_prototype {
            write!(f, "declare ")?
        } else {
            write!(f, "define ")?
        }
        write!(f, "{:?} ", self.preemption_specifier)?;
        write!(f, "{} ", self.types.to_string(self.result_ty))?;
        write!(f, "@{}(", self.name)?;
        for (i, param) in self.params.iter().enumerate() {
            write!(
                f,
                "{} %A{}{}",
                self.types.to_string(param.ty),
                i,
                if i == self.params.len() - 1 { "" } else { ", " }
            )?;
        }
        write!(f, ") ")?;
        for attr in &self.attributes {
            match attr {
                Either::Left(attr) => write!(f, "{:?} ", attr)?,
                Either::Right(id) => write!(f, "#{} ", id)?,
            }
        }

        if self.is_prototype {
            writeln!(f)?;
        } else {
            write!(f, "{{\n")?;
            for block_id in self.layout.block_iter() {
                writeln!(f, "B{:?}:", block_id.index())?;
                for inst_id in self.layout.inst_iter(block_id) {
                    let inst = self.data.inst_ref(inst_id);
                    writeln!(f, "    {:#?}", inst)?;
                }
            }
            write!(f, "}}\n")?;
        }

        Ok(())
    }
}