1use std::iter::once;
2
3use id_arena::{Arena, Id};
5use sift_trait::Sift;
6use ssa_traits::{op::OpValue, Term};
7use cfg_traits::{Term as CFGTerm};
8
9pub enum Value<O, T, Y> {
10 Op(O, Vec<Id<Value<O, T, Y>>>, Vec<Id<Block<O, T, Y>>>, Y),
11 Param(usize, Id<Block<O, T, Y>>, Y),
12}
13pub struct Block<O, T, Y> {
14 pub term: T,
15 pub insts: Vec<Id<Value<O, T, Y>>>,
16 pub params: Vec<(Y, Id<Value<O, T, Y>>)>,
17}
18pub struct Target<O, T, Y> {
19 pub args: Vec<Id<Value<O, T, Y>>>,
20 pub block: Id<Block<O, T, Y>>,
21}
22pub struct Func<O, T, Y> {
23 pub vals: Arena<Value<O, T, Y>>,
24 pub blocks: Arena<Block<O, T, Y>>,
25 pub entry: Id<Block<O, T, Y>>,
26}
27impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> cfg_traits::Func
28 for Func<O, T, Y>
29{
30
31
32 type Block = Id<Block<O, T, Y>>;
33
34
35
36 type Blocks = Arena<Block<O, T, Y>>;
37
38
39
40 fn blocks(&self) -> &Self::Blocks {
41 &self.blocks
42 }
43
44
45
46 fn blocks_mut(&mut self) -> &mut Self::Blocks {
47 &mut self.blocks
48 }
49
50 fn entry(&self) -> Self::Block {
51 self.entry
52 }
53}
54impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> ssa_traits::Func
55 for Func<O, T, Y>
56{
57 type Value = Id<Value<O, T, Y>>;
58
59
60
61 type Values = Arena<Value<O, T, Y>>;
62
63
64
65 fn values(&self) -> &Self::Values {
66 &self.vals
67 }
68
69
70
71 fn values_mut(&mut self) -> &mut Self::Values {
72 &mut self.vals
73 }
74
75
76}
77impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> ssa_traits::TypedFunc
78 for Func<O, T, Y>
79{
80 type Ty = Y;
81
82 fn add_blockparam(&mut self, k: Self::Block, y: Self::Ty) -> Self::Value {
83 let i = self.blocks[k].params.len();
84 let v = self.vals.alloc(Value::Param(i, k, y.clone()));
85 self.blocks[k].insts = vec![v]
86 .into_iter()
87 .chain(self.blocks[k].insts.iter().map(|a| *a))
88 .collect();
89 self.blocks[k].params.push((y.clone(), v));
90 return v;
91 }
92}
93impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone>
94 ssa_traits::HasValues<Func<O, T, Y>> for Value<O, T, Y>
95{
96 fn values<'a>(
97 &'a self,
98 f: &'a Func<O, T, Y>,
99 ) -> Box<(dyn Iterator<Item = Id<Value<O, T, Y>>> + 'a)> {
100 Box::new(match self {
101 Value::Op(_, a, _, _) => Some(a.iter().cloned()),
102 Value::Param(_, _, _) => None,
103 }
104 .into_iter()
105 .flatten())
106 }
107
108 fn values_mut<'a>(
109 &'a mut self,
110 g: &'a mut Func<O, T, Y>,
111 ) -> Box<(dyn Iterator<Item = &'a mut Id<Value<O, T, Y>>> + 'a)>
112 where
113 Func<O, T, Y>: 'a,
114 {
115 Box::new(match self {
116 Value::Op(_, a, _, _) => Some(a.iter_mut()),
117 Value::Param(_, _, _) => None,
118 }
119 .into_iter()
120 .flatten())
121 }
122}
123
124impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> ssa_traits::Value<Func<O, T, Y>>
125 for Value<O, T, Y>
126{
127}
128
129impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone>
130 ssa_traits::TypedValue<Func<O, T, Y>> for Value<O, T, Y>
131{
132 fn ty(&self, f: &Func<O, T, Y>) -> <Func<O, T, Y> as ssa_traits::TypedFunc>::Ty {
133 match self {
134 Value::Op(_, _, _, y) => y,
135 Value::Param(_, _, y) => y,
136 }
137 .clone()
138 }
139}
140
141impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> cfg_traits::Block<Func<O, T, Y>>
142 for Block<O, T, Y>
143{
144
145
146 type Terminator = T;
147
148 fn term(&self) -> &Self::Terminator {
149 &self.term
150 }
151
152 fn term_mut(&mut self) -> &mut Self::Terminator {
153 &mut self.term
154 }
155}
156
157impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> ssa_traits::Block<Func<O, T, Y>>
158 for Block<O, T, Y>
159{
160 fn insts(&self) -> impl Iterator<Item = <Func<O, T, Y> as ssa_traits::Func>::Value> {
161 self.insts.iter().cloned()
162 }
163
164 fn add_inst(
165 func: &mut Func<O, T, Y>,
166 key: <Func<O, T, Y> as cfg_traits::Func>::Block,
167 v: <Func<O, T, Y> as ssa_traits::Func>::Value,
168 ) {
169 func.blocks[key].insts.push(v);
170 }
171
172}
173
174
175impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone>
176 ssa_traits::TypedBlock<Func<O, T, Y>> for Block<O, T, Y>
177{
178 fn params(
179 &self,
180 ) -> impl Iterator<
181 Item = (
182 <Func<O, T, Y> as ssa_traits::TypedFunc>::Ty,
183 Id<Value<O, T, Y>>,
184 ),
185 > {
186 self.params.iter().cloned()
187 }
188}
189impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone>
190 ssa_traits::HasValues<Func<O, T, Y>> for Target<O, T, Y>
191{
192 fn values<'a>(
193 &'a self,
194 f: &'a Func<O, T, Y>,
195 ) -> Box<(dyn Iterator<Item = Id<Value<O, T, Y>>> + 'a)> {
196 Box::new(self.args.iter().cloned())
197 }
198
199 fn values_mut<'a>(
200 &'a mut self,
201 g: &'a mut Func<O, T, Y>,
202 ) -> Box<(dyn Iterator<Item = &'a mut Id<Value<O, T, Y>>> + 'a)>
203 where
204 Func<O, T, Y>: 'a,
205 {
206 Box::new(self.args.iter_mut())
207 }
208}
209impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone> cfg_traits::Term<Func<O, T, Y>>
210 for Target<O, T, Y>
211{
212 type Target = Self;
213
214 fn targets<'a>(&'a self) -> Box<(dyn Iterator<Item = &'a Target<O, T, Y>> + 'a)>
215 where
216 Func<O, T, Y>: 'a,
217 {
218 Box::new(once(self))
219 }
220
221 fn targets_mut<'a>(&'a mut self) -> Box<(dyn Iterator<Item = &'a mut Target<O, T, Y>> + 'a)>
222 where
223 Func<O, T, Y>: 'a,
224 {
225 Box::new(once(self))
226 }
227}
228impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone>
229 cfg_traits::Target<Func<O, T, Y>> for Target<O, T, Y>
230{
231 fn block(&self) -> <Func<O, T, Y> as cfg_traits::Func>::Block {
232 self.block
233 }
234
235 fn block_mut(&mut self) -> &mut <Func<O, T, Y> as cfg_traits::Func>::Block {
236 &mut self.block
237 }
238
239}
240
241impl<O, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone>
242 ssa_traits::Target<Func<O, T, Y>> for Target<O, T, Y>
243{
244
245 fn push_value(&mut self, v: <Func<O, T, Y> as ssa_traits::Func>::Value) {
246 self.args.push(v);
247 }
248
249 fn from_values_and_block(
250 a: impl Iterator<Item = <Func<O, T, Y> as ssa_traits::Func>::Value>,
251 k: <Func<O, T, Y> as cfg_traits::Func>::Block,
252 ) -> Self {
253 Target {
254 args: a.collect(),
255 block: k,
256 }
257 }
258}
259#[repr(transparent)]
260#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
261pub struct CanonOp<T> {
262 pub op: T,
263}
264impl<O: Sift<X>, T: Term<Func<O, T, Y>, Target = Target<O, T, Y>>, Y: Clone, X>
265 OpValue<Func<O, T, Y>, CanonOp<X>> for Value<O, T, Y>
266{
267 type Residue = Value<<O as Sift<X>>::Residue, T, Y>;
268
269 type Capture = Vec<Id<Value<O, T, Y>>>;
270
271 type Spit = (Y, Vec<Id<Block<O, T, Y>>>);
272
273 fn disasm(
274 self,
275 f: &mut Func<O, T, Y>,
276 ) -> Result<
277 (
278 CanonOp<X>,
279 Vec<Id<Value<O, T, Y>>>,
280 (Y, Vec<Id<Block<O, T, Y>>>),
281 ),
282 Value<<O as Sift<X>>::Residue, T, Y>,
283 > {
284 match self {
285 Value::Op(o, p, q, y) => match o.sift() {
286 Ok(px) => Ok((CanonOp { op: px }, p, (y, q))),
287 Err(r) => Err(Value::Op(
288 r,
289 p.into_iter()
290 .map(|a| unsafe { std::mem::transmute(a) })
291 .collect(),
292 q.into_iter()
293 .map(|a| unsafe { std::mem::transmute(a) })
294 .collect(),
295 y,
296 )),
297 },
298 Value::Param(a, b, c) => Err(Value::Param(a, unsafe { std::mem::transmute(b) }, c)),
299 }
300 }
301
302 fn of(f: &mut Func<O, T, Y>, o: CanonOp<X>, c: Self::Capture, s: Self::Spit) -> Option<Self> {
303 Some(Value::Op(<O as Sift<X>>::of(o.op), c, s.1, s.0))
304 }
305
306 fn lift(f: &mut Func<O, T, Y>, r: Self::Residue) -> Option<Self> {
307 Some(match r {
308 Value::Op(o, p, q, y) => {
309 let r = <O as Sift<X>>::lift(o);
310 Value::Op(
311 r,
312 p.into_iter()
313 .map(|a| unsafe { std::mem::transmute(a) })
314 .collect(),
315 q.into_iter()
316 .map(|a| unsafe { std::mem::transmute(a) })
317 .collect(),
318 y,
319 )
320 }
321 Value::Param(a, b, c) => Value::Param(a, unsafe { std::mem::transmute(b) }, c),
322 })
323 }
324}