aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-04-26 22:55:24 +0200
committerMike Pall <mike>2013-04-26 22:55:24 +0200
commit068783bf23ff173e188974b6479503cad15d0952 (patch)
tree4578a811da9264953753882e82a19ce93ad55090
parent9b8db403f28bc8b290f275ea3967d29ebccedde1 (diff)
downloadluajit-068783bf23ff173e188974b6479503cad15d0952.tar.gz
luajit-068783bf23ff173e188974b6479503cad15d0952.tar.bz2
luajit-068783bf23ff173e188974b6479503cad15d0952.zip
Compile string.rep().
-rw-r--r--src/lib_string.c2
-rw-r--r--src/lj_ffrecord.c28
-rw-r--r--src/lj_ircall.h1
-rw-r--r--src/lj_opt_fold.c40
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
88LJLIB_CF(string_rep) 88LJLIB_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
768static 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
768static void LJ_FASTCALL recff_string_op(jit_State *J, RecordFFData *rd) 796static 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
632LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_rep)
633LJFOLDF(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 ------------------------------ */