aboutsummaryrefslogtreecommitdiff
path: root/src/lj_opt_fold.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_opt_fold.c57
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
583LJFOLD(BUFHDR any any) 586LJFOLD(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
589LJFOLD(BUFPUT BUFHDR BUFSTR) 592LJFOLD(BUFPUT any BUFSTR)
590LJFOLDF(bufput_append) 593LJFOLDF(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
2311LJFOLD(FLOAD any IRFL_SBUF_W)
2312LJFOLD(FLOAD any IRFL_SBUF_E)
2313LJFOLD(FLOAD any IRFL_SBUF_B)
2314LJFOLD(FLOAD any IRFL_SBUF_L)
2315LJFOLD(FLOAD any IRFL_SBUF_REF)
2316LJFOLD(FLOAD any IRFL_SBUF_R)
2317LJFOLDF(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. */
2289LJFOLD(FLOAD KGC IRFL_CDATA_CTYPEID) 2324LJFOLD(FLOAD KGC IRFL_CDATA_CTYPEID)
2290LJFOLDF(fload_cdata_typeid_kgc) 2325LJFOLDF(fload_cdata_typeid_kgc)