ssa_canon/
lib.rs

1use std::iter::once;
2
3// use anyhow::Ok;
4use 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}