aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-04-23 00:08:04 +0200
committerMike Pall <mike>2013-04-23 00:10:01 +0200
commit2cdf90f0683e4da3afc8554d17859260fdc6b4dc (patch)
tree7709bdec5c3e562067e792d14b1e3f46df96849d
parent1ae3e5204b8cbd8b643a5a3ab747211be8fe6fba (diff)
downloadluajit-2cdf90f0683e4da3afc8554d17859260fdc6b4dc.tar.gz
luajit-2cdf90f0683e4da3afc8554d17859260fdc6b4dc.tar.bz2
luajit-2cdf90f0683e4da3afc8554d17859260fdc6b4dc.zip
Always emit TOSTR for non-string CAT operands. Fuse in backend.
-rw-r--r--src/lj_asm.c30
-rw-r--r--src/lj_opt_fold.c28
-rw-r--r--src/lj_record.c9
3 files changed, 35 insertions, 32 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 7ebde7b8..a550d3b3 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1057,26 +1057,30 @@ static void asm_bufhdr(ASMState *as, IRIns *ir)
1057 1057
1058static void asm_bufput(ASMState *as, IRIns *ir) 1058static void asm_bufput(ASMState *as, IRIns *ir)
1059{ 1059{
1060 const CCallInfo *ci; 1060 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr];
1061 IRRef args[2]; 1061 IRRef args[2];
1062 IRIns *ir2; 1062 IRIns *irs;
1063 if (!ra_used(ir)) return; 1063 if (!ra_used(ir)) return;
1064 args[0] = ir->op1; /* SBuf * */ 1064 args[0] = ir->op1; /* SBuf * */
1065 args[1] = ir->op2; /* int, double, GCstr * */ 1065 args[1] = ir->op2; /* GCstr * */
1066 ir2 = IR(ir->op2); 1066 irs = IR(ir->op2);
1067 if (irt_isstr(ir2->t)) { 1067 lua_assert(irt_isstr(irs->t));
1068 ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr]; 1068 if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) {
1069 } else if (LJ_SOFTFP ? irt_type((ir2+1)->t)==IRT_SOFTFP : irt_isnum(ir2->t)) { 1069 if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */
1070 ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; 1070 if (LJ_SOFTFP ? (irs+1)->o == IR_HIOP : irt_isnum(IR(irs->op1)->t)) {
1071 args[1] = ASMREF_TMP1; 1071 ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum];
1072 } else { 1072 args[1] = ASMREF_TMP1; /* TValue * */
1073 lua_assert(irt_isinteger(ir2->t)); 1073 } else {
1074 ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; 1074 lua_assert(irt_isinteger(IR(irs->op1)->t));
1075 ci = &lj_ir_callinfo[IRCALL_lj_buf_putint];
1076 args[1] = irs->op1; /* int */
1077 }
1078 }
1075 } 1079 }
1076 asm_setupresult(as, ir, ci); /* SBuf * */ 1080 asm_setupresult(as, ir, ci); /* SBuf * */
1077 asm_gencall(as, ci, args); 1081 asm_gencall(as, ci, args);
1078 if (args[1] == ASMREF_TMP1) 1082 if (args[1] == ASMREF_TMP1)
1079 asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2); 1083 asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), irs->op1);
1080} 1084}
1081 1085
1082static void asm_bufstr(ASMState *as, IRIns *ir) 1086static void asm_bufstr(ASMState *as, IRIns *ir)
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index fc91a75e..e3194f76 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -541,13 +541,13 @@ LJFOLDF(bufput_append)
541LJFOLD(BUFPUT any any) 541LJFOLD(BUFPUT any any)
542LJFOLDF(bufput_kgc) 542LJFOLDF(bufput_kgc)
543{ 543{
544 if (fright->o == IR_KGC) { 544 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && fright->o == IR_KGC) {
545 GCstr *s2 = ir_kstr(fright); 545 GCstr *s2 = ir_kstr(fright);
546 MSize len2 = s2->len; 546 MSize len2 = s2->len;
547 if (len2 == 0) { /* Empty string? */ 547 if (len2 == 0) { /* Empty string? */
548 return LEFTFOLD; 548 return LEFTFOLD;
549 } else { 549 } else {
550 if (fleft->o == IR_BUFPUT && IR(fleft->op2)->o == IR_KGC && 550 if (fleft->o == IR_BUFPUT && irref_isk(fleft->op2) &&
551 !irt_isphi(fleft->t)) { 551 !irt_isphi(fleft->t)) {
552 /* Join two constant string puts in a row. */ 552 /* Join two constant string puts in a row. */
553 GCstr *s1 = ir_kstr(IR(fleft->op2)); 553 GCstr *s1 = ir_kstr(IR(fleft->op2));
@@ -570,20 +570,16 @@ LJFOLD(BUFSTR any any)
570LJFOLDF(bufstr_kfold_cse) 570LJFOLDF(bufstr_kfold_cse)
571{ 571{
572 lua_assert(fright->o == IR_BUFHDR || fright->o == IR_BUFPUT); 572 lua_assert(fright->o == IR_BUFHDR || fright->o == IR_BUFPUT);
573 if (fright->o == IR_BUFHDR) { /* No put operations? */ 573 if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
574 if (!(fright->op2 & IRBUFHDR_APPEND)) /* Empty buffer? */ 574 if (fright->o == IR_BUFHDR) { /* No put operations? */
575 return lj_ir_kstr(J, &J2G(J)->strempty); 575 if (!(fright->op2 & IRBUFHDR_APPEND)) /* Empty buffer? */
576 fins->op2 = fright->prev; /* Relies on checks in bufput_append. */ 576 return lj_ir_kstr(J, &J2G(J)->strempty);
577 return CSEFOLD; 577 fins->op2 = fright->prev; /* Relies on checks in bufput_append. */
578 } else { 578 return CSEFOLD;
579 /* Shortcut for a single put operation. */ 579 } else {
580 IRIns *irb = IR(fright->op1); 580 IRIns *irb = IR(fright->op1);
581 if (irb->o == IR_BUFHDR && !(irb->op2 & IRBUFHDR_APPEND)) { 581 if (irb->o == IR_BUFHDR && !(irb->op2 & IRBUFHDR_APPEND))
582 IRRef ref = fright->op2; 582 return fright->op2; /* Shortcut for a single put operation. */
583 if (irt_isstr(IR(ref)->t))
584 return ref;
585 lua_assert(irt_isinteger(IR(ref)->t) || irt_isnum(IR(ref)->t));
586 return emitir(IRT(IR_TOSTR, IRT_STR), ref, 0);
587 } 583 }
588 } 584 }
589 /* Try to CSE the whole chain. */ 585 /* Try to CSE the whole chain. */
diff --git a/src/lj_record.c b/src/lj_record.c
index bbabd3ce..bafb6ff7 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -1608,10 +1608,13 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
1608 lua_assert(baseslot < topslot); 1608 lua_assert(baseslot < topslot);
1609 if (tref_isnumber_str(tr) && tref_isnumber_str(*(top-1))) { 1609 if (tref_isnumber_str(tr) && tref_isnumber_str(*(top-1))) {
1610 TRef hdr, *trp, *xbase, *base = &J->base[baseslot]; 1610 TRef hdr, *trp, *xbase, *base = &J->base[baseslot];
1611 /* First convert number consts to string consts to simplify FOLD rules. */ 1611 /* First convert numbers to strings. */
1612 for (trp = top; trp >= base && tref_isnumber_str(*trp); trp--) 1612 for (trp = top; trp >= base; trp--) {
1613 if (tref_isk(*trp) && tref_isnumber(*trp)) 1613 if (tref_isnumber(*trp))
1614 *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp, 0); 1614 *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp, 0);
1615 else if (!tref_isstr(*trp))
1616 break;
1617 }
1615 xbase = ++trp; 1618 xbase = ++trp;
1616 tr = hdr = emitir(IRT(IR_BUFHDR, IRT_P32), 1619 tr = hdr = emitir(IRT(IR_BUFHDR, IRT_P32),
1617 lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); 1620 lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET);