WIP.
This commit is contained in:
parent
abc46f1d14
commit
1fbbbc9637
|
@ -7,7 +7,7 @@ license = "Apache-2.0 WITH LLVM-exception"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wasmparser = { git = 'https://github.com/cfallin/wasm-tools', rev = '03a81b6a6ed4d5d9730fa71bf65636a3b1538ce7' }
|
wasmparser = "0.95"
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
structopt = "0.3"
|
structopt = "0.3"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
|
|
@ -10,10 +10,7 @@ use anyhow::{bail, Result};
|
||||||
use fxhash::{FxHashMap, FxHashSet};
|
use fxhash::{FxHashMap, FxHashSet};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use wasmparser::{
|
use wasmparser::{BlockType, DataKind, ExternalKind, Parser, Payload, TypeRef};
|
||||||
DataKind, ExternalKind, Ieee32, Ieee64, ImportSectionEntryType, Parser, Payload, TypeDef,
|
|
||||||
TypeOrFuncType,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
|
pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
|
||||||
let mut module = Module::with_orig_bytes(bytes);
|
let mut module = Module::with_orig_bytes(bytes);
|
||||||
|
@ -27,7 +24,7 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<Option<u64>> {
|
fn parse_init_expr<'a>(init_expr: &wasmparser::ConstExpr<'a>) -> Result<Option<u64>> {
|
||||||
let operators = init_expr
|
let operators = init_expr
|
||||||
.get_operators_reader()
|
.get_operators_reader()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
@ -60,24 +57,23 @@ fn handle_payload<'a>(
|
||||||
Payload::TypeSection(reader) => {
|
Payload::TypeSection(reader) => {
|
||||||
for ty in reader {
|
for ty in reader {
|
||||||
let ty = ty?;
|
let ty = ty?;
|
||||||
if let TypeDef::Func(fty) = ty {
|
let wasmparser::Type::Func(fty) = ty;
|
||||||
module.frontend_add_signature(fty.into());
|
module.frontend_add_signature(fty.into());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Payload::ImportSection(reader) => {
|
Payload::ImportSection(reader) => {
|
||||||
for import in reader {
|
for import in reader {
|
||||||
let import = import?;
|
let import = import?;
|
||||||
let module_name = import.module.to_owned();
|
let module_name = import.module.to_owned();
|
||||||
let name = import.field.unwrap_or("").to_owned();
|
let name = import.name.to_owned();
|
||||||
let kind = match import.ty {
|
let kind = match import.ty {
|
||||||
ImportSectionEntryType::Function(sig_idx) => {
|
TypeRef::Func(sig_idx) => {
|
||||||
let func =
|
let func =
|
||||||
module.frontend_add_func(FuncDecl::Import(Signature::from(sig_idx)));
|
module.frontend_add_func(FuncDecl::Import(Signature::from(sig_idx)));
|
||||||
*next_func += 1;
|
*next_func += 1;
|
||||||
Some(ImportKind::Func(func))
|
Some(ImportKind::Func(func))
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Global(ty) => {
|
TypeRef::Global(ty) => {
|
||||||
let mutable = ty.mutable;
|
let mutable = ty.mutable;
|
||||||
let ty = ty.content_type.into();
|
let ty = ty.content_type.into();
|
||||||
let global = module.frontend_add_global(GlobalData {
|
let global = module.frontend_add_global(GlobalData {
|
||||||
|
@ -87,7 +83,7 @@ fn handle_payload<'a>(
|
||||||
});
|
});
|
||||||
Some(ImportKind::Global(global))
|
Some(ImportKind::Global(global))
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Table(ty) => {
|
TypeRef::Table(ty) => {
|
||||||
let table = module.frontend_add_table(ty.element_type.into(), None);
|
let table = module.frontend_add_table(ty.element_type.into(), None);
|
||||||
Some(ImportKind::Table(table))
|
Some(ImportKind::Table(table))
|
||||||
}
|
}
|
||||||
|
@ -140,9 +136,9 @@ fn handle_payload<'a>(
|
||||||
Payload::ExportSection(reader) => {
|
Payload::ExportSection(reader) => {
|
||||||
for export in reader {
|
for export in reader {
|
||||||
let export = export?;
|
let export = export?;
|
||||||
let name = export.field.to_owned();
|
let name = export.name.to_owned();
|
||||||
let kind = match export.kind {
|
let kind = match export.kind {
|
||||||
ExternalKind::Function => Some(ExportKind::Func(Func::from(export.index))),
|
ExternalKind::Func => Some(ExportKind::Func(Func::from(export.index))),
|
||||||
ExternalKind::Table => Some(ExportKind::Table(Table::from(export.index))),
|
ExternalKind::Table => Some(ExportKind::Table(Table::from(export.index))),
|
||||||
ExternalKind::Global => Some(ExportKind::Global(Global::from(export.index))),
|
ExternalKind::Global => Some(ExportKind::Global(Global::from(export.index))),
|
||||||
ExternalKind::Memory => Some(ExportKind::Memory(Memory::from(export.index))),
|
ExternalKind::Memory => Some(ExportKind::Memory(Memory::from(export.index))),
|
||||||
|
@ -170,11 +166,11 @@ fn handle_payload<'a>(
|
||||||
DataKind::Passive => {}
|
DataKind::Passive => {}
|
||||||
DataKind::Active {
|
DataKind::Active {
|
||||||
memory_index,
|
memory_index,
|
||||||
init_expr,
|
offset_expr,
|
||||||
} => {
|
} => {
|
||||||
let data = segment.data.to_vec();
|
let data = segment.data.to_vec();
|
||||||
let memory = Memory::from(*memory_index);
|
let memory = Memory::from(*memory_index);
|
||||||
let offset = parse_init_expr(init_expr)?.unwrap_or(0) as usize;
|
let offset = parse_init_expr(offset_expr)?.unwrap_or(0) as usize;
|
||||||
module
|
module
|
||||||
.memory_mut(memory)
|
.memory_mut(memory)
|
||||||
.segments
|
.segments
|
||||||
|
@ -189,7 +185,7 @@ fn handle_payload<'a>(
|
||||||
Payload::ElementSection(reader) => {
|
Payload::ElementSection(reader) => {
|
||||||
for element in reader {
|
for element in reader {
|
||||||
let element = element?;
|
let element = element?;
|
||||||
if element.ty != wasmparser::Type::FuncRef {
|
if element.ty != wasmparser::ValType::FuncRef {
|
||||||
anyhow::bail!("Unsupported table type: {:?}", element.ty);
|
anyhow::bail!("Unsupported table type: {:?}", element.ty);
|
||||||
}
|
}
|
||||||
match &element.kind {
|
match &element.kind {
|
||||||
|
@ -197,10 +193,10 @@ fn handle_payload<'a>(
|
||||||
wasmparser::ElementKind::Declared => {}
|
wasmparser::ElementKind::Declared => {}
|
||||||
wasmparser::ElementKind::Active {
|
wasmparser::ElementKind::Active {
|
||||||
table_index,
|
table_index,
|
||||||
init_expr,
|
offset_expr,
|
||||||
} => {
|
} => {
|
||||||
let table = Table::from(*table_index);
|
let table = Table::from(*table_index);
|
||||||
let offset = parse_init_expr(&init_expr)?.unwrap_or(0) as usize;
|
let offset = parse_init_expr(&offset_expr)?.unwrap_or(0) as usize;
|
||||||
let items = element
|
let items = element
|
||||||
.items
|
.items
|
||||||
.get_items_reader()?
|
.get_items_reader()?
|
||||||
|
@ -224,7 +220,7 @@ fn handle_payload<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Payload::End => {}
|
Payload::End(_) => {}
|
||||||
payload => {
|
payload => {
|
||||||
log::warn!("Skipping section: {:?}", payload);
|
log::warn!("Skipping section: {:?}", payload);
|
||||||
}
|
}
|
||||||
|
@ -453,16 +449,12 @@ impl LocalTracker {
|
||||||
vec![ty],
|
vec![ty],
|
||||||
)),
|
)),
|
||||||
Type::F32 => body.add_value(ValueDef::Operator(
|
Type::F32 => body.add_value(ValueDef::Operator(
|
||||||
Operator::F32Const {
|
Operator::F32Const { value: 0 },
|
||||||
value: Ieee32::from_bits(0),
|
|
||||||
},
|
|
||||||
vec![],
|
vec![],
|
||||||
vec![ty],
|
vec![ty],
|
||||||
)),
|
)),
|
||||||
Type::F64 => body.add_value(ValueDef::Operator(
|
Type::F64 => body.add_value(ValueDef::Operator(
|
||||||
Operator::F64Const {
|
Operator::F64Const { value: 0 },
|
||||||
value: Ieee64::from_bits(0),
|
|
||||||
},
|
|
||||||
vec![],
|
vec![],
|
||||||
vec![ty],
|
vec![ty],
|
||||||
)),
|
)),
|
||||||
|
@ -1021,8 +1013,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmparser::Operator::Block { ty } => {
|
wasmparser::Operator::Block { blockty } => {
|
||||||
let (params, results) = self.block_params_and_results(*ty);
|
let (params, results) = self.block_params_and_results(*blockty);
|
||||||
let out = self.body.add_block();
|
let out = self.body.add_block();
|
||||||
self.add_block_params(out, &results[..]);
|
self.add_block_params(out, &results[..]);
|
||||||
let start_depth = self.op_stack.len() - params.len();
|
let start_depth = self.op_stack.len() - params.len();
|
||||||
|
@ -1034,8 +1026,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmparser::Operator::Loop { ty } => {
|
wasmparser::Operator::Loop { blockty } => {
|
||||||
let (params, results) = self.block_params_and_results(*ty);
|
let (params, results) = self.block_params_and_results(*blockty);
|
||||||
let header = self.body.add_block();
|
let header = self.body.add_block();
|
||||||
self.add_block_params(header, ¶ms[..]);
|
self.add_block_params(header, ¶ms[..]);
|
||||||
let initial_args = self.pop_n(params.len());
|
let initial_args = self.pop_n(params.len());
|
||||||
|
@ -1055,8 +1047,8 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmparser::Operator::If { ty } => {
|
wasmparser::Operator::If { blockty } => {
|
||||||
let (params, results) = self.block_params_and_results(*ty);
|
let (params, results) = self.block_params_and_results(*blockty);
|
||||||
let if_true = self.body.add_block();
|
let if_true = self.body.add_block();
|
||||||
let if_false = self.body.add_block();
|
let if_false = self.body.add_block();
|
||||||
let join = self.body.add_block();
|
let join = self.body.add_block();
|
||||||
|
@ -1140,20 +1132,20 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmparser::Operator::BrTable { table } => {
|
wasmparser::Operator::BrTable { targets } => {
|
||||||
// Get the selector index.
|
// Get the selector index.
|
||||||
let index = self.pop_1();
|
let index = self.pop_1();
|
||||||
// Get the signature of the default frame; this tells
|
// Get the signature of the default frame; this tells
|
||||||
// us the signature of all frames (since wasmparser
|
// us the signature of all frames (since wasmparser
|
||||||
// validates the input for us). Pop that many args.
|
// validates the input for us). Pop that many args.
|
||||||
let default_frame = self.relative_frame(table.default());
|
let default_frame = self.relative_frame(targets.default());
|
||||||
let default_term_target = default_frame.br_target();
|
let default_term_target = default_frame.br_target();
|
||||||
let arg_len = default_frame.br_args().len();
|
let arg_len = default_frame.br_args().len();
|
||||||
let args = self.pop_n(arg_len);
|
let args = self.pop_n(arg_len);
|
||||||
// Generate a branch terminator with the same args for
|
// Generate a branch terminator with the same args for
|
||||||
// every branch target.
|
// every branch target.
|
||||||
let mut term_targets = vec![];
|
let mut term_targets = vec![];
|
||||||
for target in table.targets() {
|
for target in targets.targets() {
|
||||||
let target = target?;
|
let target = target?;
|
||||||
let frame = self.relative_frame(target);
|
let frame = self.relative_frame(target);
|
||||||
assert_eq!(frame.br_args().len(), args.len());
|
assert_eq!(frame.br_args().len(), args.len());
|
||||||
|
@ -1181,11 +1173,11 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block_params_and_results(&self, ty: TypeOrFuncType) -> (Vec<Type>, Vec<Type>) {
|
fn block_params_and_results(&self, ty: BlockType) -> (Vec<Type>, Vec<Type>) {
|
||||||
match ty {
|
match ty {
|
||||||
TypeOrFuncType::Type(wasmparser::Type::EmptyBlockType) => (vec![], vec![]),
|
BlockType::Empty => (vec![], vec![]),
|
||||||
TypeOrFuncType::Type(ret_ty) => (vec![], vec![ret_ty.into()]),
|
BlockType::Type(ret_ty) => (vec![], vec![ret_ty.into()]),
|
||||||
TypeOrFuncType::FuncType(sig_idx) => {
|
BlockType::FuncType(sig_idx) => {
|
||||||
let sig = &self.module.signature(Signature::from(sig_idx));
|
let sig = &self.module.signature(Signature::from(sig_idx));
|
||||||
(
|
(
|
||||||
Vec::from(sig.params.clone()),
|
Vec::from(sig.params.clone()),
|
||||||
|
|
16
src/ir.rs
16
src/ir.rs
|
@ -11,15 +11,15 @@ pub enum Type {
|
||||||
V128,
|
V128,
|
||||||
FuncRef,
|
FuncRef,
|
||||||
}
|
}
|
||||||
impl From<wasmparser::Type> for Type {
|
impl From<wasmparser::ValType> for Type {
|
||||||
fn from(ty: wasmparser::Type) -> Self {
|
fn from(ty: wasmparser::ValType) -> Self {
|
||||||
match ty {
|
match ty {
|
||||||
wasmparser::Type::I32 => Type::I32,
|
wasmparser::ValType::I32 => Type::I32,
|
||||||
wasmparser::Type::I64 => Type::I64,
|
wasmparser::ValType::I64 => Type::I64,
|
||||||
wasmparser::Type::F32 => Type::F32,
|
wasmparser::ValType::F32 => Type::F32,
|
||||||
wasmparser::Type::F64 => Type::F64,
|
wasmparser::ValType::F64 => Type::F64,
|
||||||
wasmparser::Type::V128 => Type::V128,
|
wasmparser::ValType::V128 => Type::V128,
|
||||||
wasmparser::Type::FuncRef => Type::FuncRef,
|
wasmparser::ValType::FuncRef => Type::FuncRef,
|
||||||
_ => panic!("Unsupported type: {:?}", ty),
|
_ => panic!("Unsupported type: {:?}", ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,12 +53,12 @@ impl From<&wasmparser::FuncType> for SignatureData {
|
||||||
fn from(fty: &wasmparser::FuncType) -> Self {
|
fn from(fty: &wasmparser::FuncType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
params: fty
|
params: fty
|
||||||
.params
|
.params()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&ty| ty.into())
|
.map(|&ty| ty.into())
|
||||||
.collect::<Vec<Type>>(),
|
.collect::<Vec<Type>>(),
|
||||||
returns: fty
|
returns: fty
|
||||||
.returns
|
.results()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&ty| ty.into())
|
.map(|&ty| ty.into())
|
||||||
.collect::<Vec<Type>>(),
|
.collect::<Vec<Type>>(),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Metadata on operators.
|
//! Metadata on operators.
|
||||||
|
|
||||||
use crate::entity::EntityVec;
|
use crate::entity::EntityVec;
|
||||||
use crate::ir::{Global, Local, Module, Signature, Table, Type, Value};
|
use crate::ir::{Local, Module, Signature, Type, Value};
|
||||||
use crate::Operator;
|
use crate::Operator;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -711,8 +711,8 @@ impl std::fmt::Display for Operator {
|
||||||
|
|
||||||
Operator::I32Const { value } => write!(f, "i32const<{}>", value)?,
|
Operator::I32Const { value } => write!(f, "i32const<{}>", value)?,
|
||||||
Operator::I64Const { value } => write!(f, "i64const<{}>", value)?,
|
Operator::I64Const { value } => write!(f, "i64const<{}>", value)?,
|
||||||
Operator::F32Const { value } => write!(f, "f32const<{}>", value.bits())?,
|
Operator::F32Const { value } => write!(f, "f32const<{}>", value)?,
|
||||||
Operator::F64Const { value } => write!(f, "f64const<{}>", value.bits())?,
|
Operator::F64Const { value } => write!(f, "f64const<{}>", value)?,
|
||||||
|
|
||||||
Operator::I32Eqz => write!(f, "i32eqz")?,
|
Operator::I32Eqz => write!(f, "i32eqz")?,
|
||||||
Operator::I32Eq => write!(f, "i32eq")?,
|
Operator::I32Eq => write!(f, "i32eq")?,
|
||||||
|
|
35
src/ops.rs
35
src/ops.rs
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
use crate::{Func, Global, Local, Memory, Signature, Table, Type};
|
use crate::{Func, Global, Local, Memory, Signature, Table, Type};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use wasmparser::MemoryImmediate;
|
|
||||||
pub use wasmparser::{Ieee32, Ieee64};
|
pub use wasmparser::{Ieee32, Ieee64};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
@ -127,16 +126,16 @@ pub enum Operator {
|
||||||
},
|
},
|
||||||
|
|
||||||
I32Const {
|
I32Const {
|
||||||
value: i32,
|
value: u32,
|
||||||
},
|
},
|
||||||
I64Const {
|
I64Const {
|
||||||
value: i64,
|
value: u64,
|
||||||
},
|
},
|
||||||
F32Const {
|
F32Const {
|
||||||
value: Ieee32,
|
value: u32,
|
||||||
},
|
},
|
||||||
F64Const {
|
F64Const {
|
||||||
value: Ieee64,
|
value: u64,
|
||||||
},
|
},
|
||||||
|
|
||||||
I32Eqz,
|
I32Eqz,
|
||||||
|
@ -319,9 +318,11 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
|
||||||
function_index: Func::from(function_index),
|
function_index: Func::from(function_index),
|
||||||
}),
|
}),
|
||||||
&wasmparser::Operator::CallIndirect {
|
&wasmparser::Operator::CallIndirect {
|
||||||
index, table_index, ..
|
type_index,
|
||||||
|
table_index,
|
||||||
|
..
|
||||||
} => Ok(Operator::CallIndirect {
|
} => Ok(Operator::CallIndirect {
|
||||||
sig_index: Signature::from(index),
|
sig_index: Signature::from(type_index),
|
||||||
table_index: Table::from(table_index),
|
table_index: Table::from(table_index),
|
||||||
}),
|
}),
|
||||||
&wasmparser::Operator::Return => Ok(Operator::Return),
|
&wasmparser::Operator::Return => Ok(Operator::Return),
|
||||||
|
@ -413,10 +414,18 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
|
||||||
&wasmparser::Operator::I64Store32 { memarg } => Ok(Operator::I64Store32 {
|
&wasmparser::Operator::I64Store32 { memarg } => Ok(Operator::I64Store32 {
|
||||||
memory: memarg.into(),
|
memory: memarg.into(),
|
||||||
}),
|
}),
|
||||||
&wasmparser::Operator::I32Const { value } => Ok(Operator::I32Const { value }),
|
&wasmparser::Operator::I32Const { value } => Ok(Operator::I32Const {
|
||||||
&wasmparser::Operator::I64Const { value } => Ok(Operator::I64Const { value }),
|
value: value as u32,
|
||||||
&wasmparser::Operator::F32Const { value } => Ok(Operator::F32Const { value }),
|
}),
|
||||||
&wasmparser::Operator::F64Const { value } => Ok(Operator::F64Const { value }),
|
&wasmparser::Operator::I64Const { value } => Ok(Operator::I64Const {
|
||||||
|
value: value as u64,
|
||||||
|
}),
|
||||||
|
&wasmparser::Operator::F32Const { value } => Ok(Operator::F32Const {
|
||||||
|
value: value.bits(),
|
||||||
|
}),
|
||||||
|
&wasmparser::Operator::F64Const { value } => Ok(Operator::F64Const {
|
||||||
|
value: value.bits(),
|
||||||
|
}),
|
||||||
&wasmparser::Operator::I32Eqz => Ok(Operator::I32Eqz),
|
&wasmparser::Operator::I32Eqz => Ok(Operator::I32Eqz),
|
||||||
&wasmparser::Operator::I32Eq => Ok(Operator::I32Eq),
|
&wasmparser::Operator::I32Eq => Ok(Operator::I32Eq),
|
||||||
&wasmparser::Operator::I32Ne => Ok(Operator::I32Ne),
|
&wasmparser::Operator::I32Ne => Ok(Operator::I32Ne),
|
||||||
|
@ -576,8 +585,8 @@ impl<'a, 'b> std::convert::TryFrom<&'b wasmparser::Operator<'a>> for Operator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::convert::From<MemoryImmediate> for MemoryArg {
|
impl std::convert::From<wasmparser::MemArg> for MemoryArg {
|
||||||
fn from(value: MemoryImmediate) -> MemoryArg {
|
fn from(value: wasmparser::MemArg) -> MemoryArg {
|
||||||
MemoryArg {
|
MemoryArg {
|
||||||
align: value.align as u32,
|
align: value.align as u32,
|
||||||
offset: u32::try_from(value.offset).expect("offset too large"),
|
offset: u32::try_from(value.offset).expect("offset too large"),
|
||||||
|
|
|
@ -204,7 +204,7 @@ impl GVNPass {
|
||||||
match const_val {
|
match const_val {
|
||||||
Some(ConstVal::I32(val)) => {
|
Some(ConstVal::I32(val)) => {
|
||||||
value = ValueDef::Operator(
|
value = ValueDef::Operator(
|
||||||
Operator::I32Const { value: val as i32 },
|
Operator::I32Const { value: val },
|
||||||
vec![],
|
vec![],
|
||||||
vec![Type::I32],
|
vec![Type::I32],
|
||||||
);
|
);
|
||||||
|
@ -212,7 +212,7 @@ impl GVNPass {
|
||||||
}
|
}
|
||||||
Some(ConstVal::I64(val)) => {
|
Some(ConstVal::I64(val)) => {
|
||||||
value = ValueDef::Operator(
|
value = ValueDef::Operator(
|
||||||
Operator::I64Const { value: val as i64 },
|
Operator::I64Const { value: val },
|
||||||
vec![],
|
vec![],
|
||||||
vec![Type::I64],
|
vec![Type::I64],
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue