This commit is contained in:
Graham Kelly 2024-01-20 09:42:01 -05:00
parent 8b32f7a07e
commit bd6ae8eb8d
9 changed files with 124 additions and 72 deletions

View file

@ -171,7 +171,7 @@ impl<'a> WasmFuncBackend<'a> {
} }
func.instruction(&wasm_encoder::Instruction::Return); func.instruction(&wasm_encoder::Instruction::Return);
} }
WasmBlock::ReturnCall { func: f,values } => { WasmBlock::ReturnCall { func: f, values } => {
for &value in &values[..] { for &value in &values[..] {
self.lower_value(value, func); self.lower_value(value, func);
} }
@ -181,7 +181,10 @@ impl<'a> WasmFuncBackend<'a> {
for &value in &values[..] { for &value in &values[..] {
self.lower_value(value, func); self.lower_value(value, func);
} }
func.instruction(&wasm_encoder::Instruction::ReturnCallIndirect { ty: sig.index() as u32, table: table.index() as u32 }); func.instruction(&wasm_encoder::Instruction::ReturnCallIndirect {
ty: sig.index() as u32,
table: table.index() as u32,
});
} }
WasmBlock::Unreachable => { WasmBlock::Unreachable => {
func.instruction(&wasm_encoder::Instruction::Unreachable); func.instruction(&wasm_encoder::Instruction::Unreachable);

View file

@ -9,10 +9,10 @@
//! //!
//! for more details on how this algorithm works. //! for more details on how this algorithm works.
use crate::{Func, Signature, Table};
use crate::cfg::CFGInfo; use crate::cfg::CFGInfo;
use crate::entity::EntityRef; use crate::entity::EntityRef;
use crate::ir::{Block, BlockTarget, FunctionBody, Terminator, Type, Value}; use crate::ir::{Block, BlockTarget, FunctionBody, Terminator, Type, Value};
use crate::{Func, Signature, Table};
use std::collections::HashSet; use std::collections::HashSet;
use std::convert::TryFrom; use std::convert::TryFrom;
@ -31,9 +31,13 @@ pub enum WasmBlock<'a> {
header: Block, header: Block,
}, },
/// A leaf node: one CFG block. /// A leaf node: one CFG block.
Leaf { block: Block }, Leaf {
block: Block,
},
/// A translated unconditional branch. /// A translated unconditional branch.
Br { target: WasmLabel }, Br {
target: WasmLabel,
},
/// A translated conditional. /// A translated conditional.
If { If {
cond: Value, cond: Value,
@ -52,9 +56,18 @@ pub enum WasmBlock<'a> {
to: &'a [(Type, Value)], to: &'a [(Type, Value)],
}, },
/// A function return instruction. /// A function return instruction.
Return { values: &'a [Value] }, Return {
ReturnCall { func: Func,values: &'a [Value] }, values: &'a [Value],
ReturnCallIndirect { sig: Signature,table: Table,values: &'a [Value] }, },
ReturnCall {
func: Func,
values: &'a [Value],
},
ReturnCallIndirect {
sig: Signature,
table: Table,
values: &'a [Value],
},
/// An unreachable instruction. /// An unreachable instruction.
Unreachable, Unreachable,
} }
@ -445,11 +458,20 @@ impl<'a, 'b> Context<'a, 'b> {
into.push(WasmBlock::Unreachable); into.push(WasmBlock::Unreachable);
} }
&Terminator::ReturnCall { func, ref args } => { &Terminator::ReturnCall { func, ref args } => {
into.push(WasmBlock::ReturnCall { func: func, values: args }); into.push(WasmBlock::ReturnCall {
} func: func,
&Terminator::ReturnCallIndirect { sig, table, ref args } => { values: args,
into.push(WasmBlock::ReturnCallIndirect { sig, table, values: args }) });
} }
&Terminator::ReturnCallIndirect {
sig,
table,
ref args,
} => into.push(WasmBlock::ReturnCallIndirect {
sig,
table,
values: args,
}),
} }
} }
} }

View file

