cranelift_codegen/ir/
progpoint.rs

1//! Program points.
2
3use crate::ir::{Block, Inst};
4use core::fmt;
5
6/// A `ProgramPoint` represents a position in a function where the live range of an SSA value can
7/// begin or end. It can be either:
8///
9/// 1. An instruction or
10/// 2. A block header.
11///
12/// This corresponds more or less to the lines in the textual form of Cranelift IR.
13#[derive(PartialEq, Eq, Clone, Copy)]
14pub enum ProgramPoint {
15    /// An instruction in the function.
16    Inst(Inst),
17    /// A block header.
18    Block(Block),
19}
20
21impl ProgramPoint {
22    /// Get the instruction we know is inside.
23    pub fn unwrap_inst(self) -> Inst {
24        match self {
25            Self::Inst(x) => x,
26            Self::Block(x) => panic!("expected inst: {x}"),
27        }
28    }
29}
30
31impl From<Inst> for ProgramPoint {
32    fn from(inst: Inst) -> Self {
33        Self::Inst(inst)
34    }
35}
36
37impl From<Block> for ProgramPoint {
38    fn from(block: Block) -> Self {
39        Self::Block(block)
40    }
41}
42
43impl fmt::Display for ProgramPoint {
44    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
45        match *self {
46            Self::Inst(x) => write!(f, "{x}"),
47            Self::Block(x) => write!(f, "{x}"),
48        }
49    }
50}
51
52impl fmt::Debug for ProgramPoint {
53    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54        write!(f, "ProgramPoint({self})")
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use crate::entity::EntityRef;
62    use alloc::string::ToString;
63
64    #[test]
65    fn convert() {
66        let i5 = Inst::new(5);
67        let b3 = Block::new(3);
68
69        let pp1: ProgramPoint = i5.into();
70        let pp2: ProgramPoint = b3.into();
71
72        assert_eq!(pp1.to_string(), "inst5");
73        assert_eq!(pp2.to_string(), "block3");
74    }
75}