@@ -2,18 +2,32 @@ use crate::macros::optimize::*;
22use alloc:: vec:: Vec ;
33use tinywasm_types:: { CmpOp , Instruction , WasmFunctionData } ;
44
5+ pub ( crate ) struct OptimizeResult {
6+ pub ( crate ) instructions : Vec < Instruction > ,
7+ pub ( crate ) uses_local_memory : bool ,
8+ }
9+
510pub ( crate ) fn optimize_instructions (
611 mut instructions : Vec < Instruction > ,
712 function_data : & mut WasmFunctionData ,
813 self_func_addr : u32 ,
9- ) -> Vec < Instruction > {
10- rewrite ( & mut instructions, self_func_addr) ;
14+ imported_memory_count : u32 ,
15+ track_local_memory_usage : bool ,
16+ ) -> OptimizeResult {
17+ let uses_local_memory = rewrite ( & mut instructions, self_func_addr, imported_memory_count, track_local_memory_usage) ;
1118 remove_nop ( & mut instructions, function_data) ;
12- instructions
19+ OptimizeResult { instructions, uses_local_memory }
1320}
1421
15- fn rewrite ( instrs : & mut [ Instruction ] , self_func_addr : u32 ) {
22+ fn rewrite (
23+ instrs : & mut [ Instruction ] ,
24+ self_func_addr : u32 ,
25+ imported_memory_count : u32 ,
26+ track_local_memory_usage : bool ,
27+ ) -> bool {
1628 use Instruction :: * ;
29+ let mut uses_local_memory = false ;
30+
1731 for i in 0 ..instrs. len ( ) {
1832 match instrs[ i] {
1933 LocalCopy32 ( a, b) if a == b => instrs[ i] = Nop ,
@@ -22,14 +36,14 @@ fn rewrite(instrs: &mut [Instruction], self_func_addr: u32) {
2236 Call ( addr) if addr == self_func_addr => instrs[ i] = CallSelf ,
2337 ReturnCall ( addr) if addr == self_func_addr => instrs[ i] = ReturnCallSelf ,
2438 I32Add => {
25- rewrite ! ( instrs, i, [ I32Const ( c) ] => AddConst32 ( c) ) ;
2639 rewrite ! ( instrs, i, [ LocalGet32 ( a) , LocalGet32 ( b) ] => AddLocalLocal32 ( a, b) ) ;
2740 rewrite ! ( instrs, i, [ LocalGet32 ( local) , I32Const ( c) ] => [ Nop , LocalGet32 ( local) , AddConst32 ( c) ] ) ;
41+ rewrite ! ( instrs, i, [ I32Const ( c) ] => AddConst32 ( c) ) ;
2842 }
2943 I64Add => {
30- rewrite ! ( instrs, i, [ I64Const ( c) ] => AddConst64 ( c) ) ;
3144 rewrite ! ( instrs, i, [ LocalGet64 ( a) , LocalGet64 ( b) ] => AddLocalLocal64 ( a, b) ) ;
3245 rewrite ! ( instrs, i, [ LocalGet64 ( local) , I64Const ( c) ] => [ Nop , LocalGet64 ( local) , AddConst64 ( c) ] ) ;
46+ rewrite ! ( instrs, i, [ I64Const ( c) ] => AddConst64 ( c) ) ;
3347 }
3448 I64Rotl => rewrite ! ( instrs, i, [ I64Xor , I64Const ( c) ] => XorRotlConst64 ( c) ) ,
3549 I32Store ( memarg) => {
@@ -69,6 +83,7 @@ fn rewrite(instrs: &mut [Instruction], self_func_addr: u32) {
6983 rewrite ! ( instrs, i, [ LocalGet32 ( src) ] => if src == dst { Nop } else { LocalCopy32 ( src, dst) } ) ;
7084 rewrite ! ( instrs, i, [ I32Const ( c) ] => SetLocalConst32 ( dst, c) ) ;
7185 rewrite ! ( instrs, i, [ F32Const ( c) ] => SetLocalConst32 ( dst, i32 :: from_ne_bytes( c. to_bits( ) . to_ne_bytes( ) ) ) ) ;
86+ rewrite ! ( instrs, i, [ AddLocalLocal32 ( a, b) ] => AddLocalLocalSet32 ( a, b, dst) ) ;
7287 rewrite ! ( instrs, i, [ LocalGet32 ( src) , AddConst32 ( c) ] if ( src == dst) => AddLocalConst32 ( dst, c) ) ;
7388 rewrite ! ( instrs, i, [ LoadLocal32 ( memarg, addr) ] if ( let Ok ( dst) = u8 :: try_from( dst) ) => LoadLocalSet32 ( memarg, addr, dst) ) ;
7489 rewrite ! ( instrs, i,
@@ -81,6 +96,7 @@ fn rewrite(instrs: &mut [Instruction], self_func_addr: u32) {
8196 rewrite ! ( instrs, i, [ LocalGet64 ( src) ] => if src == dst { Nop } else { LocalCopy64 ( src, dst) } ) ;
8297 rewrite ! ( instrs, i, [ I64Const ( c) ] => SetLocalConst64 ( dst, c) ) ;
8398 rewrite ! ( instrs, i, [ F64Const ( c) ] => SetLocalConst64 ( dst, i64 :: from_ne_bytes( c. to_bits( ) . to_ne_bytes( ) ) ) ) ;
99+ rewrite ! ( instrs, i, [ AddLocalLocal64 ( a, b) ] => AddLocalLocalSet64 ( a, b, dst) ) ;
84100 rewrite ! ( instrs, i,
85101 [ LocalGet64 ( src) , AddConst64 ( c) ] if ( src == dst) =>
86102 AddLocalConst64 ( dst, c)
@@ -130,62 +146,68 @@ fn rewrite(instrs: &mut [Instruction], self_func_addr: u32) {
130146 replace!( instrs, i, 1 => [ Nop , JumpIfNonZero ( ip) ] ) ;
131147 continue ;
132148 } ) ;
133- rewrite ! ( instrs, i, [ cmp, I32Const ( imm) ] if ( let Some ( op) = cmp_op( cmp) ) =>
134- JumpCmpStackConst32 { target_ip: ip, imm, op: inverse_cmp_op( op) }
135- ) ;
136- rewrite ! ( instrs, i, [ cmp, I64Const ( imm) ] if ( let Some ( op) = cmp_op_64( cmp) ) =>
137- JumpCmpStackConst64 { target_ip: ip, imm, op: inverse_cmp_op( op) }
138- ) ;
139149 rewrite ! ( instrs, i,
140- [ LocalGet32 ( local) , cmp , I32Const ( imm) ] if ( let Some ( op) = cmp_op( cmp) ) =>
150+ [ LocalGet32 ( local) , I32Const ( imm) , cmp ] if ( let Some ( op) = cmp_op( cmp) ) =>
141151 JumpCmpLocalConst32 { target_ip: ip, local, imm, op: inverse_cmp_op( op) }
142152 ) ;
143153 rewrite ! ( instrs, i,
144- [ LocalGet64 ( local) , cmp , I64Const ( imm) ] if
154+ [ LocalGet64 ( local) , I64Const ( imm) , cmp ] if
145155 ( let Some ( op) = cmp_op_64( cmp) && let Ok ( imm) = i32 :: try_from( imm) ) =>
146156 JumpCmpLocalConst64 { target_ip: ip, local, imm, op: inverse_cmp_op( op) }
147157 ) ;
148158 rewrite ! ( instrs, i,
149- [ LocalGet32 ( left) , cmp , LocalGet32 ( right) ] if ( let Some ( op) = cmp_op( cmp) ) =>
159+ [ LocalGet32 ( left) , LocalGet32 ( right) , cmp ] if ( let Some ( op) = cmp_op( cmp) ) =>
150160 JumpCmpLocalLocal32 { target_ip: ip, left, right, op: inverse_cmp_op( op) }
151161 ) ;
152162 rewrite ! ( instrs, i,
153- [ LocalGet64 ( left) , cmp , LocalGet64 ( right) ] if ( let Some ( op) = cmp_op_64( cmp) ) =>
163+ [ LocalGet64 ( left) , LocalGet64 ( right) , cmp ] if ( let Some ( op) = cmp_op_64( cmp) ) =>
154164 JumpCmpLocalLocal64 { target_ip: ip, left, right, op: inverse_cmp_op( op) }
155165 ) ;
166+ rewrite ! ( instrs, i, [ I32Const ( imm) , cmp] if ( let Some ( op) = cmp_op( cmp) ) =>
167+ JumpCmpStackConst32 { target_ip: ip, imm, op: inverse_cmp_op( op) }
168+ ) ;
169+ rewrite ! ( instrs, i, [ I64Const ( imm) , cmp] if ( let Some ( op) = cmp_op_64( cmp) ) =>
170+ JumpCmpStackConst64 { target_ip: ip, imm, op: inverse_cmp_op( op) }
171+ ) ;
156172 }
157173 JumpIfNonZero ( ip) => {
158174 rewrite ! ( instrs, i, [ I32Eqz ] => {
159175 replace!( instrs, i, 1 => [ Nop , JumpIfZero ( ip) ] ) ;
160176 continue ;
161177 } ) ;
162- rewrite ! ( instrs, i, [ cmp, I32Const ( imm) ] if ( let Some ( op) = cmp_op( cmp) ) =>
163- JumpCmpStackConst32 { target_ip: ip, imm, op }
164- ) ;
165- rewrite ! ( instrs, i, [ cmp, I64Const ( imm) ] if ( let Some ( op) = cmp_op_64( cmp) ) =>
166- JumpCmpStackConst64 { target_ip: ip, imm, op }
167- ) ;
168178 rewrite ! ( instrs, i,
169- [ LocalGet32 ( local) , cmp , I32Const ( imm) ] if ( let Some ( op) = cmp_op( cmp) ) =>
179+ [ LocalGet32 ( local) , I32Const ( imm) , cmp ] if ( let Some ( op) = cmp_op( cmp) ) =>
170180 JumpCmpLocalConst32 { target_ip: ip, local, imm, op }
171181 ) ;
172182 rewrite ! ( instrs, i,
173- [ LocalGet64 ( local) , cmp , I64Const ( imm) ] if
183+ [ LocalGet64 ( local) , I64Const ( imm) , cmp ] if
174184 ( let Some ( op) = cmp_op_64( cmp) && let Ok ( imm) = i32 :: try_from( imm) ) =>
175185 JumpCmpLocalConst64 { target_ip: ip, local, imm, op }
176186 ) ;
177187 rewrite ! ( instrs, i,
178- [ LocalGet32 ( left) , cmp , LocalGet32 ( right) ] if ( let Some ( op) = cmp_op( cmp) ) =>
188+ [ LocalGet32 ( left) , LocalGet32 ( right) , cmp ] if ( let Some ( op) = cmp_op( cmp) ) =>
179189 JumpCmpLocalLocal32 { target_ip: ip, left, right, op }
180190 ) ;
181191 rewrite ! ( instrs, i,
182- [ LocalGet64 ( left) , cmp , LocalGet64 ( right) ] if ( let Some ( op) = cmp_op_64( cmp) ) =>
192+ [ LocalGet64 ( left) , LocalGet64 ( right) , cmp ] if ( let Some ( op) = cmp_op_64( cmp) ) =>
183193 JumpCmpLocalLocal64 { target_ip: ip, left, right, op }
184194 ) ;
195+ rewrite ! ( instrs, i, [ I32Const ( imm) , cmp] if ( let Some ( op) = cmp_op( cmp) ) =>
196+ JumpCmpStackConst32 { target_ip: ip, imm, op }
197+ ) ;
198+ rewrite ! ( instrs, i, [ I64Const ( imm) , cmp] if ( let Some ( op) = cmp_op_64( cmp) ) =>
199+ JumpCmpStackConst64 { target_ip: ip, imm, op }
200+ ) ;
185201 }
186202 _ => { }
187203 }
204+
205+ if track_local_memory_usage {
206+ uses_local_memory |= instrs[ i] . memory_addr ( ) . is_some_and ( |mem| mem >= imported_memory_count) ;
207+ }
188208 }
209+
210+ uses_local_memory
189211}
190212
191213fn cmp_op ( instr : Instruction ) -> Option < CmpOp > {
0 commit comments