oxicuda_ptx/ir/block.rs
1//! Basic block representation for PTX control flow.
2//!
3//! A [`BasicBlock`] groups a sequence of PTX instructions under an optional
4//! label. Basic blocks are the fundamental unit of control flow in the IR
5//! and map directly to labeled sections in PTX assembly.
6
7use super::instruction::Instruction;
8
9/// A basic block of PTX instructions.
10///
11/// Each block optionally begins with a label and contains a linear sequence
12/// of instructions. Control flow between blocks is expressed through
13/// [`Instruction::Branch`] and [`Instruction::Label`] instructions.
14///
15/// # Examples
16///
17/// ```
18/// use oxicuda_ptx::ir::{BasicBlock, Instruction};
19///
20/// let block = BasicBlock {
21/// label: Some("loop_body".to_string()),
22/// instructions: vec![
23/// Instruction::Comment("loop iteration".to_string()),
24/// ],
25/// };
26/// assert_eq!(block.label.as_deref(), Some("loop_body"));
27/// ```
28#[derive(Debug, Clone)]
29pub struct BasicBlock {
30 /// Optional label for this block (used as a branch target).
31 pub label: Option<String>,
32 /// The sequence of instructions in this block.
33 pub instructions: Vec<Instruction>,
34}
35
36impl BasicBlock {
37 /// Creates a new empty basic block with no label.
38 #[must_use]
39 pub const fn new() -> Self {
40 Self {
41 label: None,
42 instructions: Vec::new(),
43 }
44 }
45
46 /// Creates a new empty basic block with the given label.
47 #[must_use]
48 pub fn with_label(label: impl Into<String>) -> Self {
49 Self {
50 label: Some(label.into()),
51 instructions: Vec::new(),
52 }
53 }
54
55 /// Appends an instruction to this block.
56 pub fn push(&mut self, inst: Instruction) {
57 self.instructions.push(inst);
58 }
59
60 /// Returns the number of instructions in this block.
61 #[must_use]
62 pub fn len(&self) -> usize {
63 self.instructions.len()
64 }
65
66 /// Returns `true` if this block contains no instructions.
67 #[must_use]
68 pub fn is_empty(&self) -> bool {
69 self.instructions.is_empty()
70 }
71}
72
73impl Default for BasicBlock {
74 fn default() -> Self {
75 Self::new()
76 }
77}