Skip to content

Commit 165b198

Browse files
chore: add global bin op and acc superinstructions, cleanup executor
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent e6691d0 commit 165b198

8 files changed

Lines changed: 180 additions & 98 deletions

File tree

crates/parser/src/lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,7 @@ pub struct ParserOptions {
5555

5656
impl Default for ParserOptions {
5757
fn default() -> Self {
58-
Self {
59-
optimize_local_memory_allocation: true,
60-
optimize_rewrite: true,
61-
optimize_remove_nop: true,
62-
}
58+
Self { optimize_local_memory_allocation: true, optimize_rewrite: true, optimize_remove_nop: true }
6359
}
6460
}
6561

@@ -96,7 +92,6 @@ impl ParserOptions {
9692
pub const fn optimize_remove_nop(&self) -> bool {
9793
self.optimize_remove_nop
9894
}
99-
10095
}
10196

10297
/// A WebAssembly parser

crates/parser/src/optimize.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,7 @@ pub(crate) fn optimize_instructions(
1717
track_local_memory_usage: bool,
1818
) -> OptimizeResult {
1919
let uses_local_memory = if options.optimize_rewrite() {
20-
rewrite(
21-
&mut instructions,
22-
self_func_addr,
23-
imported_memory_count,
24-
track_local_memory_usage,
25-
)
20+
rewrite(&mut instructions, self_func_addr, imported_memory_count, track_local_memory_usage)
2621
} else {
2722
track_local_memory_usage
2823
&& instructions.iter().any(|instr| instr.memory_addr().is_some_and(|mem| mem >= imported_memory_count))
@@ -55,28 +50,43 @@ fn rewrite(
5550
rewrite!(instrs, i, [LocalGet32(a), LocalGet32(b)] => BinOpLocalLocal32(op, a, b));
5651
rewrite!(instrs, i, [LocalGet32(local), Const32(c)] => BinOpLocalConst32(op, local, c));
5752
rewrite!(instrs, i, [Const32(c), LocalGet32(local)] => BinOpLocalConst32(op, local, c));
53+
rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal32(op, global)]);
5854
if matches!(op, BinOp::IAdd) {
5955
rewrite!(instrs, i, [Const32(c)] => AddConst32(c));
56+
rewrite!(instrs, i, [I32Add] => [Nop, I32Add3]);
6057
}
6158
}
6259
instr @ (I32Sub | I32Shl | I32ShrS | I32ShrU | I32Rotl | I32Rotr) => {
6360
let Some(op) = int_bin_op_32(instr) else { unreachable!() };
6461
rewrite!(instrs, i, [LocalGet32(a), LocalGet32(b)] => BinOpLocalLocal32(op, a, b));
6562
rewrite!(instrs, i, [LocalGet32(local), Const32(c)] => BinOpLocalConst32(op, local, c));
63+
rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal32(op, global)]);
64+
if matches!(op, BinOp::IShrS) {
65+
rewrite!(instrs, i, [BinOpLocalConst32(BinOp::IShl, local, 8), Const32(8)] => [Nop, LocalGet32(local), I32Extend8S]);
66+
rewrite!(instrs, i, [BinOpLocalConst32(BinOp::IShl, local, 16), Const32(16)] => [Nop, LocalGet32(local), I32Extend16S]);
67+
}
6668
}
6769
instr @ (I64Add | I64Mul | I64And | I64Or | I64Xor) => {
6870
let Some(op) = int_bin_op_64(instr) else { unreachable!() };
6971
rewrite!(instrs, i, [LocalGet64(a), LocalGet64(b)] => BinOpLocalLocal64(op, a, b));
7072
rewrite!(instrs, i, [LocalGet64(local), Const64(c)] => BinOpLocalConst64(op, local, c));
7173
rewrite!(instrs, i, [Const64(c), LocalGet64(local)] => BinOpLocalConst64(op, local, c));
74+
rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal64(op, global)]);
7275
if matches!(op, BinOp::IAdd) {
7376
rewrite!(instrs, i, [Const64(c)] => AddConst64(c));
77+
rewrite!(instrs, i, [I64Add] => [Nop, I64Add3]);
7478
}
7579
}
7680
instr @ (I64Sub | I64Shl | I64ShrS | I64ShrU | I64Rotl | I64Rotr) => {
7781
let Some(op) = int_bin_op_64(instr) else { unreachable!() };
7882
rewrite!(instrs, i, [LocalGet64(a), LocalGet64(b)] => BinOpLocalLocal64(op, a, b));
7983
rewrite!(instrs, i, [LocalGet64(local), Const64(c)] => BinOpLocalConst64(op, local, c));
84+
rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal64(op, global)]);
85+
if matches!(op, BinOp::IShrS) {
86+
rewrite!(instrs, i, [BinOpLocalConst64(BinOp::IShl, local, 8), Const64(8)] => [Nop, LocalGet64(local), I64Extend8S]);
87+
rewrite!(instrs, i, [BinOpLocalConst64(BinOp::IShl, local, 16), Const64(16)] => [Nop, LocalGet64(local), I64Extend16S]);
88+
rewrite!(instrs, i, [BinOpLocalConst64(BinOp::IShl, local, 32), Const64(32)] => [Nop, LocalGet64(local), I64Extend32S]);
89+
}
8090
}
8191
instr @ (F32Add | F32Mul | F32Min | F32Max) => {
8292
let Some(op) = float_bin_op_32(instr) else { unreachable!() };
@@ -111,13 +121,15 @@ fn rewrite(
111121
rewrite!(instrs, i, [LocalGet128(local), Const128(c)] => BinOpLocalConst128(BinOp128::AndNot, local, c));
112122
}
113123
I32Store(memarg) | F32Store(memarg) => {
124+
rewrite!(instrs, i, [F32Mul, F32Add] => [Nop, Nop, FMaStoreF32(memarg)]);
114125
rewrite!(instrs, i,
115126
[LocalGet32(addr_local), LocalGet32(value_local)] if
116127
(let (Ok(addr_local), Ok(value_local)) = (u8::try_from(addr_local), u8::try_from(value_local))) =>
117128
StoreLocalLocal32(memarg, addr_local, value_local)
118129
);
119130
}
120131
I64Store(memarg) | F64Store(memarg) => {
132+
rewrite!(instrs, i, [F64Mul, F64Add] => [Nop, Nop, FMaStoreF64(memarg)]);
121133
rewrite!(instrs, i,
122134
[LocalGet32(addr_local), LocalGet64(value_local)] if
123135
(let (Ok(addr_local), Ok(value_local)) = (u8::try_from(addr_local), u8::try_from(value_local))) =>
@@ -156,6 +168,8 @@ fn rewrite(
156168
_ => Instruction::BinOpLocalConstSet32(op, lhs, imm, dst),
157169
}
158170
);
171+
rewrite!(instrs, i, [I32Mul, LocalGet32(acc), I32Add] if (acc == dst) => [Nop, Nop, Nop, MulAccLocal32(dst)]);
172+
rewrite!(instrs, i, [F32Mul, LocalGet32(acc), F32Add] if (acc == dst) => [Nop, Nop, Nop, FMulAccLocal32(dst)]);
159173
rewrite_local_set_direct!(
160174
instrs,
161175
i,
@@ -193,6 +207,8 @@ fn rewrite(
193207
_ => Instruction::BinOpLocalConstSet64(op, lhs, imm, dst),
194208
}
195209
);
210+
rewrite!(instrs, i, [I64Mul, LocalGet64(acc), I64Add] if (acc == dst) => [Nop, Nop, Nop, MulAccLocal64(dst)]);
211+
rewrite!(instrs, i, [F64Mul, LocalGet64(acc), F64Add] if (acc == dst) => [Nop, Nop, Nop, FMulAccLocal64(dst)]);
196212
rewrite_local_set_direct!(
197213
instrs,
198214
i,

crates/parser/src/visit.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,10 +227,18 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild
227227
if let Some(Instruction::LocalGet64(src)) = last { Some(*src) } else { None }
228228
}
229229
wasmparser::ValType::V128 => {
230-
if let Some(Instruction::LocalGet128(src)) = last { Some(*src) } else { None }
230+
if let Some(Instruction::LocalGet128(src)) = last {
231+
Some(*src)
232+
} else {
233+
None
234+
}
231235
}
232236
wasmparser::ValType::Ref(_) => {
233-
if let Some(Instruction::LocalGet32(src)) = last { Some(*src) } else { None }
237+
if let Some(Instruction::LocalGet32(src)) = last {
238+
Some(*src)
239+
} else {
240+
None
241+
}
234242
}
235243
};
236244

0 commit comments

Comments
 (0)