@@ -264,6 +264,40 @@ bool Optimizer::detect_rewrite_NEWC_PUSH_STUR() {
264264 return true ;
265265}
266266
267+ // pattern `N LDU` + `DROP` -> `N PLDU` (common after loading the last field manually or by `lazy`);
268+ // the same for LDI -> PLDI, LDREF -> PLDREF, etc.
269+ bool Optimizer::detect_rewrite_LDxx_DROP () {
270+ bool second_drop = pb_ > 1 && op_[1 ]->is_pop () && op_[1 ]->a == 0 ;
271+ if (!second_drop || !op_[0 ]->is_custom ()) {
272+ return false ;
273+ }
274+
275+ static const char * ends_with[] = { " LDI" , " LDU" , " LDBITS" };
276+ static const char * repl_with[] = {" PLDI" , " PLDU" , " PLDBITS" };
277+ static const char * equl_to[] = { " LDREF" , " LDDICT" , " LDOPTREF" , " LDSLICEX" };
278+ static const char * repl_to[] = {" PLDREF" , " PLDDICT" , " PLDOPTREF" , " PLDSLICEX" };
279+
280+ std::string_view f = op_[0 ]->op ;
281+ for (size_t i = 0 ; i < std::size (ends_with); ++i) {
282+ if (f.ends_with (ends_with[i])) {
283+ p_ = 2 ;
284+ q_ = 1 ;
285+ oq_[0 ] = std::make_unique<AsmOp>(AsmOp::Custom (op_[0 ]->loc , op_[0 ]->op .substr (0 , f.rfind (' ' )) + repl_with[i], 0 , 1 ));
286+ return true ;
287+ }
288+ }
289+ for (size_t i = 0 ; i < std::size (equl_to); ++i) {
290+ if (f == equl_to[i]) {
291+ p_ = 2 ;
292+ q_ = 1 ;
293+ oq_[0 ] = std::make_unique<AsmOp>(AsmOp::Custom (op_[0 ]->loc , repl_to[i], 0 , 1 ));
294+ return true ;
295+ }
296+ }
297+
298+ return false ;
299+ }
300+
267301
268302bool Optimizer::is_push_const (int * i, int * c) const {
269303 return pb_ >= 3 && pb_ <= l2_ && tr_[pb_ - 1 ].is_push_const (i, c);
@@ -685,6 +719,7 @@ bool Optimizer::find_at_least(int pb) {
685719 (is_xchg_xchg (&i, &j, &k, &l) && rewrite (AsmOp::Xchg (loc, i, j), AsmOp::Xchg (loc, k, l))) ||
686720 detect_rewrite_big_THROW () ||
687721 detect_rewrite_MY_store_int () || detect_rewrite_MY_skip_bits () || detect_rewrite_NEWC_PUSH_STUR () ||
722+ detect_rewrite_LDxx_DROP () ||
688723 (!(mode_ & 1 ) &&
689724 ((is_rot () && rewrite (AsmOp::Custom (loc, " ROT" , 3 , 3 ))) || (is_rotrev () && rewrite (AsmOp::Custom (loc, " -ROT" , 3 , 3 ))) ||
690725 (is_2dup () && rewrite (AsmOp::Custom (loc, " 2DUP" , 2 , 4 ))) ||
0 commit comments