pulsar_ir/
basic_block.rs

1// Copyright (C) 2024 Ethan Uppal. All rights reserved.
2use 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>;