From dfc60c46cdcdaadef6b052c445943917249bd0fb Mon Sep 17 00:00:00 2001 From: Graham Kelly Date: Mon, 3 Jun 2024 20:44:09 -0400 Subject: [PATCH] final stuff --- src/passes.rs | 3 +- src/passes/mem_fusing.rs | 113 ++++++++++++++++++-------------- src/passes/reorder_funs.rs | 129 +++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 51 deletions(-) create mode 100644 src/passes/reorder_funs.rs diff --git a/src/passes.rs b/src/passes.rs index 126ab14..1e83eff 100644 --- a/src/passes.rs +++ b/src/passes.rs @@ -8,4 +8,5 @@ pub mod resolve_aliases; pub mod ssa; pub mod trace; pub mod mem_fusing; -pub mod unmem; \ No newline at end of file +pub mod unmem; +pub mod reorder_funs; \ No newline at end of file diff --git a/src/passes/mem_fusing.rs b/src/passes/mem_fusing.rs index 0838710..b54ec01 100644 --- a/src/passes/mem_fusing.rs +++ b/src/passes/mem_fusing.rs @@ -14,6 +14,7 @@ pub struct Fuse { pub resolve: Func, pub grow: Func, pub size: Func, + pub target: Memory, } pub fn get_exports(m: &Module) -> BTreeMap { let mut b = BTreeMap::new(); @@ -43,59 +44,71 @@ impl Fuse { return None; }; let c = *c; + let Some(ExportKind::Memory(d)) = e.get("memory") else { + return None; + }; + let d = *d; return Some(Fuse { resolve: a, grow: b, size: c, + target: d, }); } - pub fn finalize(self, m: &mut Module) { - let mem = m.memories[Memory::new(0)].clone(); - let l = m.memories.len() - 1; + pub fn finalize(self, m: &mut Module) -> Memory{ + let mem = m.memories[self.target].clone(); m.memories = EntityVec::default(); - m.memories.push(mem); - let v = vec![self.resolve, self.grow, self.size]; - let mut new = vec![]; - for f in v.clone() { - let n = m.funcs[f].clone(); - let s = n.sig(); - let name = n.name().to_owned(); - // let n = m.funcs.push(n); - let mut b = FunctionBody::new(&m, s); - let mut p = b.blocks[b.entry] - .params - .iter() - .map(|a| a.1) - .collect::>(); - let vz = b.arg_pool.from_iter(empty()); - let tz = b.type_pool.from_iter(empty()); - let ti = b.type_pool.from_iter(vec![Type::I32].into_iter()); - let i = b.add_value(ValueDef::Operator( - Operator::I32Const { value: l as u32 }, - vz, - ti, - )); - b.append_to_block(b.entry, i); - let i = b.arg_pool.from_iter(vec![p[p.len() - 1], i].into_iter()); - let i = b.add_value(ValueDef::Operator(Operator::I32Add, i, ti)); - let l = p.len(); - p[l - 1] = i; - b.append_to_block(b.entry, i); - b.set_terminator(b.entry, crate::Terminator::ReturnCall { func: f, args: p }); - let n = FuncDecl::Body(s, name, b); - let n = m.funcs.push(n); - new.push(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 - } - } - } + let new = m.memories.push(mem); + let mut fs = BTreeMap::new(); + fs.insert(self.target, new); + crate::passes::reorder_funs::reorder_mems(m, &fs); + // let mem = m.memories[Memory::new(0)].clone(); + // let l = m.memories.len() - 1; + // m.memories = EntityVec::default(); + // m.memories.push(mem); + // let v = vec![self.resolve, self.grow, self.size]; + // let mut new = vec![]; + // for f in v.clone() { + // let n = m.funcs[f].clone(); + // let s = n.sig(); + // let name = n.name().to_owned(); + // // let n = m.funcs.push(n); + // let mut b = FunctionBody::new(&m, s); + // let mut p = b.blocks[b.entry] + // .params + // .iter() + // .map(|a| a.1) + // .collect::>(); + // let vz = b.arg_pool.from_iter(empty()); + // let tz = b.type_pool.from_iter(empty()); + // let ti = b.type_pool.from_iter(vec![Type::I32].into_iter()); + // let i = b.add_value(ValueDef::Operator( + // Operator::I32Const { value: l as u32 }, + // vz, + // ti, + // )); + // b.append_to_block(b.entry, i); + // let i = b.arg_pool.from_iter(vec![p[p.len() - 1], i].into_iter()); + // let i = b.add_value(ValueDef::Operator(Operator::I32Add, i, ti)); + // let l = p.len(); + // p[l - 1] = i; + // b.append_to_block(b.entry, i); + // b.set_terminator(b.entry, crate::Terminator::ReturnCall { func: f, args: p }); + // let n = FuncDecl::Body(s, name, b); + // let n = m.funcs.push(n); + // new.push(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) { let vz = f.arg_pool.from_iter(empty()); @@ -112,7 +125,7 @@ impl Fuse { let mut bp = f.arg_pool[*b].to_vec(); match a.clone() { Operator::MemorySize { mem } => { - if mem.index() != 0 { + if mem != self.target { let ia = f.add_value(ValueDef::Operator( Operator::I32Const { value: mem.index() as u32, @@ -129,7 +142,7 @@ impl Fuse { } } Operator::MemoryGrow { mem } => { - if mem.index() != 0 { + if mem != self.target { let ia = f.add_value(ValueDef::Operator( Operator::I32Const { value: mem.index() as u32, @@ -146,7 +159,7 @@ impl Fuse { } } _ => 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( Operator::I32Const { value: m.index() as u32, @@ -169,7 +182,7 @@ impl Fuse { // crate::append_before(f, x, vi, k); *v = x; } - *m = Memory::new(0); + *m = self.target; } Ok::<(),Infallible>(()) }).unwrap(), diff --git a/src/passes/reorder_funs.rs b/src/passes/reorder_funs.rs new file mode 100644 index 0000000..cf02a06 --- /dev/null +++ b/src/passes/reorder_funs.rs @@ -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) { + 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) { + 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) { + 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(); + } +}