llvm_scratch/core/basic_block/
basic_block.rs1use std::fmt;
2use std::fmt::Formatter;
3
4use id_arena::{Arena, Id};
5
6use crate::core;
7
8pub type BasicBlockId = Id<BasicBlock>;
9
10pub struct BasicBlock {
13 label: core::llvm_string::LLVMString,
14 pub predecessor: Option<BasicBlockId>,
15 pub kind: BasicBlockKind,
16
17 instructions: Vec<core::instruction::InstructionId>,
18 inst_allocator: Arena<core::instruction::Instruction>,
19}
20
21impl fmt::Display for BasicBlock {
22 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23 if !self.label.is_empty() {
24 writeln!(f, "{}:", self.label)?;
25 }
26
27 for inst_id in self.instructions.iter() {
28 let inst = self.inst_allocator.get(*inst_id).unwrap();
29
30 writeln!(f, " {}", inst)?;
31 }
32 Ok(())
33 }
34}
35
36#[allow(dead_code)]
37impl BasicBlock {
38 pub fn new(
39 l: core::llvm_string::LLVMString,
40 pred: Option<BasicBlockId>,
41 k: BasicBlockKind,
42 ) -> Self {
43 Self {
44 label: l,
45 predecessor: pred,
46 kind: k,
47 instructions: Vec::new(),
48 inst_allocator: Arena::new(),
49 }
50 }
51
52 pub fn print_successors(
53 &self,
54 f: &mut Formatter<'_>,
55 allocator: &Arena<core::basic_block::BasicBlock>,
56 ) -> fmt::Result {
57 match self.kind {
58 BasicBlockKind::TERMINATED => {}
59 BasicBlockKind::UNCONDITIONAL(succ_id) => {
60 let succ_bb = allocator.get(succ_id).unwrap();
61 write!(f, "{}", succ_bb)?;
62 }
63 }
64
65 Ok(())
66 }
67
68 pub fn get_label_ref(&self) -> &core::llvm_string::LLVMString {
70 &self.label
71 }
72
73 pub fn insts_empty(&self) -> bool {
75 self.instructions.is_empty()
76 }
77
78 pub fn new_inst(
79 &mut self,
80 inst: core::instruction::Instruction,
81 ) -> core::instruction::InstructionId {
82 let inst_id = self.inst_allocator.alloc(inst);
83 self.instructions.push(inst_id);
84
85 inst_id
86 }
87}
88
89impl Default for BasicBlock {
90 fn default() -> Self {
91 Self {
92 label: core::llvm_string::LLVMString::from(String::new()),
93 predecessor: None,
94 kind: BasicBlockKind::TERMINATED,
95 instructions: Vec::new(),
96 inst_allocator: Arena::new(),
97 }
98 }
99}
100
101#[derive(Eq, PartialEq, PartialOrd, Ord, Hash)]
104pub enum BasicBlockKind {
105 TERMINATED,
108
109 UNCONDITIONAL(BasicBlockId),
111}