MCPcopy Create free account
hub / github.com/explodingcamera/tinywasm / rewrite

Function rewrite

crates/parser/src/optimize.rs:31–572  ·  view source on GitHub ↗
(
    instrs: &mut [Instruction],
    function_results: ValueCounts,
    self_func_addr: u32,
    imported_memory_count: u32,
)

Source from the content-addressed store, hash-verified

29}
30
31fn rewrite(
32 instrs: &mut [Instruction],
33 function_results: ValueCounts,
34 self_func_addr: u32,
35 imported_memory_count: u32,
36) -> bool {
37 use Instruction::*;
38 let mut uses_local_memory = false;
39 let return_instr = match function_results {
40 ValueCounts { c32: 0, c64: 0, c128: 0 } => Some(ReturnVoid),
41 ValueCounts { c32: 1, c64: 0, c128: 0 } => Some(Return32),
42 ValueCounts { c32: 0, c64: 1, c128: 0 } => Some(Return64),
43 ValueCounts { c32: 0, c64: 0, c128: 1 } => Some(Return128),
44 _ => None,
45 };
46
47 for i in 0..instrs.len() {
48 match instrs[i] {
49 LocalCopy32(a, b) if a == b => instrs[i] = Nop,
50 LocalCopy64(a, b) if a == b => instrs[i] = Nop,
51 LocalCopy128(a, b) if a == b => instrs[i] = Nop,
52 Call(addr) if addr == self_func_addr => instrs[i] = CallSelf,
53 ReturnCall(addr) if addr == self_func_addr => instrs[i] = ReturnCallSelf,
54 Return if let Some(return_instr) = return_instr => instrs[i] = return_instr,
55 instr @ (I32Add | I32Mul | I32And | I32Or | I32Xor) => {
56 let Some(op) = int_bin_op_32(instr) else { unreachable!() };
57 rewrite!(instrs, i, [LocalGet32(a), LocalGet32(b)] => BinOpLocalLocal32(op, a, b));
58 rewrite!(instrs, i, [LocalGet32(local), Const32(c)] => BinOpLocalConst32(op, local, c));
59 rewrite!(instrs, i, [Const32(c), LocalGet32(local)] => BinOpLocalConst32(op, local, c));
60 rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal32(op, global)]);
61 if matches!(op, BinOp::IAdd) {
62 rewrite!(instrs, i, [Const32(c)] => AddConst32(c));
63 rewrite!(instrs, i, [I32Add] => [Nop, I32Add3]);
64 }
65 }
66 instr @ (I32Sub | I32Shl | I32ShrS | I32ShrU | I32Rotl | I32Rotr) => {
67 let Some(op) = int_bin_op_32(instr) else { unreachable!() };
68 rewrite!(instrs, i, [LocalGet32(a), LocalGet32(b)] => BinOpLocalLocal32(op, a, b));
69 rewrite!(instrs, i, [LocalGet32(local), Const32(c)] => BinOpLocalConst32(op, local, c));
70 rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal32(op, global)]);
71 if matches!(op, BinOp::IShrS) {
72 rewrite!(instrs, i, [BinOpLocalConst32(BinOp::IShl, local, 8), Const32(8)] => [Nop, LocalGet32(local), I32Extend8S]);
73 rewrite!(instrs, i, [BinOpLocalConst32(BinOp::IShl, local, 16), Const32(16)] => [Nop, LocalGet32(local), I32Extend16S]);
74 }
75 }
76 instr @ (I64Add | I64Mul | I64And | I64Or | I64Xor) => {
77 let Some(op) = int_bin_op_64(instr) else { unreachable!() };
78 rewrite!(instrs, i, [LocalGet64(a), LocalGet64(b)] => BinOpLocalLocal64(op, a, b));
79 rewrite!(instrs, i, [LocalGet64(local), Const64(c)] => BinOpLocalConst64(op, local, c));
80 rewrite!(instrs, i, [Const64(c), LocalGet64(local)] => BinOpLocalConst64(op, local, c));
81 rewrite!(instrs, i, [GlobalGet(global)] => [Nop, BinOpStackGlobal64(op, global)]);
82 if matches!(op, BinOp::IAdd) {
83 rewrite!(instrs, i, [Const64(c)] => AddConst64(c));
84 rewrite!(instrs, i, [I64Add] => [Nop, I64Add3]);
85 }
86 }
87 instr @ (I64Sub | I64Shl | I64ShrS | I64ShrU | I64Rotl | I64Rotr) => {
88 let Some(op) = int_bin_op_64(instr) else { unreachable!() };

Callers 1

optimize_instructionsFunction · 0.85

Calls 12

int_bin_op_32Function · 0.85
int_bin_op_64Function · 0.85
float_bin_op_32Function · 0.85
float_bin_op_64Function · 0.85
bin_op_128Function · 0.85
resolve_jump_targetFunction · 0.85
next_non_nopFunction · 0.85
inverse_cmp_opFunction · 0.85
canonicalize_jump_likeFunction · 0.85
memory_addrMethod · 0.80
lenMethod · 0.45

Tested by

no test coverage detected