final stuff

This commit is contained in:
Graham Kelly 2024-06-03 20:44:09 -04:00
parent 7cf77d466c
commit dfc60c46cd
3 changed files with 194 additions and 51 deletions

View file

@ -8,4 +8,5 @@ pub mod resolve_aliases;
pub mod ssa; pub mod ssa;
pub mod trace; pub mod trace;
pub mod mem_fusing; pub mod mem_fusing;
pub mod unmem; pub mod unmem;
pub mod reorder_funs;

View file

@ -14,6 +14,7 @@ pub struct Fuse {
pub resolve: Func, pub resolve: Func,
pub grow: Func, pub grow: Func,
pub size: Func, pub size: Func,
pub target: Memory,
} }
pub fn get_exports(m: &Module) -> BTreeMap<String, ExportKind> { pub fn get_exports(m: &Module) -> BTreeMap<String, ExportKind> {
let mut b = BTreeMap::new(); let mut b = BTreeMap::new();
@ -43,59 +44,71 @@ impl Fuse {
return None; return None;
}; };
let c = *c; let c = *c;
let Some(ExportKind::Memory(d)) = e.get("memory") else {
return None;
};
let d = *d;
return Some(Fuse { return Some(Fuse {
resolve: a, resolve: a,
grow: b, grow: b,
size: c, size: c,
target: d,
}); });
} }
pub fn finalize(self, m: &mut Module) { pub fn finalize(self, m: &mut Module) -> Memory{
let mem = m.memories[Memory::new(0)].clone(); let mem = m.memories[self.target].clone();
let l = m.memories.len() - 1;
m.memories = EntityVec::default(); m.memories = EntityVec::default();
m.memories.push(mem); let new = m.memories.push(mem);
let v = vec![self.resolve, self.grow, self.size]; let mut fs = BTreeMap::new();
let mut new = vec![]; fs.insert(self.target, new);
for f in v.clone() { crate::passes::reorder_funs::reorder_mems(m, &fs);
let n = m.funcs[f].clone(); // let mem = m.memories[Memory::new(0)].clone();
let s = n.sig(); // let l = m.memories.len() - 1;
let name = n.name().to_owned(); // m.memories = EntityVec::default();
// let n = m.funcs.push(n); // m.memories.push(mem);
let mut b = FunctionBody::new(&m, s); // let v = vec![self.resolve, self.grow, self.size];
let mut p = b.blocks[b.entry] // let mut new = vec![];
.params // for f in v.clone() {
.iter() // let n = m.funcs[f].clone();
.map(|a| a.1) // let s = n.sig();
.collect::<Vec<_>>(); // let name = n.name().to_owned();
let vz = b.arg_pool.from_iter(empty()); // // let n = m.funcs.push(n);
let tz = b.type_pool.from_iter(empty()); // let mut b = FunctionBody::new(&m, s);
let ti = b.type_pool.from_iter(vec![Type::I32].into_iter()); // let mut p = b.blocks[b.entry]
let i = b.add_value(ValueDef::Operator( // .params
Operator::I32Const { value: l as u32 }, // .iter()
vz, // .map(|a| a.1)
ti, // .collect::<Vec<_>>();
)); // let vz = b.arg_pool.from_iter(empty());
b.append_to_block(b.entry, i); // let tz = b.type_pool.from_iter(empty());
let i = b.arg_pool.from_iter(vec![p[p.len() - 1], i].into_iter()); // let ti = b.type_pool.from_iter(vec![Type::I32].into_iter());
let i = b.add_value(ValueDef::Operator(Operator::I32Add, i, ti)); // let i = b.add_value(ValueDef::Operator(
let l = p.len(); // Operator::I32Const { value: l as u32 },
p[l - 1] = i; // vz,
b.append_to_block(b.entry, i); // ti,
b.set_terminator(b.entry, crate::Terminator::ReturnCall { func: f, args: p }); // ));
let n = FuncDecl::Body(s, name, b); // b.append_to_block(b.entry, i);
let n = m.funcs.push(n); // let i = b.arg_pool.from_iter(vec![p[p.len() - 1], i].into_iter());
new.push(n); // let i = b.add_value(ValueDef::Operator(Operator::I32Add, i, ti));
} // let l = p.len();
for x in m.exports.iter_mut() { // p[l - 1] = i;
let ExportKind::Func(xf) = &mut x.kind else { // b.append_to_block(b.entry, i);
continue; // b.set_terminator(b.entry, crate::Terminator::ReturnCall { func: f, args: p });
}; // let n = FuncDecl::Body(s, name, b);
for (o, n) in v.iter().zip(new.iter()) { // let n = m.funcs.push(n);
if xf == o { // new.push(n);
*xf = *n // }
} // for x in m.exports.iter_mut() {
} // let ExportKind::Func(xf) = &mut x.kind else {
} // continue;
// };
// for (o, n) in v.iter().zip(new.iter()) {
// if xf == o {
// *xf = *n
// }
// }
// }
return new;
} }
pub fn process(&self, f: &mut FunctionBody) { pub fn process(&self, f: &mut FunctionBody) {
let vz = f.arg_pool.from_iter(empty()); let vz = f.arg_pool.from_iter(empty());
@ -112,7 +125,7 @@ impl Fuse {
let mut bp = f.arg_pool[*b].to_vec(); let mut bp = f.arg_pool[*b].to_vec();
match a.clone() { match a.clone() {
Operator::MemorySize { mem } => { Operator::MemorySize { mem } => {
if mem.index() != 0 { if mem != self.target {
let ia = f.add_value(ValueDef::Operator( let ia = f.add_value(ValueDef::Operator(
Operator::I32Const { Operator::I32Const {
value: mem.index() as u32, value: mem.index() as u32,
@ -129,7 +142,7 @@ impl Fuse {
} }
} }
Operator::MemoryGrow { mem } => { Operator::MemoryGrow { mem } => {
if mem.index() != 0 { if mem != self.target {
let ia = f.add_value(ValueDef::Operator( let ia = f.add_value(ValueDef::Operator(
Operator::I32Const { Operator::I32Const {
value: mem.index() as u32, value: mem.index() as u32,
@ -146,7 +159,7 @@ impl Fuse {
} }
} }
_ => crate::op_traits::rewrite_mem(a, &mut bp, |m, v| { _ => crate::op_traits::rewrite_mem(a, &mut bp, |m, v| {
if m.index() != 0 { if *m != self.target{
let ia = f.add_value(ValueDef::Operator( let ia = f.add_value(ValueDef::Operator(
Operator::I32Const { Operator::I32Const {
value: m.index() as u32, value: m.index() as u32,
@ -169,7 +182,7 @@ impl Fuse {
// crate::append_before(f, x, vi, k); // crate::append_before(f, x, vi, k);
*v = x; *v = x;
} }
*m = Memory::new(0); *m = self.target;
} }
Ok::<(),Infallible>(()) Ok::<(),Infallible>(())
}).unwrap(), }).unwrap(),

129
src/passes/reorder_funs.rs Normal file
View file

@ -0,0 +1,129 @@
use std::collections::BTreeMap;
use std::convert::Infallible;
use crate::{
entity::EntityRef, ExportKind, Func, FuncDecl, FunctionBody, ImportKind, Memory, Module,
Operator, Terminator, ValueDef,
};
use crate::op_traits::rewrite_mem;
pub fn reorder_funcs_in_body(b: &mut FunctionBody, f: &BTreeMap<Func, Func>) {
for v in b.values.values_mut() {
if let ValueDef::Operator(a, _, _) = v {
if let Operator::Call { function_index } = a {
*function_index = *f.get(&*function_index).unwrap();
}
}
}
for k in b.blocks.values_mut() {
if let Terminator::ReturnCall { func, args } = &mut k.terminator {
*func = *f.get(&*func).unwrap();
}
}
}
pub fn reorder_funcs(m: &mut Module, fs: &BTreeMap<Func, Func>) {
let mut n = m.funcs.clone();
for (f, b) in m.funcs.entries() {
let mut b = b.clone();
if let Some(b) = b.body_mut() {
reorder_funcs_in_body(b, fs);
}
n[*fs.get(&f).unwrap()] = b;
}
m.funcs = n;
for t in m.tables.values_mut() {
if let Some(e) = t.func_elements.as_mut() {
for e in e.iter_mut() {
let Some(f) = fs.get(&*e) else {
let f = *e;
panic!("invalid func: {f}; {}", m.funcs[f].name())
};
*e = *f;
}
}
}
for i in m.imports.iter_mut() {
if let ImportKind::Func(f) = &mut i.kind {
*f = *fs.get(&*f).unwrap();
}
}
for i in m.exports.iter_mut() {
if let ExportKind::Func(f) = &mut i.kind {
*f = *fs.get(&*f).unwrap();
}
}
}
pub fn fixup_orders(m: &mut Module) {
let mut fs = BTreeMap::new();
let mut a = vec![];
let mut b = vec![];
for (f, d) in m.funcs.entries() {
if let FuncDecl::Import(_, _) = d {
a.push(f)
} else {
b.push(f)
}
}
let mut i = 0;
for v in a {
fs.insert(v, Func::new(i));
i += 1;
}
for v in b {
fs.insert(v, Func::new(i));
i += 1;
}
assert_eq!(fs.len(), m.funcs.len());
fs.insert(Func::invalid(), Func::invalid());
reorder_funcs(m, &fs);
return;
}
pub fn fixup_mem_orders(m: &mut Module) {
let mut fs = BTreeMap::new();
let mut a = vec![];
let mut b = vec![];
for (f, d) in m.memories.entries() {
let mut c = false;
for i in m.imports.iter() {
if i.kind == ImportKind::Memory(f) {
c = true
}
}
if c {
a.push(f)
} else {
b.push(f)
}
}
let mut i = 0;
for v in a {
fs.insert(v, Memory::new(i));
i += 1;
}
for v in b {
fs.insert(v, Memory::new(i));
i += 1;
}
reorder_mems(m, &fs);
}
pub fn reorder_mems(m: &mut Module, fs: &BTreeMap<Memory, Memory>) {
for f in m.funcs.values_mut() {
if let Some(b) = f.body_mut() {
for v in b.values.values_mut() {
if let ValueDef::Operator(a, _, _) = v {
let mut w = [(); 4];
rewrite_mem(a, &mut w, |m, _| {
*m = fs.get(m).copied().unwrap();
Ok::<(), Infallible>(())
})
.unwrap()
}
}
}
}
let mes = m.memories.clone();
for (f, g) in fs.iter() {
m.memories[*g] = mes[*f].clone();
}
}