@ -1233,13 +1233,27 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
wasmparser::Operator::ReturnCall { function_index } => { wasmparser::Operator::ReturnCall { function_index } => {
let sig = self.module.funcs[Func::new(*function_index as usize)].sig(); let sig = self.module.funcs[Func::new(*function_index as usize)].sig();
let retvals = self.pop_n(self.module.signatures[sig].params.len()); let retvals = self.pop_n(self.module.signatures[sig].params.len());
self.emit_term(Terminator::ReturnCall { func: Func::new(*function_index as usize), args: retvals }); self.emit_term(Terminator::ReturnCall {
func: Func::new(*function_index as usize),
args: retvals,
});
self.reachable = false; self.reachable = false;
} }
wasmparser::Operator::ReturnCallIndirect { type_index, table_index } => { wasmparser::Operator::ReturnCallIndirect {
type_index,
table_index,
} => {
// let sig = self.module.funcs[Func::new(*function_index as usize)].sig(); // let sig = self.module.funcs[Func::new(*function_index as usize)].sig();
let retvals = self.pop_n(self.module.signatures[Signature::new(*type_index as usize)].params.len()); let retvals = self.pop_n(
self.emit_term(Terminator::ReturnCallIndirect { sig: Signature::new(*type_index as usize), table: Table::new(*table_index as usize),args: retvals }); self.module.signatures[Signature::new(*type_index as usize)]
.params
.len(),
);
self.emit_term(Terminator::ReturnCallIndirect {
sig: Signature::new(*type_index as usize),
table: Table::new(*table_index as usize),
args: retvals,
});
self.reachable = false; self.reachable = false;
} }
@ -1659,7 +1673,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
} }
} }
fn emit_term(&mut self, t: Terminator){ fn emit_term(&mut self, t: Terminator) {
log::trace!( log::trace!(
"emit_term: cur_block {} reachable {} terminator {:?}", "emit_term: cur_block {} reachable {} terminator {:?}",
self.cur_block, self.cur_block,
@ -1668,8 +1682,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
); );
if self.reachable { if self.reachable {
// let values = values.to_vec(); // let values = values.to_vec();
self.body self.body.set_terminator(self.cur_block, t);
.set_terminator(self.cur_block,t);
self.reachable = false; self.reachable = false;
} }
} }

View file

@ -227,7 +227,11 @@ impl InterpContext {
} }
match &body.blocks[frame.cur_block].terminator { match &body.blocks[frame.cur_block].terminator {
&Terminator::ReturnCallIndirect { sig, table, ref args } => { &Terminator::ReturnCallIndirect {
sig,
table,
ref args,
} => {
let args = args let args = args
.iter() .iter()
.map(|&arg| { .map(|&arg| {

View file

@ -1,11 +1,11 @@
use super::{Block, FunctionBodyDisplay, Local, Module, Signature, Type, Value, ValueDef}; use super::{Block, FunctionBodyDisplay, Local, Module, Signature, Type, Value, ValueDef};
use crate::{Func, Table};
use crate::backend::WasmFuncBackend; use crate::backend::WasmFuncBackend;
use crate::cfg::CFGInfo; use crate::cfg::CFGInfo;
use crate::entity::{EntityRef, EntityVec, PerEntity}; use crate::entity::{EntityRef, EntityVec, PerEntity};
use crate::frontend::parse_body; use crate::frontend::parse_body;
use crate::ir::SourceLoc; use crate::ir::SourceLoc;
use crate::pool::{ListPool, ListRef}; use crate::pool::{ListPool, ListRef};
use crate::{Func, Table};
use anyhow::Result; use anyhow::Result;
use fxhash::FxHashMap; use fxhash::FxHashMap;
use std::collections::HashSet; use std::collections::HashSet;
@ -595,8 +595,7 @@ impl std::fmt::Display for Terminator {
f, f,
"return_call {}({})", "return_call {}({})",
func, func,
args args.iter()
.iter()
.map(|val| format!("{}", val)) .map(|val| format!("{}", val))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
@ -604,9 +603,9 @@ impl std::fmt::Display for Terminator {
Terminator::ReturnCallIndirect { sig, table, args } => write!( Terminator::ReturnCallIndirect { sig, table, args } => write!(
f, f,
"return_call_indirect ({};{})({})", "return_call_indirect ({};{})({})",
sig,table, sig,
args table,
.iter() args.iter()
.map(|val| format!("{}", val)) .map(|val| format!("{}", val))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
@ -641,8 +640,8 @@ impl Terminator {
} }
Terminator::None => {} Terminator::None => {}
Terminator::Unreachable => {} Terminator::Unreachable => {}
Terminator::ReturnCall { func, args } =>{}, Terminator::ReturnCall { func, args } => {}
Terminator::ReturnCallIndirect { sig, table, args } => {}, Terminator::ReturnCallIndirect { sig, table, args } => {}
} }
} }
@ -670,8 +669,8 @@ impl Terminator {
} }
Terminator::None => {} Terminator::None => {}
Terminator::Unreachable => {} Terminator::Unreachable => {}
Terminator::ReturnCall { func, args } =>{}, Terminator::ReturnCall { func, args } => {}
Terminator::ReturnCallIndirect { sig, table, args } => {}, Terminator::ReturnCallIndirect { sig, table, args } => {}
} }
} }
@ -752,15 +751,19 @@ impl Terminator {
} }
} }
&Terminator::ReturnCall { func, ref args } => { &Terminator::ReturnCall { func, ref args } => {
for value in args{ for value in args {
f(*value); f(*value);
} }
} }
&Terminator::ReturnCallIndirect { sig, table, ref args } => { &Terminator::ReturnCallIndirect {
for value in args{ sig,
table,
ref args,
} => {
for value in args {
f(*value); f(*value);
} }
}, }
_ => {} _ => {}
} }
} }
@ -780,15 +783,19 @@ impl Terminator {
} }
} }
&mut Terminator::ReturnCall { func, ref mut args } => { &mut Terminator::ReturnCall { func, ref mut args } => {
for value in args{ for value in args {
f(value); f(value);
} }
} }
&mut Terminator::ReturnCallIndirect { sig, table, ref mut args } => { &mut Terminator::ReturnCallIndirect {
for value in args{ sig,
table,
ref mut args,
} => {
for value in args {
f(value); f(value);
} }
}, }
_ => {} _ => {}
} }
} }

