Skip to main content

vicis_core/ir/function/
builder.rs

1use crate::ir::value::{Value, ValueId};
2
3use super::{basic_block::BasicBlockId, instruction::builder::Builder as InstBuilder, Function};
4use rustc_hash::FxHashSet;
5
6pub struct Builder<'a> {
7    ctx: Context,
8    pub(super) func: &'a mut Function,
9    pub(super) cur_block: Option<BasicBlockId>,
10}
11
12struct Context {
13    is_inserted: FxHashSet<BasicBlockId>,
14}
15
16impl<'a> Builder<'a> {
17    pub fn new(func: &'a mut Function) -> Self {
18        Self {
19            ctx: Context::default(),
20            func,
21            cur_block: None,
22        }
23    }
24
25    pub fn create_block(&mut self) -> BasicBlockId {
26        self.func.data.create_block()
27    }
28
29    pub fn switch_to_block(&mut self, block: BasicBlockId) {
30        self.cur_block = Some(block);
31        self.ensure_inserted_block(block);
32    }
33
34    pub fn ensure_inserted_block(&mut self, block: BasicBlockId) {
35        if self.ctx.is_inserted(block) {
36            return;
37        }
38        self.func.layout.append_block(block);
39        self.ctx.set_as_inserted(block);
40    }
41
42    pub fn inst<'short>(&'short mut self) -> InstBuilder<'a, 'short> {
43        InstBuilder::new(self)
44    }
45
46    pub fn value<T: Into<Value>>(&mut self, val: T) -> ValueId {
47        self.func.data.create_value(val.into())
48    }
49}
50
51impl Default for Context {
52    fn default() -> Self {
53        Self {
54            is_inserted: FxHashSet::default(),
55        }
56    }
57}
58
59impl Context {
60    fn set_as_inserted(&mut self, block: BasicBlockId) {
61        self.is_inserted.insert(block);
62    }
63
64    fn is_inserted(&self, block: BasicBlockId) -> bool {
65        self.is_inserted.contains(&block)
66    }
67}