diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_opt_fold.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 97dad4ff..41e0d1ca 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -578,6 +578,9 @@ LJFOLDF(kfold_strcmp) | |||
578 | ** The compromise is to declare them as loads, emit them like stores and | 578 | ** The compromise is to declare them as loads, emit them like stores and |
579 | ** CSE whole chains manually when the BUFSTR is to be emitted. Any chain | 579 | ** CSE whole chains manually when the BUFSTR is to be emitted. Any chain |
580 | ** fragments left over from CSE are eliminated by DCE. | 580 | ** fragments left over from CSE are eliminated by DCE. |
581 | ** | ||
582 | ** The string buffer methods emit a USE instead of a BUFSTR to keep the | ||
583 | ** chain alive. | ||
581 | */ | 584 | */ |
582 | 585 | ||
583 | LJFOLD(BUFHDR any any) | 586 | LJFOLD(BUFHDR any any) |
@@ -586,18 +589,38 @@ LJFOLDF(bufhdr_merge) | |||
586 | return fins->op2 == IRBUFHDR_WRITE ? CSEFOLD : EMITFOLD; | 589 | return fins->op2 == IRBUFHDR_WRITE ? CSEFOLD : EMITFOLD; |
587 | } | 590 | } |
588 | 591 | ||
589 | LJFOLD(BUFPUT BUFHDR BUFSTR) | 592 | LJFOLD(BUFPUT any BUFSTR) |
590 | LJFOLDF(bufput_append) | 593 | LJFOLDF(bufput_bufstr) |
591 | { | 594 | { |
592 | /* New buffer, no other buffer op inbetween and same buffer? */ | 595 | if ((J->flags & JIT_F_OPT_FWD)) { |
593 | if ((J->flags & JIT_F_OPT_FWD) && | 596 | IRRef hdr = fright->op2; |
594 | fleft->op2 == IRBUFHDR_RESET && | 597 | /* New buffer, no other buffer op inbetween and same buffer? */ |
595 | fleft->prev == fright->op2 && | 598 | if (fleft->o == IR_BUFHDR && fleft->op2 == IRBUFHDR_RESET && |
596 | fleft->op1 == IR(fright->op2)->op1) { | 599 | fleft->prev == hdr && |
597 | IRRef ref = fins->op1; | 600 | fleft->op1 == IR(hdr)->op1) { |
598 | IR(ref)->op2 = IRBUFHDR_APPEND; /* Modify BUFHDR. */ | 601 | IRRef ref = fins->op1; |
599 | IR(ref)->op1 = fright->op1; | 602 | IR(ref)->op2 = IRBUFHDR_APPEND; /* Modify BUFHDR. */ |
600 | return ref; | 603 | IR(ref)->op1 = fright->op1; |
604 | return ref; | ||
605 | } | ||
606 | /* Replay puts to global temporary buffer. */ | ||
607 | if (IR(hdr)->op2 == IRBUFHDR_RESET) { | ||
608 | IRIns *ir = IR(fright->op1); | ||
609 | /* For now only handle single string.reverse .lower .upper .rep. */ | ||
610 | if (ir->o == IR_CALLL && | ||
611 | ir->op2 >= IRCALL_lj_buf_putstr_reverse && | ||
612 | ir->op2 <= IRCALL_lj_buf_putstr_rep) { | ||
613 | IRIns *carg1 = IR(ir->op1); | ||
614 | if (ir->op2 == IRCALL_lj_buf_putstr_rep) { | ||
615 | IRIns *carg2 = IR(carg1->op1); | ||
616 | if (carg2->op1 == hdr) { | ||
617 | return lj_ir_call(J, ir->op2, fins->op1, carg2->op2, carg1->op2); | ||
618 | } | ||
619 | } else if (carg1->op1 == hdr) { | ||
620 | return lj_ir_call(J, ir->op2, fins->op1, carg1->op2); | ||
621 | } | ||
622 | } | ||
623 | } | ||
601 | } | 624 | } |
602 | return EMITFOLD; /* Always emit, CSE later. */ | 625 | return EMITFOLD; /* Always emit, CSE later. */ |
603 | } | 626 | } |
@@ -2285,6 +2308,18 @@ LJFOLDF(fload_str_len_tostr) | |||
2285 | return NEXTFOLD; | 2308 | return NEXTFOLD; |
2286 | } | 2309 | } |
2287 | 2310 | ||
2311 | LJFOLD(FLOAD any IRFL_SBUF_W) | ||
2312 | LJFOLD(FLOAD any IRFL_SBUF_E) | ||
2313 | LJFOLD(FLOAD any IRFL_SBUF_B) | ||
2314 | LJFOLD(FLOAD any IRFL_SBUF_L) | ||
2315 | LJFOLD(FLOAD any IRFL_SBUF_REF) | ||
2316 | LJFOLD(FLOAD any IRFL_SBUF_R) | ||
2317 | LJFOLDF(fload_sbuf) | ||
2318 | { | ||
2319 | TRef tr = lj_opt_fwd_fload(J); | ||
2320 | return lj_opt_fwd_sbuf(J, tref_ref(tr)) ? tr : EMITFOLD; | ||
2321 | } | ||
2322 | |||
2288 | /* The C type ID of cdata objects is immutable. */ | 2323 | /* The C type ID of cdata objects is immutable. */ |
2289 | LJFOLD(FLOAD KGC IRFL_CDATA_CTYPEID) | 2324 | LJFOLD(FLOAD KGC IRFL_CDATA_CTYPEID) |
2290 | LJFOLDF(fload_cdata_typeid_kgc) | 2325 | LJFOLDF(fload_cdata_typeid_kgc) |