Skip to content

Commit

Permalink
feat(compiler): Add ability to match on low level wasm types (#1588)
Browse files Browse the repository at this point in the history
  • Loading branch information
ospencer authored Jan 10, 2023
1 parent 8d465b7 commit 0d30888
Show file tree
Hide file tree
Showing 6 changed files with 877 additions and 18 deletions.
52 changes: 34 additions & 18 deletions compiler/src/middle_end/matchcomp.re
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ and switch_type =
| ArraySwitch

and equality_type =
| PhysicalEquality
| PhysicalEquality(wasm_repr)
| StructuralEquality;

type conversion_result = {
Expand Down Expand Up @@ -544,13 +544,10 @@ let equality_type =
| Const_void
| Const_bool(_)
| Const_char(_)
| Const_wasmi32(_) => PhysicalEquality
| Const_wasmi64(_)
| Const_wasmf32(_)
| Const_wasmf64(_) =>
failwith(
"Pattern matching not supported on low-level i64/f32/f64 types.",
);
| Const_wasmi32(_) => PhysicalEquality(WasmI32)
| Const_wasmi64(_) => PhysicalEquality(WasmI64)
| Const_wasmf32(_) => PhysicalEquality(WasmF32)
| Const_wasmf64(_) => PhysicalEquality(WasmF64);

let rec compile_matrix = mtx =>
switch (mtx) {
Expand Down Expand Up @@ -878,7 +875,25 @@ module MatchTreeCompiler = {
let equality_op =
switch (equality_type) {
| StructuralEquality => Eq
| PhysicalEquality => Is
| PhysicalEquality(WasmI32) => Is
| PhysicalEquality(WasmI64) =>
WasmBinaryI64({
wasm_op: Op_eq_int64,
arg_types: (Wasm_int64, Wasm_int64),
ret_type: Grain_bool,
})
| PhysicalEquality(WasmF32) =>
WasmBinaryF32({
wasm_op: Op_eq_float32,
arg_types: (Wasm_float32, Wasm_float32),
ret_type: Grain_bool,
})
| PhysicalEquality(WasmF64) =>
WasmBinaryF64({
wasm_op: Op_eq_float64,
arg_types: (Wasm_float64, Wasm_float64),
ret_type: Grain_bool,
})
};
let (const, const_setup) =
switch (helpConst(const)) {
Expand Down Expand Up @@ -1158,23 +1173,24 @@ module MatchTreeCompiler = {
let collect_bindings = (~mut_boxing=false, ~global=Nonglobal, branches) => {
let rec collect_bindings = pat => {
let bind = id => {
let allocation_type = get_allocation_type(pat.pat_env, pat.pat_type);
// Dummy value to be filled in during matching
let dummy_value = Imm.const(Const_wasmi32(0l));
let dummy_value =
switch (allocation_type) {
| Managed
| Unmanaged(WasmI32) => Imm.const(Const_wasmi32(0l))
| Unmanaged(WasmI64) => Imm.const(Const_wasmi64(0L))
| Unmanaged(WasmF32) => Imm.const(Const_wasmf32(0.))
| Unmanaged(WasmF64) => Imm.const(Const_wasmf64(0.))
};
if (mut_boxing) {
BLetMut(
id,
Comp.prim1(~allocation_type=Managed, BoxBind, dummy_value),
Nonglobal,
);
} else {
BLetMut(
id,
Comp.imm(
~allocation_type=get_allocation_type(pat.pat_env, pat.pat_type),
dummy_value,
),
global,
);
BLetMut(id, Comp.imm(~allocation_type, dummy_value), global);
};
};
switch (pat.pat_desc) {
Expand Down
205 changes: 205 additions & 0 deletions compiler/test/__snapshots__/pattern_matching.0fa61137.0.snapshot
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
pattern matching › low_level_constant_match_2
(module
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
(type $none_=>_i32 (func (result i32)))
(type $none_=>_none (func))
(import \"_grainEnv\" \"mem\" (memory $0 0))
(import \"_grainEnv\" \"tbl\" (table $tbl 0 funcref))
(import \"_grainEnv\" \"relocBase\" (global $relocBase_0 i32))
(import \"_grainEnv\" \"moduleRuntimeId\" (global $moduleRuntimeId_0 i32))
(import \"GRAIN$MODULE$runtime/gc\" \"GRAIN$EXPORT$incRef\" (global $GRAIN$EXPORT$incRef_0 (mut i32)))
(import \"GRAIN$MODULE$pervasives\" \"GRAIN$EXPORT$print\" (global $print_1134 (mut i32)))
(import \"GRAIN$MODULE$runtime/gc\" \"incRef\" (func $incRef_0 (param i32 i32) (result i32)))
(import \"GRAIN$MODULE$pervasives\" \"print\" (func $print_1134 (param i32 i32) (result i32)))
(global $GRAIN$TABLE_SIZE i32 (i32.const 0))
(elem $elem (global.get $relocBase_0))
(export \"memory\" (memory $0))
(export \"_gmain\" (func $_gmain))
(export \"_start\" (func $_start))
(export \"GRAIN$TABLE_SIZE\" (global $GRAIN$TABLE_SIZE))
(func $_gmain (result i32)
(local $0 i32)
(local $1 i32)
(local $2 i32)
(local $3 i64)
(local $4 f32)
(local $5 f64)
(local $6 i32)
(local $7 i32)
(local $8 i32)
(local $9 i32)
(return
(block $cleanup_locals.26 (result i32)
(local.set $0
(block $compile_block.25 (result i32)
(block $compile_store.2
(local.set $6
(select
(i32.const -2)
(i32.const 2147483646)
(i64.eq
(i64.const 1)
(i64.const 0)
)
)
)
(block $do_backpatches.1
)
)
(block $compile_store.14
(local.set $7
(if (result i32)
(i32.shr_u
(local.get $6)
(i32.const 31)
)
(block $compile_block.3 (result i32)
(i32.const 1)
)
(block $compile_block.12 (result i32)
(block $compile_store.5
(local.set $7
(select
(i32.const -2)
(i32.const 2147483646)
(i64.eq
(i64.const 1)
(i64.const 1)
)
)
)
(block $do_backpatches.4
)
)
(if (result i32)
(i32.shr_u
(local.get $7)
(i32.const 31)
)
(block $compile_block.6 (result i32)
(i32.const 3)
)
(block $compile_block.11 (result i32)
(block $compile_store.8
(local.set $8
(select
(i32.const -2)
(i32.const 2147483646)
(i64.eq
(i64.const 1)
(i64.const 2)
)
)
)
(block $do_backpatches.7
)
)
(if (result i32)
(i32.shr_u
(local.get $8)
(i32.const 31)
)
(block $compile_block.9 (result i32)
(i32.const 5)
)
(block $compile_block.10 (result i32)
(i32.const 7)
)
)
)
)
)
)
)
(block $do_backpatches.13
)
)
(block $compile_store.22
(local.set $8
(block $switch.15_outer (result i32)
(block $switch.15_branch_0 (result i32)
(drop
(block $switch.15_branch_1 (result i32)
(drop
(block $switch.15_branch_2 (result i32)
(drop
(block $switch.15_branch_3 (result i32)
(drop
(block $switch.15_branch_4 (result i32)
(drop
(block $switch.15_default (result i32)
(br_table $switch.15_branch_1 $switch.15_branch_2 $switch.15_branch_3 $switch.15_branch_4 $switch.15_default $switch.15_default
(i32.const 0)
(i32.shr_s
(local.get $7)
(i32.const 1)
)
)
)
)
(br $switch.15_outer
(block $compile_block.20 (result i32)
(unreachable)
)
)
)
)
(br $switch.15_outer
(block $compile_block.19 (result i32)
(i32.const 2147483646)
)
)
)
)
(br $switch.15_outer
(block $compile_block.18 (result i32)
(i32.const 2147483646)
)
)
)
)
(br $switch.15_outer
(block $compile_block.17 (result i32)
(i32.const -2)
)
)
)
)
(br $switch.15_outer
(block $compile_block.16 (result i32)
(i32.const 2147483646)
)
)
)
)
)
(block $do_backpatches.21
)
)
(block $compile_store.24
(local.set $9
(call $print_1134
(call $incRef_0
(global.get $GRAIN$EXPORT$incRef_0)
(global.get $print_1134)
)
(local.get $8)
)
)
(block $do_backpatches.23
)
)
(i32.const 1)
)
)
(local.get $0)
)
)
)
(func $_start
(drop
(call $_gmain)
)
)
;; custom section \"cmi\", size 258
)
Loading

0 comments on commit 0d30888

Please sign in to comment.