1use super::{branch_condition::BranchCondition, Ir};
3use pulsar_utils::{
4 id::{Gen, Id},
5 mutcell::MutCell
6};
7use std::{fmt::Display, hash::Hash};
8
9pub struct BasicBlock {
10 id: Id,
11 contents: Vec<Ir>,
12 branch_condition: MutCell<BranchCondition>
13}
14
15impl BasicBlock {
16 pub fn new() -> Self {
17 Self {
18 id: Gen::next("basic block"),
19 contents: vec![],
20 branch_condition: MutCell::new(BranchCondition::Never)
21 }
22 }
23
24 pub fn id(&self) -> Id {
25 self.id
26 }
27
28 pub fn add(&mut self, ir: Ir) {
29 self.contents.push(ir);
30 }
31
32 pub fn branch_condition(&self) -> BranchCondition {
33 self.branch_condition.clone_out()
34 }
35}
36
37impl PartialEq for BasicBlock {
38 fn eq(&self, other: &Self) -> bool {
39 self.id.eq(&other.id)
40 }
41}
42
43impl Eq for BasicBlock {}
44
45impl Hash for BasicBlock {
46 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
47 self.id.hash(state);
48 }
49}
50
51impl Display for BasicBlock {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 writeln!(f, ".L_BB{}", self.id)?;
54 for instr in &self.contents {
55 writeln!(f, " {}", instr)?;
56 }
57 write!(f, " branch {}", self.branch_condition)
58 }
59}
60
61impl<'a> IntoIterator for &'a BasicBlock {
62 type Item = &'a Ir;
63 type IntoIter = std::slice::Iter<'a, Ir>;
64
65 fn into_iter(self) -> Self::IntoIter {
66 self.contents.iter()
67 }
68}
69
70pub type BasicBlockCell = MutCell<BasicBlock>;