duskphantom_middle/ir/
macros.rs1#[macro_export]
18macro_rules! define_graph_iterator {
19 ($name:ident, $collection:ty, $pop_method:ident, $bb_update_method:ident) => {
20 pub struct $name {
21 container: $collection,
22 visited: HashSet<BBPtr>,
23 }
24
25 impl Iterator for $name {
26 type Item = BBPtr;
27 fn next(&mut self) -> Option<Self::Item> {
28 while let Some(bb) = self.container.$pop_method() {
29 if !self.visited.contains(&bb) {
30 self.visited.insert(bb);
31 self.container.extend(bb.$bb_update_method());
32 return Some(bb);
33 }
34 }
35 None
36 }
37 }
38
39 impl From<BBPtr> for $name {
40 fn from(bb: BBPtr) -> Self {
41 Self {
42 container: vec![bb].into(),
43 visited: HashSet::new(),
44 }
45 }
46 }
47 };
48}
49
50#[macro_export]
55macro_rules! gen_common_code {
56 ($type:ty,$id:ident) => {
57 #[inline]
58 unsafe fn as_any(&self) -> &dyn Any {
59 self
60 }
61 #[inline]
62 unsafe fn as_any_mut(&mut self) -> &mut dyn Any {
63 self
64 }
65 #[inline]
66 fn get_type(&self) -> InstType {
67 InstType::$id
68 }
69 #[inline]
70 fn get_manager(&self) -> &InstManager {
71 &self.manager
72 }
73 #[inline]
74 unsafe fn get_manager_mut(&mut self) -> &mut InstManager {
75 &mut self.manager
76 }
77 };
78}
79
80#[macro_export]
82macro_rules! define_inst_type_enum {
83 ($( $variant:ident ),*) => {
84 #[derive(Clone, Copy, Eq, PartialEq, Hash)]
85 pub enum InstType {
86 $( $variant ),*
87 }
88
89 impl InstType {
90 #[inline]
91 fn get_name(&self) -> String {
92 match self {
93 $( InstType::$variant => stringify!($variant).to_lowercase(), )*
94 }
95 }
96 }
97
98 impl std::fmt::Display for InstType {
99 #[inline]
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 write!(f, "{}", self.get_name())
102 }
103 }
104
105 impl std::fmt::Debug for InstType {
106 #[inline]
107 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
108 write!(f, "{}", self.get_name())
109 }
110 }
111 };
112}
113
114#[macro_export]
116macro_rules! impl_binary_inst {
117 ($type:ident, $operand_type:expr,$func: ident, $lhs:ident, $rhs: ident, $value_type: ident) => {
118 pub struct $type {
121 manager: InstManager,
122 }
123 impl BinaryInst for $type {
124 #[inline]
125 fn get_lhs(&self) -> &Operand {
126 &self.manager.operand[0]
127 }
128
129 #[inline]
130 fn set_lhs(&mut self, lhs: Operand) {
131 unsafe { self.get_manager_mut().set_operand(0, lhs) };
132 }
133
134 #[inline]
135 fn get_rhs(&self) -> &Operand {
136 &self.manager.operand[1]
137 }
138
139 #[inline]
140 fn set_rhs(&mut self, rhs: Operand) {
141 unsafe { self.get_manager_mut().set_operand(1, rhs) };
142 }
143 }
144
145 impl Instruction for $type {
146 gen_common_code!($type, $type);
147 fn copy_self(&self) -> Box<dyn Instruction> {
148 Box::new($type {
149 manager: InstManager::new($value_type),
150 })
151 }
152 #[inline]
153 fn gen_llvm_ir(&self) -> String {
154 format!(
155 "{} = {} {} {}, {}",
156 self,
157 self.get_type(),
158 $operand_type,
159 self.get_lhs(),
160 self.get_rhs()
161 )
162 }
163 }
164
165 impl Display for $type {
166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167 write!(f, "%{}_{}", stringify!($type), self.get_id())
168 }
169 }
170
171 impl IRBuilder {
172 pub fn $func(&mut self, $lhs: Operand, $rhs: Operand) -> InstPtr {
174 let mut inst = self.new_instruction(Box::new($type {
175 manager: InstManager::new($value_type),
176 }));
177 unsafe {
178 inst.get_manager_mut().add_operand($lhs);
179 inst.get_manager_mut().add_operand($rhs);
180 }
181 inst
182 }
183 }
184 };
185}