final stuff
This commit is contained in:
parent
7cf77d466c
commit
dfc60c46cd
|
@ -9,3 +9,4 @@ 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;
|
|
@ -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();
|
||||||
|
// 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::<Vec<_>>();
|
||||||
|
// 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);
|
// let n = m.funcs.push(n);
|
||||||
let mut b = FunctionBody::new(&m, s);
|
// new.push(n);
|
||||||
let mut p = b.blocks[b.entry]
|
// }
|
||||||
.params
|
// for x in m.exports.iter_mut() {
|
||||||
.iter()
|
// let ExportKind::Func(xf) = &mut x.kind else {
|
||||||
.map(|a| a.1)
|
// continue;
|
||||||
.collect::<Vec<_>>();
|
// };
|
||||||
let vz = b.arg_pool.from_iter(empty());
|
// for (o, n) in v.iter().zip(new.iter()) {
|
||||||
let tz = b.type_pool.from_iter(empty());
|
// if xf == o {
|
||||||
let ti = b.type_pool.from_iter(vec![Type::I32].into_iter());
|
// *xf = *n
|
||||||
let i = b.add_value(ValueDef::Operator(
|
// }
|
||||||
Operator::I32Const { value: l as u32 },
|
// }
|
||||||
vz,
|
// }
|
||||||
ti,
|
return new;
|
||||||
));
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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
129
src/passes/reorder_funs.rs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue