vicis_core/ir/function/
builder.rs1use 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}