WIP.
This commit is contained in:
parent
e6c44bbf7d
commit
43bdb36952
|
@ -1320,7 +1320,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
let n_outputs = outputs.len();
|
let n_outputs = outputs.len();
|
||||||
|
|
||||||
let mut input_operands = vec![];
|
let mut input_operands = vec![];
|
||||||
for input in inputs.into_iter().rev() {
|
for &input in inputs.into_iter().rev() {
|
||||||
let (stack_top_ty, stack_top) = self.op_stack.pop().unwrap();
|
let (stack_top_ty, stack_top) = self.op_stack.pop().unwrap();
|
||||||
assert_eq!(stack_top_ty, input);
|
assert_eq!(stack_top_ty, input);
|
||||||
input_operands.push(stack_top);
|
input_operands.push(stack_top);
|
||||||
|
@ -1331,7 +1331,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
|
|
||||||
let value = self
|
let value = self
|
||||||
.body
|
.body
|
||||||
.add_value(ValueDef::Operator(op, input_operands, outputs.clone()));
|
.add_value(ValueDef::Operator(op, input_operands, outputs.to_vec()));
|
||||||
log::trace!(" -> value: {:?}", value);
|
log::trace!(" -> value: {:?}", value);
|
||||||
|
|
||||||
if let Some(block) = self.cur_block {
|
if let Some(block) = self.cur_block {
|
||||||
|
@ -1342,7 +1342,7 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
let output_ty = outputs[0];
|
let output_ty = outputs[0];
|
||||||
self.op_stack.push((output_ty, value));
|
self.op_stack.push((output_ty, value));
|
||||||
} else {
|
} else {
|
||||||
for (i, output_ty) in outputs.into_iter().enumerate() {
|
for (i, &output_ty) in outputs.into_iter().enumerate() {
|
||||||
let pick = self
|
let pick = self
|
||||||
.body
|
.body
|
||||||
.add_value(ValueDef::PickOutput(value, i, output_ty));
|
.add_value(ValueDef::PickOutput(value, i, output_ty));
|
||||||
|
|
|
@ -13,6 +13,7 @@ mod ir;
|
||||||
mod op_traits;
|
mod op_traits;
|
||||||
mod ops;
|
mod ops;
|
||||||
pub mod passes;
|
pub mod passes;
|
||||||
|
mod scoped_map;
|
||||||
|
|
||||||
pub use ir::*;
|
pub use ir::*;
|
||||||
pub use ops::Operator;
|
pub use ops::Operator;
|
||||||
|
|
455
src/op_traits.rs
455
src/op_traits.rs
|
@ -4,6 +4,7 @@ use crate::entity::EntityVec;
|
||||||
use crate::ir::{Global, Local, Module, Signature, Table, Type, Value};
|
use crate::ir::{Global, Local, Module, Signature, Table, Type, Value};
|
||||||
use crate::Operator;
|
use crate::Operator;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
pub fn op_inputs(
|
pub fn op_inputs(
|
||||||
module: &Module,
|
module: &Module,
|
||||||
|
@ -11,34 +12,34 @@ pub fn op_inputs(
|
||||||
my_locals: &EntityVec<Local, Type>,
|
my_locals: &EntityVec<Local, Type>,
|
||||||
op_stack: &[(Type, Value)],
|
op_stack: &[(Type, Value)],
|
||||||
op: &Operator,
|
op: &Operator,
|
||||||
) -> Result<Vec<Type>> {
|
) -> Result<Cow<'static, [Type]>> {
|
||||||
match op {
|
match op {
|
||||||
&Operator::Unreachable | &Operator::Nop => Ok(vec![]),
|
&Operator::Unreachable | &Operator::Nop => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
&Operator::Call { function_index } => {
|
&Operator::Call { function_index } => {
|
||||||
let sig = module.func(function_index).sig();
|
let sig = module.func(function_index).sig();
|
||||||
Ok(Vec::from(module.signature(sig).params.clone()))
|
Ok(Vec::from(module.signature(sig).params.clone()).into())
|
||||||
}
|
}
|
||||||
&Operator::CallIndirect { sig_index, .. } => {
|
&Operator::CallIndirect { sig_index, .. } => {
|
||||||
let mut params = module.signature(sig_index).params.to_vec();
|
let mut params = module.signature(sig_index).params.to_vec();
|
||||||
params.push(Type::I32);
|
params.push(Type::I32);
|
||||||
Ok(params)
|
Ok(params.into())
|
||||||
}
|
}
|
||||||
&Operator::Return => Ok(Vec::from(module.signature(my_sig).returns.clone())),
|
&Operator::Return => Ok(Vec::from(module.signature(my_sig).returns.clone()).into()),
|
||||||
|
|
||||||
&Operator::LocalSet { local_index } | &Operator::LocalTee { local_index } => {
|
&Operator::LocalSet { local_index } | &Operator::LocalTee { local_index } => {
|
||||||
Ok(vec![my_locals[local_index]])
|
Ok(vec![my_locals[local_index]].into())
|
||||||
}
|
}
|
||||||
&Operator::LocalGet { .. } => Ok(vec![]),
|
&Operator::LocalGet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
&Operator::Select => {
|
&Operator::Select => {
|
||||||
let val_ty = op_stack[op_stack.len() - 2].0;
|
let val_ty = op_stack[op_stack.len() - 2].0;
|
||||||
Ok(vec![val_ty, val_ty, Type::I32])
|
Ok(vec![val_ty, val_ty, Type::I32].into())
|
||||||
}
|
}
|
||||||
&Operator::TypedSelect { ty } => Ok(vec![ty, ty, Type::I32]),
|
&Operator::TypedSelect { ty } => Ok(vec![ty, ty, Type::I32].into()),
|
||||||
|
|
||||||
&Operator::GlobalGet { .. } => Ok(vec![]),
|
&Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
&Operator::GlobalSet { global_index } => Ok(vec![module.global_ty(global_index)]),
|
&Operator::GlobalSet { global_index } => Ok(vec![module.global_ty(global_index)].into()),
|
||||||
|
|
||||||
Operator::I32Load { .. }
|
Operator::I32Load { .. }
|
||||||
| Operator::I64Load { .. }
|
| Operator::I64Load { .. }
|
||||||
|
@ -53,24 +54,24 @@ pub fn op_inputs(
|
||||||
| Operator::I64Load16S { .. }
|
| Operator::I64Load16S { .. }
|
||||||
| Operator::I64Load16U { .. }
|
| Operator::I64Load16U { .. }
|
||||||
| Operator::I64Load32S { .. }
|
| Operator::I64Load32S { .. }
|
||||||
| Operator::I64Load32U { .. } => Ok(vec![Type::I32]),
|
| Operator::I64Load32U { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
|
|
||||||
Operator::I32Store { .. } => Ok(vec![Type::I32, Type::I32]),
|
Operator::I32Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])),
|
||||||
Operator::I64Store { .. } => Ok(vec![Type::I32, Type::I64]),
|
Operator::I64Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])),
|
||||||
Operator::F32Store { .. } => Ok(vec![Type::I32, Type::F32]),
|
Operator::F32Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::F32])),
|
||||||
Operator::F64Store { .. } => Ok(vec![Type::I32, Type::F64]),
|
Operator::F64Store { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::F64])),
|
||||||
Operator::I32Store8 { .. } => Ok(vec![Type::I32, Type::I32]),
|
Operator::I32Store8 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])),
|
||||||
Operator::I32Store16 { .. } => Ok(vec![Type::I32, Type::I32]),
|
Operator::I32Store16 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I32])),
|
||||||
Operator::I64Store8 { .. } => Ok(vec![Type::I32, Type::I64]),
|
Operator::I64Store8 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])),
|
||||||
Operator::I64Store16 { .. } => Ok(vec![Type::I32, Type::I64]),
|
Operator::I64Store16 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])),
|
||||||
Operator::I64Store32 { .. } => Ok(vec![Type::I32, Type::I64]),
|
Operator::I64Store32 { .. } => Ok(Cow::Borrowed(&[Type::I32, Type::I64])),
|
||||||
|
|
||||||
Operator::I32Const { .. }
|
Operator::I32Const { .. }
|
||||||
| Operator::I64Const { .. }
|
| Operator::I64Const { .. }
|
||||||
| Operator::F32Const { .. }
|
| Operator::F32Const { .. }
|
||||||
| Operator::F64Const { .. } => Ok(vec![]),
|
| Operator::F64Const { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32Eqz => Ok(vec![Type::I32]),
|
Operator::I32Eqz => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32Eq
|
Operator::I32Eq
|
||||||
| Operator::I32Ne
|
| Operator::I32Ne
|
||||||
| Operator::I32LtS
|
| Operator::I32LtS
|
||||||
|
@ -80,9 +81,9 @@ pub fn op_inputs(
|
||||||
| Operator::I32LeS
|
| Operator::I32LeS
|
||||||
| Operator::I32LeU
|
| Operator::I32LeU
|
||||||
| Operator::I32GeS
|
| Operator::I32GeS
|
||||||
| Operator::I32GeU => Ok(vec![Type::I32, Type::I32]),
|
| Operator::I32GeU => Ok(Cow::Borrowed(&[Type::I32, Type::I32])),
|
||||||
|
|
||||||
Operator::I64Eqz => Ok(vec![Type::I64]),
|
Operator::I64Eqz => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
|
|
||||||
Operator::I64Eq
|
Operator::I64Eq
|
||||||
| Operator::I64Ne
|
| Operator::I64Ne
|
||||||
|
@ -93,23 +94,25 @@ pub fn op_inputs(
|
||||||
| Operator::I64LeS
|
| Operator::I64LeS
|
||||||
| Operator::I64LeU
|
| Operator::I64LeU
|
||||||
| Operator::I64GeS
|
| Operator::I64GeS
|
||||||
| Operator::I64GeU => Ok(vec![Type::I64, Type::I64]),
|
| Operator::I64GeU => Ok(Cow::Borrowed(&[Type::I64, Type::I64])),
|
||||||
|
|
||||||
Operator::F32Eq
|
Operator::F32Eq
|
||||||
| Operator::F32Ne
|
| Operator::F32Ne
|
||||||
| Operator::F32Lt
|
| Operator::F32Lt
|
||||||
| Operator::F32Gt
|
| Operator::F32Gt
|
||||||
| Operator::F32Le
|
| Operator::F32Le
|
||||||
| Operator::F32Ge => Ok(vec![Type::F32, Type::F32]),
|
| Operator::F32Ge => Ok(Cow::Borrowed(&[Type::F32, Type::F32])),
|
||||||
|
|
||||||
Operator::F64Eq
|
Operator::F64Eq
|
||||||
| Operator::F64Ne
|
| Operator::F64Ne
|
||||||
| Operator::F64Lt
|
| Operator::F64Lt
|
||||||
| Operator::F64Gt
|
| Operator::F64Gt
|
||||||
| Operator::F64Le
|
| Operator::F64Le
|
||||||
| Operator::F64Ge => Ok(vec![Type::F64, Type::F64]),
|
| Operator::F64Ge => Ok(Cow::Borrowed(&[Type::F64, Type::F64])),
|
||||||
|
|
||||||
Operator::I32Clz | Operator::I32Ctz | Operator::I32Popcnt => Ok(vec![Type::I32]),
|
Operator::I32Clz | Operator::I32Ctz | Operator::I32Popcnt => {
|
||||||
|
Ok(Cow::Borrowed(&[Type::I32]))
|
||||||
|
}
|
||||||
|
|
||||||
Operator::I32Add
|
Operator::I32Add
|
||||||
| Operator::I32Sub
|
| Operator::I32Sub
|
||||||
|
@ -125,9 +128,11 @@ pub fn op_inputs(
|
||||||
| Operator::I32ShrS
|
| Operator::I32ShrS
|
||||||
| Operator::I32ShrU
|
| Operator::I32ShrU
|
||||||
| Operator::I32Rotl
|
| Operator::I32Rotl
|
||||||
| Operator::I32Rotr => Ok(vec![Type::I32, Type::I32]),
|
| Operator::I32Rotr => Ok(Cow::Borrowed(&[Type::I32, Type::I32])),
|
||||||
|
|
||||||
Operator::I64Clz | Operator::I64Ctz | Operator::I64Popcnt => Ok(vec![Type::I64]),
|
Operator::I64Clz | Operator::I64Ctz | Operator::I64Popcnt => {
|
||||||
|
Ok(Cow::Borrowed(&[Type::I64]))
|
||||||
|
}
|
||||||
|
|
||||||
Operator::I64Add
|
Operator::I64Add
|
||||||
| Operator::I64Sub
|
| Operator::I64Sub
|
||||||
|
@ -143,7 +148,7 @@ pub fn op_inputs(
|
||||||
| Operator::I64ShrS
|
| Operator::I64ShrS
|
||||||
| Operator::I64ShrU
|
| Operator::I64ShrU
|
||||||
| Operator::I64Rotl
|
| Operator::I64Rotl
|
||||||
| Operator::I64Rotr => Ok(vec![Type::I64, Type::I64]),
|
| Operator::I64Rotr => Ok(Cow::Borrowed(&[Type::I64, Type::I64])),
|
||||||
|
|
||||||
Operator::F32Abs
|
Operator::F32Abs
|
||||||
| Operator::F32Neg
|
| Operator::F32Neg
|
||||||
|
@ -151,7 +156,7 @@ pub fn op_inputs(
|
||||||
| Operator::F32Floor
|
| Operator::F32Floor
|
||||||
| Operator::F32Trunc
|
| Operator::F32Trunc
|
||||||
| Operator::F32Nearest
|
| Operator::F32Nearest
|
||||||
| Operator::F32Sqrt => Ok(vec![Type::F32]),
|
| Operator::F32Sqrt => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
|
|
||||||
Operator::F32Add
|
Operator::F32Add
|
||||||
| Operator::F32Sub
|
| Operator::F32Sub
|
||||||
|
@ -159,7 +164,7 @@ pub fn op_inputs(
|
||||||
| Operator::F32Div
|
| Operator::F32Div
|
||||||
| Operator::F32Min
|
| Operator::F32Min
|
||||||
| Operator::F32Max
|
| Operator::F32Max
|
||||||
| Operator::F32Copysign => Ok(vec![Type::F32, Type::F32]),
|
| Operator::F32Copysign => Ok(Cow::Borrowed(&[Type::F32, Type::F32])),
|
||||||
|
|
||||||
Operator::F64Abs
|
Operator::F64Abs
|
||||||
| Operator::F64Neg
|
| Operator::F64Neg
|
||||||
|
@ -167,7 +172,7 @@ pub fn op_inputs(
|
||||||
| Operator::F64Floor
|
| Operator::F64Floor
|
||||||
| Operator::F64Trunc
|
| Operator::F64Trunc
|
||||||
| Operator::F64Nearest
|
| Operator::F64Nearest
|
||||||
| Operator::F64Sqrt => Ok(vec![Type::F64]),
|
| Operator::F64Sqrt => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
|
|
||||||
Operator::F64Add
|
Operator::F64Add
|
||||||
| Operator::F64Sub
|
| Operator::F64Sub
|
||||||
|
@ -175,52 +180,54 @@ pub fn op_inputs(
|
||||||
| Operator::F64Div
|
| Operator::F64Div
|
||||||
| Operator::F64Min
|
| Operator::F64Min
|
||||||
| Operator::F64Max
|
| Operator::F64Max
|
||||||
| Operator::F64Copysign => Ok(vec![Type::F64, Type::F64]),
|
| Operator::F64Copysign => Ok(Cow::Borrowed(&[Type::F64, Type::F64])),
|
||||||
|
|
||||||
Operator::I32WrapI64 => Ok(vec![Type::I64]),
|
Operator::I32WrapI64 => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I32TruncF32S => Ok(vec![Type::F32]),
|
Operator::I32TruncF32S => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I32TruncF32U => Ok(vec![Type::F32]),
|
Operator::I32TruncF32U => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I32TruncF64S => Ok(vec![Type::F64]),
|
Operator::I32TruncF64S => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I32TruncF64U => Ok(vec![Type::F64]),
|
Operator::I32TruncF64U => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I64ExtendI32S => Ok(vec![Type::I32]),
|
Operator::I64ExtendI32S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64ExtendI32U => Ok(vec![Type::I32]),
|
Operator::I64ExtendI32U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64TruncF32S => Ok(vec![Type::F32]),
|
Operator::I64TruncF32S => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I64TruncF32U => Ok(vec![Type::F32]),
|
Operator::I64TruncF32U => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I64TruncF64S => Ok(vec![Type::F64]),
|
Operator::I64TruncF64S => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I64TruncF64U => Ok(vec![Type::F64]),
|
Operator::I64TruncF64U => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F32ConvertI32S => Ok(vec![Type::I32]),
|
Operator::F32ConvertI32S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::F32ConvertI32U => Ok(vec![Type::I32]),
|
Operator::F32ConvertI32U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::F32ConvertI64S => Ok(vec![Type::I64]),
|
Operator::F32ConvertI64S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F32ConvertI64U => Ok(vec![Type::I64]),
|
Operator::F32ConvertI64U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F32DemoteF64 => Ok(vec![Type::F64]),
|
Operator::F32DemoteF64 => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F64ConvertI32S => Ok(vec![Type::I32]),
|
Operator::F64ConvertI32S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::F64ConvertI32U => Ok(vec![Type::I32]),
|
Operator::F64ConvertI32U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::F64ConvertI64S => Ok(vec![Type::I64]),
|
Operator::F64ConvertI64S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F64ConvertI64U => Ok(vec![Type::I64]),
|
Operator::F64ConvertI64U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F64PromoteF32 => Ok(vec![Type::F32]),
|
Operator::F64PromoteF32 => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I32Extend8S => Ok(vec![Type::I32]),
|
Operator::I32Extend8S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32Extend16S => Ok(vec![Type::I32]),
|
Operator::I32Extend16S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64Extend8S => Ok(vec![Type::I64]),
|
Operator::I64Extend8S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64Extend16S => Ok(vec![Type::I64]),
|
Operator::I64Extend16S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64Extend32S => Ok(vec![Type::I64]),
|
Operator::I64Extend32S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I32TruncSatF32S => Ok(vec![Type::F32]),
|
Operator::I32TruncSatF32S => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I32TruncSatF32U => Ok(vec![Type::F32]),
|
Operator::I32TruncSatF32U => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I32TruncSatF64S => Ok(vec![Type::F64]),
|
Operator::I32TruncSatF64S => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I32TruncSatF64U => Ok(vec![Type::F64]),
|
Operator::I32TruncSatF64U => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I64TruncSatF32S => Ok(vec![Type::F32]),
|
Operator::I64TruncSatF32S => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I64TruncSatF32U => Ok(vec![Type::F32]),
|
Operator::I64TruncSatF32U => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I64TruncSatF64S => Ok(vec![Type::F64]),
|
Operator::I64TruncSatF64S => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I64TruncSatF64U => Ok(vec![Type::F64]),
|
Operator::I64TruncSatF64U => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F32ReinterpretI32 => Ok(vec![Type::I32]),
|
Operator::F32ReinterpretI32 => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::F64ReinterpretI64 => Ok(vec![Type::I64]),
|
Operator::F64ReinterpretI64 => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I32ReinterpretF32 => Ok(vec![Type::F32]),
|
Operator::I32ReinterpretF32 => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::I64ReinterpretF64 => Ok(vec![Type::F64]),
|
Operator::I64ReinterpretF64 => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::TableGet { .. } => Ok(vec![Type::I32]),
|
Operator::TableGet { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::TableSet { table_index } => Ok(vec![Type::I32, module.table(*table_index).ty]),
|
Operator::TableSet { table_index } => {
|
||||||
Operator::TableGrow { .. } => Ok(vec![Type::I32]),
|
Ok(vec![Type::I32, module.table(*table_index).ty].into())
|
||||||
Operator::TableSize { .. } => Ok(vec![]),
|
}
|
||||||
Operator::MemorySize { .. } => Ok(vec![]),
|
Operator::TableGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::MemoryGrow { .. } => Ok(vec![Type::I32]),
|
Operator::TableSize { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,60 +236,60 @@ pub fn op_outputs(
|
||||||
my_locals: &EntityVec<Local, Type>,
|
my_locals: &EntityVec<Local, Type>,
|
||||||
op_stack: &[(Type, Value)],
|
op_stack: &[(Type, Value)],
|
||||||
op: &Operator,
|
op: &Operator,
|
||||||
) -> Result<Vec<Type>> {
|
) -> Result<Cow<'static, [Type]>> {
|
||||||
match op {
|
match op {
|
||||||
&Operator::Unreachable | &Operator::Nop => Ok(vec![]),
|
&Operator::Unreachable | &Operator::Nop => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
&Operator::Call { function_index } => {
|
&Operator::Call { function_index } => {
|
||||||
let sig = module.func(function_index).sig();
|
let sig = module.func(function_index).sig();
|
||||||
Ok(Vec::from(module.signature(sig).returns.clone()))
|
Ok(Vec::from(module.signature(sig).returns.clone()).into())
|
||||||
}
|
}
|
||||||
&Operator::CallIndirect { sig_index, .. } => {
|
&Operator::CallIndirect { sig_index, .. } => {
|
||||||
Ok(Vec::from(module.signature(sig_index).returns.clone()))
|
Ok(Vec::from(module.signature(sig_index).returns.clone()).into())
|
||||||
}
|
}
|
||||||
&Operator::Return => Ok(vec![]),
|
&Operator::Return => Ok(Cow::Borrowed(&[])),
|
||||||
&Operator::LocalSet { .. } => Ok(vec![]),
|
&Operator::LocalSet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
&Operator::LocalGet { local_index } | &Operator::LocalTee { local_index } => {
|
&Operator::LocalGet { local_index } | &Operator::LocalTee { local_index } => {
|
||||||
Ok(vec![my_locals[local_index]])
|
Ok(vec![my_locals[local_index]].into())
|
||||||
}
|
}
|
||||||
|
|
||||||
&Operator::Select => {
|
&Operator::Select => {
|
||||||
let val_ty = op_stack[op_stack.len() - 2].0;
|
let val_ty = op_stack[op_stack.len() - 2].0;
|
||||||
Ok(vec![val_ty])
|
Ok(vec![val_ty].into())
|
||||||
}
|
}
|
||||||
&Operator::TypedSelect { ty } => Ok(vec![ty]),
|
&Operator::TypedSelect { ty } => Ok(vec![ty].into()),
|
||||||
&Operator::GlobalGet { global_index } => Ok(vec![module.global_ty(global_index)]),
|
&Operator::GlobalGet { global_index } => Ok(vec![module.global_ty(global_index)].into()),
|
||||||
&Operator::GlobalSet { .. } => Ok(vec![]),
|
&Operator::GlobalSet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32Load { .. }
|
Operator::I32Load { .. }
|
||||||
| Operator::I32Load8S { .. }
|
| Operator::I32Load8S { .. }
|
||||||
| Operator::I32Load8U { .. }
|
| Operator::I32Load8U { .. }
|
||||||
| Operator::I32Load16S { .. }
|
| Operator::I32Load16S { .. }
|
||||||
| Operator::I32Load16U { .. } => Ok(vec![Type::I32]),
|
| Operator::I32Load16U { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64Load { .. }
|
Operator::I64Load { .. }
|
||||||
| Operator::I64Load8S { .. }
|
| Operator::I64Load8S { .. }
|
||||||
| Operator::I64Load8U { .. }
|
| Operator::I64Load8U { .. }
|
||||||
| Operator::I64Load16S { .. }
|
| Operator::I64Load16S { .. }
|
||||||
| Operator::I64Load16U { .. }
|
| Operator::I64Load16U { .. }
|
||||||
| Operator::I64Load32S { .. }
|
| Operator::I64Load32S { .. }
|
||||||
| Operator::I64Load32U { .. } => Ok(vec![Type::I64]),
|
| Operator::I64Load32U { .. } => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F32Load { .. } => Ok(vec![Type::F32]),
|
Operator::F32Load { .. } => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F64Load { .. } => Ok(vec![Type::F64]),
|
Operator::F64Load { .. } => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
|
|
||||||
Operator::I32Store { .. } => Ok(vec![]),
|
Operator::I32Store { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Store { .. } => Ok(vec![]),
|
Operator::I64Store { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F32Store { .. } => Ok(vec![]),
|
Operator::F32Store { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64Store { .. } => Ok(vec![]),
|
Operator::F64Store { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32Store8 { .. } => Ok(vec![]),
|
Operator::I32Store8 { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32Store16 { .. } => Ok(vec![]),
|
Operator::I32Store16 { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Store8 { .. } => Ok(vec![]),
|
Operator::I64Store8 { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Store16 { .. } => Ok(vec![]),
|
Operator::I64Store16 { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Store32 { .. } => Ok(vec![]),
|
Operator::I64Store32 { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32Const { .. } => Ok(vec![Type::I32]),
|
Operator::I32Const { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64Const { .. } => Ok(vec![Type::I64]),
|
Operator::I64Const { .. } => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F32Const { .. } => Ok(vec![Type::F32]),
|
Operator::F32Const { .. } => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F64Const { .. } => Ok(vec![Type::F64]),
|
Operator::F64Const { .. } => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
|
|
||||||
Operator::I32Eqz
|
Operator::I32Eqz
|
||||||
| Operator::I32Eq
|
| Operator::I32Eq
|
||||||
|
@ -317,7 +324,7 @@ pub fn op_outputs(
|
||||||
| Operator::F64Lt
|
| Operator::F64Lt
|
||||||
| Operator::F64Gt
|
| Operator::F64Gt
|
||||||
| Operator::F64Le
|
| Operator::F64Le
|
||||||
| Operator::F64Ge => Ok(vec![Type::I32]),
|
| Operator::F64Ge => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
|
|
||||||
Operator::I32Clz
|
Operator::I32Clz
|
||||||
| Operator::I32Ctz
|
| Operator::I32Ctz
|
||||||
|
@ -336,7 +343,7 @@ pub fn op_outputs(
|
||||||
| Operator::I32ShrS
|
| Operator::I32ShrS
|
||||||
| Operator::I32ShrU
|
| Operator::I32ShrU
|
||||||
| Operator::I32Rotl
|
| Operator::I32Rotl
|
||||||
| Operator::I32Rotr => Ok(vec![Type::I32]),
|
| Operator::I32Rotr => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
|
|
||||||
Operator::I64Clz
|
Operator::I64Clz
|
||||||
| Operator::I64Ctz
|
| Operator::I64Ctz
|
||||||
|
@ -355,7 +362,7 @@ pub fn op_outputs(
|
||||||
| Operator::I64ShrS
|
| Operator::I64ShrS
|
||||||
| Operator::I64ShrU
|
| Operator::I64ShrU
|
||||||
| Operator::I64Rotl
|
| Operator::I64Rotl
|
||||||
| Operator::I64Rotr => Ok(vec![Type::I64]),
|
| Operator::I64Rotr => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
|
|
||||||
Operator::F32Abs
|
Operator::F32Abs
|
||||||
| Operator::F32Neg
|
| Operator::F32Neg
|
||||||
|
@ -370,7 +377,7 @@ pub fn op_outputs(
|
||||||
| Operator::F32Div
|
| Operator::F32Div
|
||||||
| Operator::F32Min
|
| Operator::F32Min
|
||||||
| Operator::F32Max
|
| Operator::F32Max
|
||||||
| Operator::F32Copysign => Ok(vec![Type::F32]),
|
| Operator::F32Copysign => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
|
|
||||||
Operator::F64Abs
|
Operator::F64Abs
|
||||||
| Operator::F64Neg
|
| Operator::F64Neg
|
||||||
|
@ -385,52 +392,52 @@ pub fn op_outputs(
|
||||||
| Operator::F64Div
|
| Operator::F64Div
|
||||||
| Operator::F64Min
|
| Operator::F64Min
|
||||||
| Operator::F64Max
|
| Operator::F64Max
|
||||||
| Operator::F64Copysign => Ok(vec![Type::F64]),
|
| Operator::F64Copysign => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
|
|
||||||
Operator::I32WrapI64 => Ok(vec![Type::I32]),
|
Operator::I32WrapI64 => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncF32S => Ok(vec![Type::I32]),
|
Operator::I32TruncF32S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncF32U => Ok(vec![Type::I32]),
|
Operator::I32TruncF32U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncF64S => Ok(vec![Type::I32]),
|
Operator::I32TruncF64S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncF64U => Ok(vec![Type::I32]),
|
Operator::I32TruncF64U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64ExtendI32S => Ok(vec![Type::I64]),
|
Operator::I64ExtendI32S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64ExtendI32U => Ok(vec![Type::I64]),
|
Operator::I64ExtendI32U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncF32S => Ok(vec![Type::I64]),
|
Operator::I64TruncF32S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncF32U => Ok(vec![Type::I64]),
|
Operator::I64TruncF32U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncF64S => Ok(vec![Type::I64]),
|
Operator::I64TruncF64S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncF64U => Ok(vec![Type::I64]),
|
Operator::I64TruncF64U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F32ConvertI32S => Ok(vec![Type::F32]),
|
Operator::F32ConvertI32S => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F32ConvertI32U => Ok(vec![Type::F32]),
|
Operator::F32ConvertI32U => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F32ConvertI64S => Ok(vec![Type::F32]),
|
Operator::F32ConvertI64S => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F32ConvertI64U => Ok(vec![Type::F32]),
|
Operator::F32ConvertI64U => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F32DemoteF64 => Ok(vec![Type::F32]),
|
Operator::F32DemoteF64 => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F64ConvertI32S => Ok(vec![Type::F64]),
|
Operator::F64ConvertI32S => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F64ConvertI32U => Ok(vec![Type::F64]),
|
Operator::F64ConvertI32U => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F64ConvertI64S => Ok(vec![Type::F64]),
|
Operator::F64ConvertI64S => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F64ConvertI64U => Ok(vec![Type::F64]),
|
Operator::F64ConvertI64U => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::F64PromoteF32 => Ok(vec![Type::F64]),
|
Operator::F64PromoteF32 => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I32Extend8S => Ok(vec![Type::I32]),
|
Operator::I32Extend8S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32Extend16S => Ok(vec![Type::I32]),
|
Operator::I32Extend16S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64Extend8S => Ok(vec![Type::I64]),
|
Operator::I64Extend8S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64Extend16S => Ok(vec![Type::I64]),
|
Operator::I64Extend16S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64Extend32S => Ok(vec![Type::I64]),
|
Operator::I64Extend32S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I32TruncSatF32S => Ok(vec![Type::I32]),
|
Operator::I32TruncSatF32S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncSatF32U => Ok(vec![Type::I32]),
|
Operator::I32TruncSatF32U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncSatF64S => Ok(vec![Type::I32]),
|
Operator::I32TruncSatF64S => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I32TruncSatF64U => Ok(vec![Type::I32]),
|
Operator::I32TruncSatF64U => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64TruncSatF32S => Ok(vec![Type::I64]),
|
Operator::I64TruncSatF32S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncSatF32U => Ok(vec![Type::I64]),
|
Operator::I64TruncSatF32U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncSatF64S => Ok(vec![Type::I64]),
|
Operator::I64TruncSatF64S => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::I64TruncSatF64U => Ok(vec![Type::I64]),
|
Operator::I64TruncSatF64U => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::F32ReinterpretI32 => Ok(vec![Type::F32]),
|
Operator::F32ReinterpretI32 => Ok(Cow::Borrowed(&[Type::F32])),
|
||||||
Operator::F64ReinterpretI64 => Ok(vec![Type::F64]),
|
Operator::F64ReinterpretI64 => Ok(Cow::Borrowed(&[Type::F64])),
|
||||||
Operator::I32ReinterpretF32 => Ok(vec![Type::I32]),
|
Operator::I32ReinterpretF32 => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::I64ReinterpretF64 => Ok(vec![Type::I64]),
|
Operator::I64ReinterpretF64 => Ok(Cow::Borrowed(&[Type::I64])),
|
||||||
Operator::TableGet { table_index } => Ok(vec![module.table(*table_index).ty]),
|
Operator::TableGet { table_index } => Ok(vec![module.table(*table_index).ty].into()),
|
||||||
Operator::TableSet { .. } => Ok(vec![]),
|
Operator::TableSet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::TableGrow { .. } => Ok(vec![]),
|
Operator::TableGrow { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::TableSize { .. } => Ok(vec![Type::I32]),
|
Operator::TableSize { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::MemorySize { .. } => Ok(vec![Type::I32]),
|
Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
Operator::MemoryGrow { .. } => Ok(vec![Type::I32]),
|
Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[Type::I32])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,26 +456,26 @@ pub enum SideEffect {
|
||||||
All,
|
All,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
pub fn op_effects(op: &Operator) -> Result<Cow<'static, [SideEffect]>> {
|
||||||
use SideEffect::*;
|
use SideEffect::*;
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
&Operator::Unreachable => Ok(vec![Trap]),
|
&Operator::Unreachable => Ok(Cow::Borrowed(&[Trap])),
|
||||||
&Operator::Nop => Ok(vec![]),
|
&Operator::Nop => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
&Operator::Call { .. } => Ok(vec![All]),
|
&Operator::Call { .. } => Ok(Cow::Borrowed(&[All])),
|
||||||
&Operator::CallIndirect { .. } => Ok(vec![All]),
|
&Operator::CallIndirect { .. } => Ok(Cow::Borrowed(&[All])),
|
||||||
&Operator::Return => Ok(vec![Return]),
|
&Operator::Return => Ok(Cow::Borrowed(&[Return])),
|
||||||
&Operator::LocalSet { local_index, .. } => Ok(vec![WriteLocal(local_index)]),
|
&Operator::LocalSet { local_index, .. } => Ok(vec![WriteLocal(local_index)].into()),
|
||||||
&Operator::LocalGet { local_index, .. } => Ok(vec![ReadLocal(local_index)]),
|
&Operator::LocalGet { local_index, .. } => Ok(vec![ReadLocal(local_index)].into()),
|
||||||
&Operator::LocalTee { local_index, .. } => {
|
&Operator::LocalTee { local_index, .. } => {
|
||||||
Ok(vec![ReadLocal(local_index), WriteLocal(local_index)])
|
Ok(vec![ReadLocal(local_index), WriteLocal(local_index)].into())
|
||||||
}
|
}
|
||||||
|
|
||||||
&Operator::Select => Ok(vec![]),
|
&Operator::Select => Ok(Cow::Borrowed(&[])),
|
||||||
&Operator::TypedSelect { .. } => Ok(vec![]),
|
&Operator::TypedSelect { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
&Operator::GlobalGet { global_index, .. } => Ok(vec![ReadGlobal(global_index)]),
|
&Operator::GlobalGet { global_index, .. } => Ok(vec![ReadGlobal(global_index)].into()),
|
||||||
&Operator::GlobalSet { global_index, .. } => Ok(vec![WriteGlobal(global_index)]),
|
&Operator::GlobalSet { global_index, .. } => Ok(vec![WriteGlobal(global_index)].into()),
|
||||||
|
|
||||||
Operator::I32Load { .. }
|
Operator::I32Load { .. }
|
||||||
| Operator::I32Load8S { .. }
|
| Operator::I32Load8S { .. }
|
||||||
|
@ -483,7 +490,7 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::I64Load32S { .. }
|
| Operator::I64Load32S { .. }
|
||||||
| Operator::I64Load32U { .. }
|
| Operator::I64Load32U { .. }
|
||||||
| Operator::F32Load { .. }
|
| Operator::F32Load { .. }
|
||||||
| Operator::F64Load { .. } => Ok(vec![Trap, ReadMem]),
|
| Operator::F64Load { .. } => Ok(Cow::Borrowed(&[Trap, ReadMem])),
|
||||||
|
|
||||||
Operator::I32Store { .. }
|
Operator::I32Store { .. }
|
||||||
| Operator::I64Store { .. }
|
| Operator::I64Store { .. }
|
||||||
|
@ -493,12 +500,12 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::I32Store16 { .. }
|
| Operator::I32Store16 { .. }
|
||||||
| Operator::I64Store8 { .. }
|
| Operator::I64Store8 { .. }
|
||||||
| Operator::I64Store16 { .. }
|
| Operator::I64Store16 { .. }
|
||||||
| Operator::I64Store32 { .. } => Ok(vec![Trap, WriteMem]),
|
| Operator::I64Store32 { .. } => Ok(Cow::Borrowed(&[Trap, WriteMem])),
|
||||||
|
|
||||||
Operator::I32Const { .. }
|
Operator::I32Const { .. }
|
||||||
| Operator::I64Const { .. }
|
| Operator::I64Const { .. }
|
||||||
| Operator::F32Const { .. }
|
| Operator::F32Const { .. }
|
||||||
| Operator::F64Const { .. } => Ok(vec![]),
|
| Operator::F64Const { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32Eqz
|
Operator::I32Eqz
|
||||||
| Operator::I32Eq
|
| Operator::I32Eq
|
||||||
|
@ -533,7 +540,7 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::F64Lt
|
| Operator::F64Lt
|
||||||
| Operator::F64Gt
|
| Operator::F64Gt
|
||||||
| Operator::F64Le
|
| Operator::F64Le
|
||||||
| Operator::F64Ge => Ok(vec![]),
|
| Operator::F64Ge => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32Clz
|
Operator::I32Clz
|
||||||
| Operator::I32Ctz
|
| Operator::I32Ctz
|
||||||
|
@ -548,10 +555,10 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::I32ShrS
|
| Operator::I32ShrS
|
||||||
| Operator::I32ShrU
|
| Operator::I32ShrU
|
||||||
| Operator::I32Rotl
|
| Operator::I32Rotl
|
||||||
| Operator::I32Rotr => Ok(vec![]),
|
| Operator::I32Rotr => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32DivS | Operator::I32DivU | Operator::I32RemS | Operator::I32RemU => {
|
Operator::I32DivS | Operator::I32DivU | Operator::I32RemS | Operator::I32RemU => {
|
||||||
Ok(vec![Trap])
|
Ok(Cow::Borrowed(&[Trap]))
|
||||||
}
|
}
|
||||||
|
|
||||||
Operator::I64Clz
|
Operator::I64Clz
|
||||||
|
@ -567,10 +574,10 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::I64ShrS
|
| Operator::I64ShrS
|
||||||
| Operator::I64ShrU
|
| Operator::I64ShrU
|
||||||
| Operator::I64Rotl
|
| Operator::I64Rotl
|
||||||
| Operator::I64Rotr => Ok(vec![]),
|
| Operator::I64Rotr => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I64DivS | Operator::I64DivU | Operator::I64RemS | Operator::I64RemU => {
|
Operator::I64DivS | Operator::I64DivU | Operator::I64RemS | Operator::I64RemU => {
|
||||||
Ok(vec![Trap])
|
Ok(Cow::Borrowed(&[Trap]))
|
||||||
}
|
}
|
||||||
|
|
||||||
Operator::F32Abs
|
Operator::F32Abs
|
||||||
|
@ -586,7 +593,7 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::F32Div
|
| Operator::F32Div
|
||||||
| Operator::F32Min
|
| Operator::F32Min
|
||||||
| Operator::F32Max
|
| Operator::F32Max
|
||||||
| Operator::F32Copysign => Ok(vec![]),
|
| Operator::F32Copysign => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::F64Abs
|
Operator::F64Abs
|
||||||
| Operator::F64Neg
|
| Operator::F64Neg
|
||||||
|
@ -601,52 +608,52 @@ pub fn op_effects(op: &Operator) -> Result<Vec<SideEffect>> {
|
||||||
| Operator::F64Div
|
| Operator::F64Div
|
||||||
| Operator::F64Min
|
| Operator::F64Min
|
||||||
| Operator::F64Max
|
| Operator::F64Max
|
||||||
| Operator::F64Copysign => Ok(vec![]),
|
| Operator::F64Copysign => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32WrapI64 => Ok(vec![]),
|
Operator::I32WrapI64 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32TruncF32S => Ok(vec![Trap]),
|
Operator::I32TruncF32S => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I32TruncF32U => Ok(vec![Trap]),
|
Operator::I32TruncF32U => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I32TruncF64S => Ok(vec![Trap]),
|
Operator::I32TruncF64S => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I32TruncF64U => Ok(vec![Trap]),
|
Operator::I32TruncF64U => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I64ExtendI32S => Ok(vec![]),
|
Operator::I64ExtendI32S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64ExtendI32U => Ok(vec![]),
|
Operator::I64ExtendI32U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64TruncF32S => Ok(vec![Trap]),
|
Operator::I64TruncF32S => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I64TruncF32U => Ok(vec![Trap]),
|
Operator::I64TruncF32U => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I64TruncF64S => Ok(vec![Trap]),
|
Operator::I64TruncF64S => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::I64TruncF64U => Ok(vec![Trap]),
|
Operator::I64TruncF64U => Ok(Cow::Borrowed(&[Trap])),
|
||||||
Operator::F32ConvertI32S => Ok(vec![]),
|
Operator::F32ConvertI32S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F32ConvertI32U => Ok(vec![]),
|
Operator::F32ConvertI32U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F32ConvertI64S => Ok(vec![]),
|
Operator::F32ConvertI64S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F32ConvertI64U => Ok(vec![]),
|
Operator::F32ConvertI64U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F32DemoteF64 => Ok(vec![]),
|
Operator::F32DemoteF64 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64ConvertI32S => Ok(vec![]),
|
Operator::F64ConvertI32S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64ConvertI32U => Ok(vec![]),
|
Operator::F64ConvertI32U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64ConvertI64S => Ok(vec![]),
|
Operator::F64ConvertI64S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64ConvertI64U => Ok(vec![]),
|
Operator::F64ConvertI64U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64PromoteF32 => Ok(vec![]),
|
Operator::F64PromoteF32 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32Extend8S => Ok(vec![]),
|
Operator::I32Extend8S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32Extend16S => Ok(vec![]),
|
Operator::I32Extend16S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Extend8S => Ok(vec![]),
|
Operator::I64Extend8S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Extend16S => Ok(vec![]),
|
Operator::I64Extend16S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64Extend32S => Ok(vec![]),
|
Operator::I64Extend32S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32TruncSatF32S => Ok(vec![]),
|
Operator::I32TruncSatF32S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32TruncSatF32U => Ok(vec![]),
|
Operator::I32TruncSatF32U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32TruncSatF64S => Ok(vec![]),
|
Operator::I32TruncSatF64S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32TruncSatF64U => Ok(vec![]),
|
Operator::I32TruncSatF64U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64TruncSatF32S => Ok(vec![]),
|
Operator::I64TruncSatF32S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64TruncSatF32U => Ok(vec![]),
|
Operator::I64TruncSatF32U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64TruncSatF64S => Ok(vec![]),
|
Operator::I64TruncSatF64S => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64TruncSatF64U => Ok(vec![]),
|
Operator::I64TruncSatF64U => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F32ReinterpretI32 => Ok(vec![]),
|
Operator::F32ReinterpretI32 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::F64ReinterpretI64 => Ok(vec![]),
|
Operator::F64ReinterpretI64 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I32ReinterpretF32 => Ok(vec![]),
|
Operator::I32ReinterpretF32 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::I64ReinterpretF64 => Ok(vec![]),
|
Operator::I64ReinterpretF64 => Ok(Cow::Borrowed(&[])),
|
||||||
Operator::TableGet { table_index, .. } => Ok(vec![ReadTable(*table_index), Trap]),
|
Operator::TableGet { table_index, .. } => Ok(vec![ReadTable(*table_index), Trap].into()),
|
||||||
Operator::TableSet { table_index, .. } => Ok(vec![WriteTable(*table_index), Trap]),
|
Operator::TableSet { table_index, .. } => Ok(vec![WriteTable(*table_index), Trap].into()),
|
||||||
Operator::TableGrow { table_index, .. } => Ok(vec![WriteTable(*table_index), Trap]),
|
Operator::TableGrow { table_index, .. } => Ok(vec![WriteTable(*table_index), Trap].into()),
|
||||||
Operator::TableSize { table_index, .. } => Ok(vec![ReadTable(*table_index)]),
|
Operator::TableSize { table_index, .. } => Ok(vec![ReadTable(*table_index)].into()),
|
||||||
Operator::MemorySize { .. } => Ok(vec![ReadMem]),
|
Operator::MemorySize { .. } => Ok(Cow::Borrowed(&[ReadMem])),
|
||||||
Operator::MemoryGrow { .. } => Ok(vec![WriteMem, Trap]),
|
Operator::MemoryGrow { .. } => Ok(Cow::Borrowed(&[WriteMem, Trap])),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//! Passes.
|
//! Passes.
|
||||||
|
|
||||||
pub mod rpo;
|
pub mod basic_opt;
|
||||||
|
pub mod dom_pass;
|
||||||
pub mod resolve_aliases;
|
pub mod resolve_aliases;
|
||||||
|
pub mod rpo;
|
||||||
|
|
10
src/passes/basic_opt.rs
Normal file
10
src/passes/basic_opt.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
//! Basic optimizations: GVN and constant-propagation/folding.
|
||||||
|
|
||||||
|
use crate::ir::*;
|
||||||
|
use crate::passes::dom_pass;
|
||||||
|
use crate::scoped_map::ScopedMap;
|
||||||
|
use crate::cfg::CFGInfo;
|
||||||
|
|
||||||
|
pub fn gvn(body: &mut FunctionBody, cfg: &CFGInfo) {
|
||||||
|
let mut map: ScopedMap<ValueDef, Value> = ScopedMap::new();
|
||||||
|
}
|
57
src/scoped_map.rs
Normal file
57
src/scoped_map.rs
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
//! Scoped hashmap.
|
||||||
|
|
||||||
|
use fxhash::FxHashMap;
|
||||||
|
use std::hash::Hash;
|
||||||
|
|
||||||
|
pub struct ScopedMap<K: Hash + Eq, V> {
|
||||||
|
map: FxHashMap<K, ScopedMapEntry<V>>,
|
||||||
|
gen: u32,
|
||||||
|
gen_by_level: Vec<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ScopedMapEntry<V> {
|
||||||
|
gen: u32,
|
||||||
|
level: u32,
|
||||||
|
value: V,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<K: Hash + Eq, V> ScopedMap<K, V> {
|
||||||
|
pub fn new() -> ScopedMap<K, V> {
|
||||||
|
ScopedMap {
|
||||||
|
map: FxHashMap::default(),
|
||||||
|
gen: 0,
|
||||||
|
gen_by_level: vec![0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push_level(&mut self) {
|
||||||
|
self.gen += 1;
|
||||||
|
self.gen_by_level.push(self.gen);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pop_level(&mut self) {
|
||||||
|
self.gen_by_level.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, k: K, v: V) {
|
||||||
|
self.map.insert(
|
||||||
|
k,
|
||||||
|
ScopedMapEntry {
|
||||||
|
gen: self.gen,
|
||||||
|
level: self.gen_by_level.len() as u32,
|
||||||
|
value: v,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, k: &K) -> Option<&V> {
|
||||||
|
self.map.get(k).and_then(|entry| {
|
||||||
|
let level = entry.level as usize;
|
||||||
|
if level < self.gen_by_level.len() && entry.gen == self.gen_by_level[level] {
|
||||||
|
Some(&entry.value)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue