duskphantom_middle/ir/
function.rs1use std::ops::{Deref, DerefMut};
18
19use super::*;
20use crate::define_graph_iterator;
21
22pub type FunPtr = ObjPtr<Function>;
23
24pub struct Function {
25 pub mem_pool: ObjPtr<IRBuilder>,
26
27 pub name: String,
28
29 pub entry: Option<BBPtr>,
32
33 pub exit: Option<BBPtr>,
36
37 pub return_type: ValueType,
38
39 pub params: Vec<ParaPtr>,
41}
42
43impl Function {
44 pub fn is_lib(&self) -> bool {
46 self.entry.is_none()
47 }
48
49 pub fn is_main(&self) -> bool {
51 self.name == "main"
52 }
53
54 pub fn dfs_iter(&self) -> DFSIterator {
58 DFSIterator::from(self.entry.unwrap())
59 }
60
61 pub fn bfs_iter(&self) -> BFSIterator {
65 BFSIterator::from(self.entry.unwrap())
66 }
67
68 pub fn dfs_iter_rev(&self) -> DFSIteratorRev {
72 DFSIteratorRev::from(self.exit.unwrap())
73 }
74
75 pub fn bfs_iter_rev(&self) -> BFSIteratorRev {
79 BFSIteratorRev::from(self.exit.unwrap())
80 }
81
82 pub fn po_iter(&self) -> POIterator {
84 POIterator::from(self.entry.unwrap())
85 }
86
87 pub fn rpo_iter(&self) -> RPOIterator {
89 RPOIterator::from(self.entry.unwrap())
90 }
91
92 pub fn gen_llvm_ir(&self) -> String {
93 let header = if self.is_lib() { "declare" } else { "define" };
94 let mut ir = format!("{} {} @{}(", header, self.return_type, self.name);
95 if !self.params.is_empty() {
96 for param in self.params.iter() {
97 ir += &format!("{}, ", param.as_ref());
98 }
99 let _ = ir.split_off(ir.len() - 2);
100 }
101 ir += ")";
102
103 if self.is_lib() {
105 ir += "\n";
106 return ir;
107 }
108
109 ir += " {\n";
111 self.bfs_iter().for_each(|bb| {
112 ir += &bb.gen_llvm_ir();
113 });
114 ir + "\n}\n"
115 }
116}
117
118define_graph_iterator!(BFSIterator, VecDeque<BBPtr>, pop_front, get_succ_bb);
119define_graph_iterator!(BFSIteratorRev, VecDeque<BBPtr>, pop_front, get_pred_bb);
120define_graph_iterator!(DFSIterator, Vec<BBPtr>, pop, get_succ_bb);
121define_graph_iterator!(DFSIteratorRev, Vec<BBPtr>, pop, get_pred_bb);
122
123pub struct POIterator {
125 container: VecDeque<BBPtr>,
126}
127
128impl Iterator for POIterator {
129 type Item = BBPtr;
130 fn next(&mut self) -> Option<Self::Item> {
131 self.container.pop_front()
132 }
133}
134
135impl From<BBPtr> for POIterator {
136 fn from(bb: BBPtr) -> Self {
137 let mut container = Vec::new();
139 let mut visited = HashSet::new();
140 run_postorder(bb, &mut visited, &mut container);
141
142 Self {
144 container: container.into(),
145 }
146 }
147}
148
149pub struct RPOIterator {
151 container: Vec<BBPtr>,
152}
153
154impl Iterator for RPOIterator {
155 type Item = BBPtr;
156 fn next(&mut self) -> Option<Self::Item> {
157 self.container.pop()
158 }
159}
160
161impl From<BBPtr> for RPOIterator {
162 fn from(bb: BBPtr) -> Self {
163 let mut container = Vec::new();
165 let mut visited = HashSet::new();
166 run_postorder(bb, &mut visited, &mut container);
167
168 Self { container }
170 }
171}
172
173fn run_postorder(bb: BBPtr, visited: &mut HashSet<BBPtr>, container: &mut Vec<BBPtr>) {
175 if visited.contains(&bb) {
176 return;
177 }
178 visited.insert(bb);
179 for succ in bb.get_succ_bb() {
180 run_postorder(*succ, visited, container);
181 }
182 container.push(bb);
183}
184
185#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
186pub struct ParaPtr(ObjPtr<Parameter>);
187impl Display for ParaPtr {
188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189 write!(f, "%{}", self.0.name)
190 }
191}
192impl Deref for ParaPtr {
193 type Target = Parameter;
194 fn deref(&self) -> &Parameter {
195 self.0.as_ref()
196 }
197}
198impl DerefMut for ParaPtr {
199 fn deref_mut(&mut self) -> &mut Self::Target {
200 self.0.as_mut()
201 }
202}
203impl AsRef<Parameter> for ParaPtr {
204 fn as_ref(&self) -> &Parameter {
205 self.0.as_ref()
206 }
207}
208impl From<ObjPtr<Parameter>> for ParaPtr {
209 fn from(ptr: ObjPtr<Parameter>) -> Self {
210 Self(ptr)
211 }
212}
213
214#[derive(Clone)]
215pub struct Parameter {
216 pub name: String,
217 pub value_type: ValueType,
218 user: Vec<InstPtr>,
219}
220
221impl Display for Parameter {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 write!(f, "{} %{}", self.value_type, self.name)
224 }
225}
226
227impl Parameter {
228 pub fn new(name: String, value_type: ValueType) -> Self {
229 Self {
230 name,
231 value_type,
232 user: Vec::new(),
233 }
234 }
235
236 pub fn get_user(&self) -> &[InstPtr] {
237 &self.user
238 }
239 pub fn get_user_mut(&mut self) -> &mut Vec<InstPtr> {
240 &mut self.user
241 }
242 pub unsafe fn add_user(&mut self, inst: InstPtr) {
245 self.user.push(inst);
246 }
247 pub unsafe fn remove_user(&mut self, inst: InstPtr) {
250 self.user
251 .iter()
252 .position(|x| *x == inst)
253 .map(|i| self.user.swap_remove(i));
254 }
255}