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, ¶ms, 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, ¶ms, Self::go, &t)?;
118 }
119 }
120}