View file

@ -24,7 +24,7 @@ pub fn op_inputs(
} }
&Operator::Select => { &Operator::Select => {
let Some(op_stack) = op_stack else{ let Some(op_stack) = op_stack else {
anyhow::bail!("selects cannot be typed with no stack"); anyhow::bail!("selects cannot be typed with no stack");
}; };
let val_ty = op_stack[op_stack.len() - 2].0; let val_ty = op_stack[op_stack.len() - 2].0;
@ -246,7 +246,7 @@ pub fn op_outputs(
} }
&Operator::Select => { &Operator::Select => {
let Some(op_stack) = op_stack else{ let Some(op_stack) = op_stack else {
anyhow::bail!("selects cannot be typed with no stack"); anyhow::bail!("selects cannot be typed with no stack");
}; };
let val_ty = op_stack[op_stack.len() - 2].0; let val_ty = op_stack[op_stack.len() - 2].0;

View file

@ -579,9 +579,9 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
dst_mem: Memory::from(dst_mem), dst_mem: Memory::from(dst_mem),
src_mem: Memory::from(src_mem), src_mem: Memory::from(src_mem),
}), }),
&wasmparser::Operator::MemoryFill { mem } => { &wasmparser::Operator::MemoryFill { mem } => Ok(Operator::MemoryFill {
Ok(Operator::MemoryFill { mem: Memory::from(mem) }) mem: Memory::from(mem),
} }),
_ => Err(()), _ => Err(()),
} }
} }

View file

@ -5,7 +5,7 @@ pub mod dom_pass;
pub mod empty_blocks; pub mod empty_blocks;
pub mod maxssa; pub mod maxssa;
pub mod remove_phis; pub mod remove_phis;
pub mod reorder_funs;
pub mod resolve_aliases; pub mod resolve_aliases;
pub mod ssa; pub mod ssa;
pub mod trace; pub mod trace;
pub mod reorder_funs;

View file

@ -1,6 +1,9 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use crate::{ExportKind, Func, FuncDecl, FunctionBody, ImportKind, Module, Operator, ValueDef, entity::EntityRef, Terminator}; use crate::{
entity::EntityRef, ExportKind, Func, FuncDecl, FunctionBody, ImportKind, Module, Operator,
Terminator, ValueDef,
};
pub fn reorder_funcs_in_body(b: &mut FunctionBody, f: &BTreeMap<Func, Func>) { pub fn reorder_funcs_in_body(b: &mut FunctionBody, f: &BTreeMap<Func, Func>) {
for v in b.values.values_mut() { for v in b.values.values_mut() {
@ -10,8 +13,8 @@ pub fn reorder_funcs_in_body(b: &mut FunctionBody, f: &BTreeMap<Func, Func>) {
} }
} }
} }
for k in b.blocks.values_mut(){ for k in b.blocks.values_mut() {
if let Terminator::ReturnCall { func, args } = &mut k.terminator{ if let Terminator::ReturnCall { func, args } = &mut k.terminator {
*func = *f.get(&*func).unwrap(); *func = *f.get(&*func).unwrap();
} }
} }
@ -56,11 +59,11 @@ pub fn fixup_orders(m: &mut Module) {
} }
} }
let mut i = 0; let mut i = 0;
for v in a{ for v in a {
fs.insert(v, Func::new(i)); fs.insert(v, Func::new(i));
i += 1; i += 1;
} }
for v in b{ for v in b {
fs.insert(v, Func::new(i)); fs.insert(v, Func::new(i));
i += 1; i += 1;
} }