better fusing

This commit is contained in:
Graham Kelly 2024-06-23 13:31:20 -04:00
parent 332a4216e6
commit 4bdc602ef9

View file

@ -1,4 +1,4 @@
use std::{collections::BTreeMap, convert::Infallible, iter::empty}; use std::{collections::BTreeMap, convert::Infallible, iter::{empty, once}};
use anyhow::Context; use anyhow::Context;
// use libc::name_t; // use libc::name_t;
@ -55,7 +55,7 @@ impl Fuse {
target: d, target: d,
}); });
} }
pub fn finalize(self, m: &mut Module) -> Memory{ pub fn finalize(self, m: &mut Module) -> Memory {
let mem = m.memories[self.target].clone(); let mem = m.memories[self.target].clone();
m.memories = EntityVec::default(); m.memories = EntityVec::default();
let new = m.memories.push(mem); let new = m.memories.push(mem);
@ -110,7 +110,7 @@ impl Fuse {
// } // }
return new; return new;
} }
pub fn process(&self, f: &mut FunctionBody) { pub fn process(&self, m: &mut Module, f: &mut FunctionBody) {
let vz = f.arg_pool.from_iter(empty()); let vz = f.arg_pool.from_iter(empty());
let tz = f.type_pool.from_iter(empty()); let tz = f.type_pool.from_iter(empty());
let ti = f.type_pool.from_iter(vec![Type::I32].into_iter()); let ti = f.type_pool.from_iter(vec![Type::I32].into_iter());
@ -123,6 +123,42 @@ impl Fuse {
// let vi = v; // let vi = v;
if let ValueDef::Operator(a, b, c) = &mut w { if let ValueDef::Operator(a, b, c) = &mut w {
let mut bp = f.arg_pool[*b].to_vec(); let mut bp = f.arg_pool[*b].to_vec();
fn g(
a: impl for<'a> FnMut(&mut Module,&mut FunctionBody, Memory, &'a mut crate::Value),
) -> impl for<'a> FnMut(&mut Module,&mut FunctionBody, Memory, &'a mut crate::Value)
{
return a;
}
let mut p = g(|m: &mut Module,f, mem, v| {
match (m.memories[mem].memory64, m.memories[self.target].memory64) {
(true, true) => {}
(true, false) => {
let ti = f.type_pool.from_iter(once(Type::I32));
let w = f.arg_pool.from_iter(vec![*v].into_iter());
let x = f.add_value(ValueDef::Operator(
Operator::I32WrapI64,
w,
ti,
));
f.append_to_block(k, x);
// crate::append_before(f, x, vi, k);
*v = x;
}
(false, true) => {
let ti = f.type_pool.from_iter(once(Type::I64));
let w = f.arg_pool.from_iter(vec![*v].into_iter());
let x = f.add_value(ValueDef::Operator(
Operator::I64ExtendI32U,
w,
ti,
));
f.append_to_block(k, x);
// crate::append_before(f, x, vi, k);
*v = x;
},
(false, false) => {}
}
});
match a.clone() { match a.clone() {
Operator::MemorySize { mem } => { Operator::MemorySize { mem } => {
if mem != self.target { if mem != self.target {
@ -139,6 +175,7 @@ impl Fuse {
function_index: self.size, function_index: self.size,
}; };
bp.push(ia); bp.push(ia);
p(m,f, mem, &mut bp[0]);
} }
} }
Operator::MemoryGrow { mem } => { Operator::MemoryGrow { mem } => {
@ -156,13 +193,14 @@ impl Fuse {
function_index: self.grow, function_index: self.grow,
}; };
bp.push(ia); bp.push(ia);
p(m, f,mem, &mut bp[0]);
} }
} }
_ => crate::op_traits::rewrite_mem(a, &mut bp, |m, v| { _ => crate::op_traits::rewrite_mem(a, &mut bp, |mem, v| {
if *m != self.target{ if *mem != 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: mem.index() as u32,
}, },
vz, vz,
ti, ti,
@ -170,6 +208,7 @@ impl Fuse {
f.append_to_block(k, ia); f.append_to_block(k, ia);
// append_before(f, ia, vi, k); // append_before(f, ia, vi, k);
if let Some(v) = v { if let Some(v) = v {
p(m,f, *mem, &mut *v);
let w = f.arg_pool.from_iter(vec![*v, ia].into_iter()); let w = f.arg_pool.from_iter(vec![*v, ia].into_iter());
let x = f.add_value(ValueDef::Operator( let x = f.add_value(ValueDef::Operator(
Operator::Call { Operator::Call {
@ -182,10 +221,11 @@ impl Fuse {
// crate::append_before(f, x, vi, k); // crate::append_before(f, x, vi, k);
*v = x; *v = x;
} }
*m = self.target; *mem = self.target;
} }
Ok::<(),Infallible>(()) Ok::<(), Infallible>(())
}).unwrap(), })
.unwrap(),
} }
*b = *ka *b = *ka
.entry(bp.clone()) .entry(bp.clone())
@ -201,7 +241,7 @@ pub fn fuse(m: &mut Module) -> anyhow::Result<()> {
let f = Fuse::new(m).context("in getting the fuse funcs")?; let f = Fuse::new(m).context("in getting the fuse funcs")?;
crate::passes::unmem::metafuse_all(m, &mut crate::passes::unmem::All {}); crate::passes::unmem::metafuse_all(m, &mut crate::passes::unmem::All {});
// crate::passes::splice::splice_module(m)?; // crate::passes::splice::splice_module(m)?;
m.per_func_body(|b| f.process(b)); m.take_per_func_body(|m, b| f.process(m, b));
f.finalize(m); f.finalize(m);
return Ok(()); return Ok(());
} }