diff options
author | Mike Pall <mike> | 2013-04-23 00:08:04 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2013-04-23 00:10:01 +0200 |
commit | 2cdf90f0683e4da3afc8554d17859260fdc6b4dc (patch) | |
tree | 7709bdec5c3e562067e792d14b1e3f46df96849d | |
parent | 1ae3e5204b8cbd8b643a5a3ab747211be8fe6fba (diff) | |
download | luajit-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.c | 30 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 28 | ||||
-rw-r--r-- | src/lj_record.c | 9 |
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 | ||
1058 | static void asm_bufput(ASMState *as, IRIns *ir) | 1058 | static 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 | ||
1082 | static void asm_bufstr(ASMState *as, IRIns *ir) | 1086 | static 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) | |||
541 | LJFOLD(BUFPUT any any) | 541 | LJFOLD(BUFPUT any any) |
542 | LJFOLDF(bufput_kgc) | 542 | LJFOLDF(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) | |||
570 | LJFOLDF(bufstr_kfold_cse) | 570 | LJFOLDF(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); |