Cheap optimisation for boolean conditions in Switch statements

This commit is contained in:
Brian Carroll 2021-11-12 08:59:19 +00:00
parent 78a7e45b8f
commit 3a751aa3e8

View file

@ -4,7 +4,7 @@ use code_builder::Align;
use roc_collections::all::MutMap; use roc_collections::all::MutMap;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use roc_mono::ir::{CallType, Expr, JoinPointId, Literal, Proc, Stmt}; use roc_mono::ir::{CallType, Expr, JoinPointId, Literal, Proc, Stmt};
use roc_mono::layout::{Layout, LayoutIds}; use roc_mono::layout::{Builtin, Layout, LayoutIds};
use crate::layout::WasmLayout; use crate::layout::WasmLayout;
use crate::low_level::{build_call_low_level, LowlevelBuildResult}; use crate::low_level::{build_call_low_level, LowlevelBuildResult};
@ -326,6 +326,7 @@ impl<'a> WasmBackend<'a> {
self.start_block(BlockType::NoResult) self.start_block(BlockType::NoResult)
} }
let is_bool = matches!(cond_layout, Layout::Builtin(Builtin::Int1));
let cond_type = WasmLayout::new(cond_layout).value_type(); let cond_type = WasmLayout::new(cond_layout).value_type();
// then, we jump whenever the value under scrutiny is equal to the value of a branch // then, we jump whenever the value under scrutiny is equal to the value of a branch
@ -334,22 +335,29 @@ impl<'a> WasmBackend<'a> {
self.storage self.storage
.load_symbols(&mut self.code_builder, &[*cond_symbol]); .load_symbols(&mut self.code_builder, &[*cond_symbol]);
match cond_type { if is_bool {
ValueType::I32 => { // We already have a bool, don't need to compare against a const to get one
self.code_builder.i32_const(*value as i32); if *value == 0 {
self.code_builder.i32_eq(); self.code_builder.i32_eqz();
} }
ValueType::I64 => { } else {
self.code_builder.i64_const(*value as i64); match cond_type {
self.code_builder.i64_eq(); ValueType::I32 => {
} self.code_builder.i32_const(*value as i32);
ValueType::F32 => { self.code_builder.i32_eq();
self.code_builder.f32_const(f32::from_bits(*value as u32)); }
self.code_builder.f32_eq(); ValueType::I64 => {
} self.code_builder.i64_const(*value as i64);
ValueType::F64 => { self.code_builder.i64_eq();
self.code_builder.f64_const(f64::from_bits(*value as u64)); }
self.code_builder.f64_eq(); ValueType::F32 => {
self.code_builder.f32_const(f32::from_bits(*value as u32));
self.code_builder.f32_eq();
}
ValueType::F64 => {
self.code_builder.f64_const(f64::from_bits(*value as u64));
self.code_builder.f64_eq();
}
} }
} }