1 //! Program points.
2 
3 use crate::ir::{Block, Inst};
4 use 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)]
14 pub enum ProgramPoint {
15     /// An instruction in the function.
16     Inst(Inst),
17     /// A block header.
18     Block(Block),
19 }
20 
21 impl ProgramPoint {
22     /// Get the instruction we know is inside.
unwrap_inst(self) -> Inst23     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 
31 impl From<Inst> for ProgramPoint {
from(inst: Inst) -> Self32     fn from(inst: Inst) -> Self {
33         Self::Inst(inst)
34     }
35 }
36 
37 impl From<Block> for ProgramPoint {
from(block: Block) -> Self38     fn from(block: Block) -> Self {
39         Self::Block(block)
40     }
41 }
42 
43 impl fmt::Display for ProgramPoint {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result44     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 
52 impl fmt::Debug for ProgramPoint {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result53     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54         write!(f, "ProgramPoint({self})")
55     }
56 }
57 
58 #[cfg(test)]
59 mod tests {
60     use super::*;
61     use crate::entity::EntityRef;
62     use alloc::string::ToString;
63 
64     #[test]
convert()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 }
76