Skip to main content

ssa_translation/
lib.rs

1#![no_std]
2extern crate alloc;
3
4use core::{
5    ops::{Index, IndexMut},
6};
7use  alloc::{
8    collections::BTreeMap, vec,
9};
10
11
12use arena_traits::{Arena, IndexAlloc};
13use ssa_traits::TypedBlock;
14use ssa_traits::{Block, Func, TypedFunc};
15use cfg_traits::{Block as CFGBlock};
16use valser::{AnyKind, ValSer};
17
18pub mod ai;
19
20pub trait EqIter: IntoIterator + FromIterator<Self::Item> {}
21impl<T: IntoIterator + FromIterator<Self::Item>> EqIter for T {}
22
23pub trait CarryTranslator<F: TypedFunc, G: Func>:
24    Translator<F, G, Meta: ValSer<G::Value>, Instance: EqIter<Item = (F::Ty, <Self::Meta as ValSer<G::Value>>::Kind)>>
25{
26}
27impl<
28        F: TypedFunc,
29        G: Func,
30        X: Translator<F, G, Meta: ValSer<G::Value>, Instance: EqIter<Item = (F::Ty, <Self::Meta as ValSer<G::Value>>::Kind)>>,
31    > CarryTranslator<F, G> for X
32{
33}
34pub trait Translator<F: TypedFunc, G: Func> {
35    type Meta;
36    type Instance;
37    fn add_blockparam(
38        &mut self,
39        i: &mut Self::Instance,
40        g: &mut G,
41        f: &F,
42        k: G::Block,
43        p: F::Ty,
44        i2: usize,
45    ) -> anyhow::Result<(Self::Meta, G::Block)>;
46    fn emit_val<T: AsMut<Self>>(
47        ctx: &mut T,
48        i: &mut Self::Instance,
49        g: &mut G,
50        f: &F,
51        k: G::Block,
52        map: &BTreeMap<F::Value, Self::Meta>,
53        params: &[Self::Meta],
54        go: impl FnMut(&mut T, &mut G, &F, F::Block, Self::Instance) -> anyhow::Result<G::Block>,
55        val: &<F::Values as Index<F::Value>>::Output,
56    ) -> anyhow::Result<(Self::Meta, G::Block)>;
57    fn emit_term<T: AsMut<Self>>(
58        ctx: &mut T,
59        i: &mut Self::Instance,
60        g: &mut G,
61        f: &F,
62        k: G::Block,
63        map: &BTreeMap<F::Value, Self::Meta>,
64        params: &[Self::Meta],
65        go: impl FnMut(&mut T, &mut G, &F, F::Block, Self::Instance) -> anyhow::Result<G::Block>,
66        val: &<<F::Blocks as Index<F::Block>>::Output as CFGBlock<F>>::Terminator,
67    ) -> anyhow::Result<()>;
68}
69pub struct State<F: TypedFunc, G: Func, T: Translator<F, G>> {
70    pub wrapped: T,
71    pub in_map: BTreeMap<(F::Block, T::Instance), G::Block>,
72}
73impl<
74        F: TypedFunc<Block: Ord + Clone, Values: Arena<F::Value, Output: Sized>>,
75        G: Func<Block: Ord + Clone, Blocks: Arena<G::Block, Output: Default>>,
76        T: Translator<F, G, Instance: Ord + Clone>,
77    > AsMut<T> for State<F, G, T>
78{
79    fn as_mut(&mut self) -> &mut T {
80        &mut self.wrapped
81    }
82}
83impl<
84        F: TypedFunc<Block: Ord + Clone, Values: Arena<F::Value, Output: Sized>, Value: Clone + Ord>,
85        G: Func<Block: Ord + Clone, Blocks: Arena<G::Block, Output: Default>>,
86        T: Translator<F, G, Instance: Ord + Clone>,
87    > State<F, G, T>
88{
89    pub fn go(
90        &mut self,
91        g: &mut G,
92        f: &F,
93        b: F::Block,
94        mut i: T::Instance,
95    ) -> anyhow::Result<G::Block> {
96        loop {
97            if let Some(v) = self.in_map.get(&(b.clone(), i.clone())) {
98                return Ok(v.clone());
99            }
100            let mut i = i.clone();
101            let mut v = g.blocks_mut().alloc(Default::default());
102            self.in_map.insert((b.clone(), i.clone()), v.clone());
103            let mut vals = BTreeMap::new();
104            let mut params = vec![];
105            for (i2,(fp, _)) in f.blocks()[b.clone()].params().enumerate() {
106                let val;
107                (val, v) = self.wrapped.add_blockparam(&mut i, g, f, v.clone(), fp,i2)?;
108                params.push(val);
109            }
110            for val2 in f.blocks()[b.clone()].insts() {
111                let w = &f.values()[val2.clone()];
112                let val;
113                (val, v) = T::emit_val(self, &mut i, g, f, v.clone(), &vals, &params, Self::go, w)?;
114                vals.insert(val2, val);
115            }
116            let t = f.blocks()[b.clone()].term();
117            T::emit_term(self, &mut i, g, f, v.clone(), &vals, &params, Self::go, &t)?;
118        }
119    }
120}