cranelift_codegen/ir/
progpoint.rs1use crate::entity::EntityRef;
4use crate::ir::{Ebb, Inst, ValueDef};
5use core::cmp;
6use core::fmt;
7use core::u32;
8
9#[derive(PartialEq, Eq, Clone, Copy)]
17pub struct ProgramPoint(u32);
18
19impl From<Inst> for ProgramPoint {
20 fn from(inst: Inst) -> Self {
21 let idx = inst.index();
22 debug_assert!(idx < (u32::MAX / 2) as usize);
23 Self((idx * 2) as u32)
24 }
25}
26
27impl From<Ebb> for ProgramPoint {
28 fn from(ebb: Ebb) -> Self {
29 let idx = ebb.index();
30 debug_assert!(idx < (u32::MAX / 2) as usize);
31 Self((idx * 2 + 1) as u32)
32 }
33}
34
35impl From<ValueDef> for ProgramPoint {
36 fn from(def: ValueDef) -> Self {
37 match def {
38 ValueDef::Result(inst, _) => inst.into(),
39 ValueDef::Param(ebb, _) => ebb.into(),
40 }
41 }
42}
43
44#[derive(PartialEq, Eq, Clone, Copy)]
47pub enum ExpandedProgramPoint {
48 Inst(Inst),
50 Ebb(Ebb),
52}
53
54impl ExpandedProgramPoint {
55 pub fn unwrap_inst(self) -> Inst {
57 match self {
58 Self::Inst(x) => x,
59 Self::Ebb(x) => panic!("expected inst: {}", x),
60 }
61 }
62}
63
64impl From<Inst> for ExpandedProgramPoint {
65 fn from(inst: Inst) -> Self {
66 Self::Inst(inst)
67 }
68}
69
70impl From<Ebb> for ExpandedProgramPoint {
71 fn from(ebb: Ebb) -> Self {
72 Self::Ebb(ebb)
73 }
74}
75
76impl From<ValueDef> for ExpandedProgramPoint {
77 fn from(def: ValueDef) -> Self {
78 match def {
79 ValueDef::Result(inst, _) => inst.into(),
80 ValueDef::Param(ebb, _) => ebb.into(),
81 }
82 }
83}
84
85impl From<ProgramPoint> for ExpandedProgramPoint {
86 fn from(pp: ProgramPoint) -> Self {
87 if pp.0 & 1 == 0 {
88 Self::Inst(Inst::from_u32(pp.0 / 2))
89 } else {
90 Self::Ebb(Ebb::from_u32(pp.0 / 2))
91 }
92 }
93}
94
95impl fmt::Display for ExpandedProgramPoint {
96 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 match *self {
98 Self::Inst(x) => write!(f, "{}", x),
99 Self::Ebb(x) => write!(f, "{}", x),
100 }
101 }
102}
103
104impl fmt::Display for ProgramPoint {
105 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
106 let epp: ExpandedProgramPoint = (*self).into();
107 epp.fmt(f)
108 }
109}
110
111impl fmt::Debug for ExpandedProgramPoint {
112 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
113 write!(f, "ExpandedProgramPoint({})", self)
114 }
115}
116
117impl fmt::Debug for ProgramPoint {
118 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
119 write!(f, "ProgramPoint({})", self)
120 }
121}
122
123pub trait ProgramOrder {
128 fn cmp<A, B>(&self, a: A, b: B) -> cmp::Ordering
136 where
137 A: Into<ExpandedProgramPoint>,
138 B: Into<ExpandedProgramPoint>;
139
140 fn is_ebb_gap(&self, inst: Inst, ebb: Ebb) -> bool;
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149 use crate::entity::EntityRef;
150 use crate::ir::{Ebb, Inst};
151 use alloc::string::ToString;
152
153 #[test]
154 fn convert() {
155 let i5 = Inst::new(5);
156 let b3 = Ebb::new(3);
157
158 let pp1: ProgramPoint = i5.into();
159 let pp2: ProgramPoint = b3.into();
160
161 assert_eq!(pp1.to_string(), "inst5");
162 assert_eq!(pp2.to_string(), "ebb3");
163 }
164}