diff options
author | Mike Pall <mike> | 2013-04-26 22:55:24 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2013-04-26 22:55:24 +0200 |
commit | 068783bf23ff173e188974b6479503cad15d0952 (patch) | |
tree | 4578a811da9264953753882e82a19ce93ad55090 | |
parent | 9b8db403f28bc8b290f275ea3967d29ebccedde1 (diff) | |
download | luajit-068783bf23ff173e188974b6479503cad15d0952.tar.gz luajit-068783bf23ff173e188974b6479503cad15d0952.tar.bz2 luajit-068783bf23ff173e188974b6479503cad15d0952.zip |
Compile string.rep().
-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 ------------------------------ */ |