Fix #975 (Structure of cranelift-wasm/src/translation_utils.rs causes many pointless heap allocations) (#1010)

This patch restricts the `Err(..)` return from `blocktype_to_type` to be
`Err(..)` only in the case where it really is an error to continue.  The three
use points of `blocktype_to_type` are changed to check for an `Err(..)` rather
than silently ignoring it.  There are also cosmetic changes to `type_to_type`
and `tabletype_to_type`.

When compiling wasm_lua_binarytrees, this reduces the number of blocks
allocated by CL by 1.9%.  Instruction count falls by 0.1%.

Details:

* `type_to_type` and `tabletype_to_type`:

   - Added the function name in the failure message

   - No functional change for non-error cases

   - Push the `Ok(..)` to expression leaves, where it really applies.  This
     corrects the misleading impression that, in the case of an unsupported
     type, the function returns `Ok` wrapped around whatever
     `wasm_unsupported` returns.  It doesn't do that, but it certainly reads
     like that.  This assumes that the LLVM backend will do tail merging, so
     the generated code will be unchanged.

* `blocktype_to_type`:

  - Change return type from `WasmResult<ir::Type>` to `WasmResult<Option<ir::Type>>`

  - Manually inline the call to `type_to_type`, to make this function easier
    to read.

  - For the non-error case: map `TypeOrFuncType::Type(Type::EmptyBlockType)`
    to `Ok(None)` rather than `Err(..)`, since that's what all the call sites
    expect - For the error cases, add the function name in the failure
    messages

* cranelift-wasm/src/code_translator.rs

  - For the three uses of `blocktype_to_type`, use `?` to detect failures and
    drop out immediately, meaning that the code will no longer silently ignore
    errors.
This commit is contained in:
julian-seward1
2019-09-10 15:06:10 +02:00
committed by GitHub
parent 81fa5e7696
commit 63367d205c
2 changed files with 32 additions and 24 deletions

View File

@@ -115,35 +115,43 @@ pub struct Memory {
/// Helper function translating wasmparser types to Cranelift types when possible.
pub fn type_to_type(ty: wasmparser::Type) -> WasmResult<ir::Type> {
Ok(match ty {
wasmparser::Type::I32 => ir::types::I32,
wasmparser::Type::I64 => ir::types::I64,
wasmparser::Type::F32 => ir::types::F32,
wasmparser::Type::F64 => ir::types::F64,
ty => wasm_unsupported!("unsupported wasm type {:?}", ty),
})
match ty {
wasmparser::Type::I32 => Ok(ir::types::I32),
wasmparser::Type::I64 => Ok(ir::types::I64),
wasmparser::Type::F32 => Ok(ir::types::F32),
wasmparser::Type::F64 => Ok(ir::types::F64),
ty => wasm_unsupported!("type_to_type: wasm type {:?}", ty),
}
}
/// Helper function translating wasmparser possible table types to Cranelift types when possible,
/// or None for Func tables.
pub fn tabletype_to_type(ty: wasmparser::Type) -> WasmResult<Option<ir::Type>> {
Ok(match ty {
wasmparser::Type::I32 => Some(ir::types::I32),
wasmparser::Type::I64 => Some(ir::types::I64),
wasmparser::Type::F32 => Some(ir::types::F32),
wasmparser::Type::F64 => Some(ir::types::F64),
wasmparser::Type::AnyFunc => None,
ty => wasm_unsupported!("unsupported table wasm type {:?}", ty),
})
match ty {
wasmparser::Type::I32 => Ok(Some(ir::types::I32)),
wasmparser::Type::I64 => Ok(Some(ir::types::I64)),
wasmparser::Type::F32 => Ok(Some(ir::types::F32)),
wasmparser::Type::F64 => Ok(Some(ir::types::F64)),
wasmparser::Type::AnyFunc => Ok(None),
ty => wasm_unsupported!("tabletype_to_type: table wasm type {:?}", ty),
}
}
/// Helper function translating wasmparser block signatures to Cranelift types when possible.
pub fn blocktype_to_type(ty: wasmparser::TypeOrFuncType) -> WasmResult<ir::Type> {
match ty {
wasmparser::TypeOrFuncType::Type(ty) => type_to_type(ty),
wasmparser::TypeOrFuncType::FuncType(_) => {
wasm_unsupported!("multi-value block signature {:?}", ty);
}
pub fn blocktype_to_type(ty_or_ft: wasmparser::TypeOrFuncType) -> WasmResult<Option<ir::Type>> {
match ty_or_ft {
wasmparser::TypeOrFuncType::Type(ty) => match ty {
wasmparser::Type::I32 => Ok(Some(ir::types::I32)),
wasmparser::Type::I64 => Ok(Some(ir::types::I64)),
wasmparser::Type::F32 => Ok(Some(ir::types::F32)),
wasmparser::Type::F64 => Ok(Some(ir::types::F64)),
wasmparser::Type::EmptyBlockType => Ok(None),
ty => wasm_unsupported!("blocktype_to_type: type {:?}", ty),
},
wasmparser::TypeOrFuncType::FuncType(_) => wasm_unsupported!(
"blocktype_to_type: multi-value block signature {:?}",
ty_or_ft
),
}
}