diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib_string.c | 2 | ||||
| -rw-r--r-- | src/lj_ffrecord.c | 28 | ||||
| -rw-r--r-- | src/lj_ircall.h | 1 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 40 |
4 files changed, 55 insertions, 16 deletions
diff --git a/src/lib_string.c b/src/lib_string.c index 598cd93e..e460e834 100644 --- a/src/lib_string.c +++ b/src/lib_string.c | |||
| @@ -85,7 +85,7 @@ LJLIB_ASM(string_sub) LJLIB_REC(string_range 1) | |||
| 85 | return FFH_RETRY; | 85 | return FFH_RETRY; |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | LJLIB_CF(string_rep) | 88 | LJLIB_CF(string_rep) LJLIB_REC(.) |
| 89 | { | 89 | { |
| 90 | GCstr *s = lj_lib_checkstr(L, 1); | 90 | GCstr *s = lj_lib_checkstr(L, 1); |
| 91 | int32_t rep = lj_lib_checkint(L, 2); | 91 | int32_t rep = lj_lib_checkint(L, 2); |
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 1560d3f5..d66aaa53 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
| @@ -765,6 +765,34 @@ static void LJ_FASTCALL recff_string_char(jit_State *J, RecordFFData *rd) | |||
| 765 | UNUSED(rd); | 765 | UNUSED(rd); |
| 766 | } | 766 | } |
| 767 | 767 | ||
| 768 | static void LJ_FASTCALL recff_string_rep(jit_State *J, RecordFFData *rd) | ||
| 769 | { | ||
| 770 | TRef str = lj_ir_tostr(J, J->base[0]); | ||
| 771 | TRef rep = lj_opt_narrow_toint(J, J->base[1]); | ||
| 772 | TRef hdr, tr, str2 = 0; | ||
| 773 | if (J->base[2]) { | ||
| 774 | TRef sep = lj_ir_tostr(J, J->base[2]); | ||
| 775 | int32_t vrep = argv2int(J, &rd->argv[1]); | ||
| 776 | emitir(IRTGI(vrep > 1 ? IR_GT : IR_LE), rep, lj_ir_kint(J, 1)); | ||
| 777 | if (vrep > 1) { | ||
| 778 | TRef hdr2 = emitir(IRT(IR_BUFHDR, IRT_P32), | ||
| 779 | lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); | ||
| 780 | TRef tr2 = emitir(IRT(IR_BUFPUT, IRT_P32), hdr2, sep); | ||
| 781 | tr2 = emitir(IRT(IR_BUFPUT, IRT_P32), tr2, str); | ||
| 782 | str2 = emitir(IRT(IR_BUFSTR, IRT_STR), tr2, hdr2); | ||
| 783 | } | ||
| 784 | } | ||
| 785 | tr = hdr = emitir(IRT(IR_BUFHDR, IRT_P32), | ||
| 786 | lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); | ||
| 787 | if (str2) { | ||
| 788 | tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, str); | ||
| 789 | str = str2; | ||
| 790 | rep = emitir(IRTI(IR_ADD), rep, lj_ir_kint(J, -1)); | ||
| 791 | } | ||
| 792 | tr = lj_ir_call(J, IRCALL_lj_buf_putstr_rep, tr, str, rep); | ||
| 793 | J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr); | ||
| 794 | } | ||
| 795 | |||
| 768 | static void LJ_FASTCALL recff_string_op(jit_State *J, RecordFFData *rd) | 796 | static void LJ_FASTCALL recff_string_op(jit_State *J, RecordFFData *rd) |
| 769 | { | 797 | { |
| 770 | TRef str = lj_ir_tostr(J, J->base[0]); | 798 | TRef str = lj_ir_tostr(J, J->base[0]); |
diff --git a/src/lj_ircall.h b/src/lj_ircall.h index 3e190c80..f652befd 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h | |||
| @@ -114,6 +114,7 @@ typedef struct CCallInfo { | |||
| 114 | _(ANY, lj_buf_putstr_reverse, 2, FL, P32, 0) \ | 114 | _(ANY, lj_buf_putstr_reverse, 2, FL, P32, 0) \ |
| 115 | _(ANY, lj_buf_putstr_lower, 2, FL, P32, 0) \ | 115 | _(ANY, lj_buf_putstr_lower, 2, FL, P32, 0) \ |
| 116 | _(ANY, lj_buf_putstr_upper, 2, FL, P32, 0) \ | 116 | _(ANY, lj_buf_putstr_upper, 2, FL, P32, 0) \ |
| 117 | _(ANY, lj_buf_putstr_rep, 3, L, P32, 0) \ | ||
| 117 | _(ANY, lj_buf_tostr, 1, FL, STR, 0) \ | 118 | _(ANY, lj_buf_tostr, 1, FL, STR, 0) \ |
| 118 | _(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \ | 119 | _(ANY, lj_tab_new1, 2, FS, TAB, CCI_L) \ |
| 119 | _(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \ | 120 | _(ANY, lj_tab_dup, 2, FS, TAB, CCI_L) \ |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index fc625b84..94d5702f 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -596,18 +596,13 @@ LJFOLDF(bufstr_kfold_cse) | |||
| 596 | if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) { | 596 | if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) { |
| 597 | IRRef ref = J->chain[IR_BUFSTR]; | 597 | IRRef ref = J->chain[IR_BUFSTR]; |
| 598 | while (ref) { | 598 | while (ref) { |
| 599 | IRRef last = fins->op1; | ||
| 600 | IRIns *irs = IR(ref), *ira = fleft, *irb = IR(irs->op1); | 599 | IRIns *irs = IR(ref), *ira = fleft, *irb = IR(irs->op1); |
| 601 | while (ira->o == irb->o && ira->op2 == irb->op2) { | 600 | while (ira->o == irb->o && ira->op2 == irb->op2) { |
| 602 | if (ira->o == IR_BUFHDR && !(ira->op2 & IRBUFHDR_APPEND)) { | 601 | lua_assert(ira->o == IR_BUFHDR || ira->o == IR_BUFPUT || |
| 602 | ira->o == IR_CALLL || ira->o == IR_CARG); | ||
| 603 | if (ira->o == IR_BUFHDR && !(ira->op2 & IRBUFHDR_APPEND)) | ||
| 603 | return ref; /* CSE succeeded. */ | 604 | return ref; /* CSE succeeded. */ |
| 604 | } else if (ira->o == IR_CALLL) { | 605 | ira = IR(ira->op1); |
| 605 | ira = IR(ira->op1); irb = IR(irb->op1); | ||
| 606 | lua_assert(ira->o == IR_CARG && irb->o == IR_CARG); | ||
| 607 | if (ira->op2 != irb->op2) break; | ||
| 608 | } | ||
| 609 | last = ira->op1; | ||
| 610 | ira = IR(last); | ||
| 611 | irb = IR(irb->op1); | 606 | irb = IR(irb->op1); |
| 612 | } | 607 | } |
| 613 | ref = irs->prev; | 608 | ref = irs->prev; |
| @@ -623,17 +618,32 @@ LJFOLDF(bufput_kfold_op) | |||
| 623 | { | 618 | { |
| 624 | if (irref_isk(fleft->op2)) { | 619 | if (irref_isk(fleft->op2)) { |
| 625 | const CCallInfo *ci = &lj_ir_callinfo[fins->op2]; | 620 | const CCallInfo *ci = &lj_ir_callinfo[fins->op2]; |
| 626 | SBuf *sb = &J2G(J)->tmpbuf; | 621 | SBuf *sb = lj_buf_tmp_(J->L); |
| 627 | setsbufL(sb, J->L); | ||
| 628 | lj_buf_reset(sb); | ||
| 629 | sb = ((SBuf * (LJ_FASTCALL *)(SBuf *, GCstr *))ci->func)(sb, | 622 | sb = ((SBuf * (LJ_FASTCALL *)(SBuf *, GCstr *))ci->func)(sb, |
| 630 | ir_kstr(IR(fleft->op2))); | 623 | ir_kstr(IR(fleft->op2))); |
| 631 | fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb)); | ||
| 632 | fins->op1 = fleft->op1; | ||
| 633 | fins->o = IR_BUFPUT; | 624 | fins->o = IR_BUFPUT; |
| 625 | fins->op1 = fleft->op1; | ||
| 626 | fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb)); | ||
| 634 | return RETRYFOLD; | 627 | return RETRYFOLD; |
| 635 | } | 628 | } |
| 636 | return EMITFOLD; /* This is a store and always emitted. */ | 629 | return EMITFOLD; /* Always emit, CSE later. */ |
| 630 | } | ||
| 631 | |||
| 632 | LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_rep) | ||
| 633 | LJFOLDF(bufput_kfold_rep) | ||
| 634 | { | ||
| 635 | if (irref_isk(fleft->op2)) { | ||
| 636 | IRIns *irc = IR(fleft->op1); | ||
| 637 | if (irref_isk(irc->op2)) { | ||
| 638 | SBuf *sb = lj_buf_tmp_(J->L); | ||
| 639 | sb = lj_buf_putstr_rep(sb, ir_kstr(IR(irc->op2)), IR(fleft->op2)->i); | ||
| 640 | fins->o = IR_BUFPUT; | ||
| 641 | fins->op1 = irc->op1; | ||
| 642 | fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb)); | ||
| 643 | return RETRYFOLD; | ||
| 644 | } | ||
| 645 | } | ||
| 646 | return EMITFOLD; /* Always emit, CSE later. */ | ||
| 637 | } | 647 | } |
| 638 | 648 | ||
| 639 | /* -- Constant folding of pointer arithmetic ------------------------------ */ | 649 | /* -- Constant folding of pointer arithmetic ------------------------------ */ |
