diff options
| author | Mike Pall <mike> | 2013-04-23 00:56:03 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2013-04-23 00:56:03 +0200 |
| commit | 557391c3b7110cdb431a26351e87010e7f1a41e9 (patch) | |
| tree | 0e436f0d5fa052097adc38ba4af9ffa624a9766a /src | |
| parent | 2cdf90f0683e4da3afc8554d17859260fdc6b4dc (diff) | |
| download | luajit-557391c3b7110cdb431a26351e87010e7f1a41e9.tar.gz luajit-557391c3b7110cdb431a26351e87010e7f1a41e9.tar.bz2 luajit-557391c3b7110cdb431a26351e87010e7f1a41e9.zip | |
Fuse string creation into concats. Optimize single-char concats.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_asm.c | 29 | ||||
| -rw-r--r-- | src/lj_buf.c | 11 | ||||
| -rw-r--r-- | src/lj_buf.h | 3 | ||||
| -rw-r--r-- | src/lj_ircall.h | 2 |
4 files changed, 37 insertions, 8 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index a550d3b3..e847b8c9 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -1058,14 +1058,22 @@ static void asm_bufhdr(ASMState *as, IRIns *ir) | |||
| 1058 | static void asm_bufput(ASMState *as, IRIns *ir) | 1058 | static void asm_bufput(ASMState *as, IRIns *ir) |
| 1059 | { | 1059 | { |
| 1060 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr]; | 1060 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_buf_putstr]; |
| 1061 | IRRef args[2]; | 1061 | IRRef args[3]; |
| 1062 | IRIns *irs; | 1062 | IRIns *irs; |
| 1063 | int kchar = -1; | ||
| 1063 | if (!ra_used(ir)) return; | 1064 | if (!ra_used(ir)) return; |
| 1064 | args[0] = ir->op1; /* SBuf * */ | 1065 | args[0] = ir->op1; /* SBuf * */ |
| 1065 | args[1] = ir->op2; /* GCstr * */ | 1066 | args[1] = ir->op2; /* GCstr * */ |
| 1066 | irs = IR(ir->op2); | 1067 | irs = IR(ir->op2); |
| 1067 | lua_assert(irt_isstr(irs->t)); | 1068 | lua_assert(irt_isstr(irs->t)); |
| 1068 | if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) { | 1069 | if (irs->o == IR_KGC) { |
| 1070 | GCstr *s = ir_kstr(irs); | ||
| 1071 | if (s->len == 1) { /* Optimize put of single-char string constant. */ | ||
| 1072 | kchar = strdata(s)[0]; | ||
| 1073 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; | ||
| 1074 | args[1] = ASMREF_TMP1; /* int, truncated to char */ | ||
| 1075 | } | ||
| 1076 | } else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) { | ||
| 1069 | if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */ | 1077 | if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */ |
| 1070 | if (LJ_SOFTFP ? (irs+1)->o == IR_HIOP : irt_isnum(IR(irs->op1)->t)) { | 1078 | if (LJ_SOFTFP ? (irs+1)->o == IR_HIOP : irt_isnum(IR(irs->op1)->t)) { |
| 1071 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; | 1079 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; |
| @@ -1075,12 +1083,21 @@ static void asm_bufput(ASMState *as, IRIns *ir) | |||
| 1075 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; | 1083 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; |
| 1076 | args[1] = irs->op1; /* int */ | 1084 | args[1] = irs->op1; /* int */ |
| 1077 | } | 1085 | } |
| 1086 | } else if (irs->o == IR_SNEW) { /* Fuse string allocation. */ | ||
| 1087 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem]; | ||
| 1088 | args[1] = irs->op1; /* const void * */ | ||
| 1089 | args[2] = irs->op2; /* MSize */ | ||
| 1078 | } | 1090 | } |
| 1079 | } | 1091 | } |
| 1080 | asm_setupresult(as, ir, ci); /* SBuf * */ | 1092 | asm_setupresult(as, ir, ci); /* SBuf * */ |
| 1081 | asm_gencall(as, ci, args); | 1093 | asm_gencall(as, ci, args); |
| 1082 | if (args[1] == ASMREF_TMP1) | 1094 | if (args[1] == ASMREF_TMP1) { |
| 1083 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), irs->op1); | 1095 | Reg tmp = ra_releasetmp(as, ASMREF_TMP1); |
| 1096 | if (kchar == -1) | ||
| 1097 | asm_tvptr(as, tmp, irs->op1); | ||
| 1098 | else | ||
| 1099 | ra_allockreg(as, kchar, tmp); | ||
| 1100 | } | ||
| 1084 | } | 1101 | } |
| 1085 | 1102 | ||
| 1086 | static void asm_bufstr(ASMState *as, IRIns *ir) | 1103 | static void asm_bufstr(ASMState *as, IRIns *ir) |
| @@ -2015,11 +2032,11 @@ static void asm_setup_regsp(ASMState *as) | |||
| 2015 | /* fallthrough */ | 2032 | /* fallthrough */ |
| 2016 | #endif | 2033 | #endif |
| 2017 | /* C calls evict all scratch regs and return results in RID_RET. */ | 2034 | /* C calls evict all scratch regs and return results in RID_RET. */ |
| 2018 | case IR_SNEW: case IR_XSNEW: case IR_NEWREF: | 2035 | case IR_SNEW: case IR_XSNEW: case IR_NEWREF: case IR_BUFPUT: |
| 2019 | if (REGARG_NUMGPR < 3 && as->evenspill < 3) | 2036 | if (REGARG_NUMGPR < 3 && as->evenspill < 3) |
| 2020 | as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */ | 2037 | as->evenspill = 3; /* lj_str_new and lj_tab_newkey need 3 args. */ |
| 2021 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: | 2038 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: |
| 2022 | case IR_BUFPUT: case IR_BUFSTR: | 2039 | case IR_BUFSTR: |
| 2023 | ir->prev = REGSP_HINT(RID_RET); | 2040 | ir->prev = REGSP_HINT(RID_RET); |
| 2024 | if (inloop) | 2041 | if (inloop) |
| 2025 | as->modset = RSET_SCRATCH; | 2042 | as->modset = RSET_SCRATCH; |
diff --git a/src/lj_buf.c b/src/lj_buf.c index ef48b580..67525694 100644 --- a/src/lj_buf.c +++ b/src/lj_buf.c | |||
| @@ -58,11 +58,12 @@ char *lj_buf_wmem(char *p, const void *q, MSize len) | |||
| 58 | return p; | 58 | return p; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | void lj_buf_putmem(SBuf *sb, const void *q, MSize len) | 61 | SBuf * lj_buf_putmem(SBuf *sb, const void *q, MSize len) |
| 62 | { | 62 | { |
| 63 | char *p = lj_buf_more(sb, len); | 63 | char *p = lj_buf_more(sb, len); |
| 64 | p = lj_buf_wmem(p, q, len); | 64 | p = lj_buf_wmem(p, q, len); |
| 65 | setsbufP(sb, p); | 65 | setsbufP(sb, p); |
| 66 | return sb; | ||
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | #if LJ_HASJIT | 69 | #if LJ_HASJIT |
| @@ -75,6 +76,14 @@ SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s) | |||
| 75 | return sb; | 76 | return sb; |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 79 | SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c) | ||
| 80 | { | ||
| 81 | char *p = lj_buf_more(sb, 1); | ||
| 82 | *p++ = (char)c; | ||
| 83 | setsbufP(sb, p); | ||
| 84 | return sb; | ||
| 85 | } | ||
| 86 | |||
| 78 | SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k) | 87 | SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k) |
| 79 | { | 88 | { |
| 80 | setsbufP(sb, lj_str_bufint(lj_buf_more(sb, LJ_STR_INTBUF), k)); | 89 | setsbufP(sb, lj_str_bufint(lj_buf_more(sb, LJ_STR_INTBUF), k)); |
diff --git a/src/lj_buf.h b/src/lj_buf.h index e028a434..426ec720 100644 --- a/src/lj_buf.h +++ b/src/lj_buf.h | |||
| @@ -25,9 +25,10 @@ LJ_FUNC void LJ_FASTCALL lj_buf_grow(SBuf *sb, char *en); | |||
| 25 | LJ_FUNC void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb); | 25 | LJ_FUNC void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb); |
| 26 | 26 | ||
| 27 | LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len); | 27 | LJ_FUNC char *lj_buf_wmem(char *p, const void *q, MSize len); |
| 28 | LJ_FUNC void lj_buf_putmem(SBuf *sb, const void *q, MSize len); | 28 | LJ_FUNC SBuf * lj_buf_putmem(SBuf *sb, const void *q, MSize len); |
| 29 | #if LJ_HASJIT | 29 | #if LJ_HASJIT |
| 30 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s); | 30 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putstr(SBuf *sb, GCstr *s); |
| 31 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putchar(SBuf *sb, int c); | ||
| 31 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k); | 32 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putint(SBuf *sb, int32_t k); |
| 32 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o); | 33 | LJ_FUNC SBuf * LJ_FASTCALL lj_buf_putnum(SBuf *sb, cTValue *o); |
| 33 | LJ_FUNC GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb); | 34 | LJ_FUNC GCstr * LJ_FASTCALL lj_buf_tostr(SBuf *sb); |
diff --git a/src/lj_ircall.h b/src/lj_ircall.h index 3b1cc928..46bb54fe 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h | |||
| @@ -105,7 +105,9 @@ typedef struct CCallInfo { | |||
| 105 | _(ANY, lj_strscan_num, 2, FN, INT, 0) \ | 105 | _(ANY, lj_strscan_num, 2, FN, INT, 0) \ |
| 106 | _(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \ | 106 | _(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \ |
| 107 | _(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \ | 107 | _(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \ |
| 108 | _(ANY, lj_buf_putmem, 3, S, P32, 0) \ | ||
| 108 | _(ANY, lj_buf_putstr, 2, FS, P32, 0) \ | 109 | _(ANY, lj_buf_putstr, 2, FS, P32, 0) \ |
| 110 | _(ANY, lj_buf_putchar, 2, FS, P32, 0) \ | ||
| 109 | _(ANY, lj_buf_putint, 2, FS, P32, 0) \ | 111 | _(ANY, lj_buf_putint, 2, FS, P32, 0) \ |
| 110 | _(ANY, lj_buf_putnum, 2, FS, P32, 0) \ | 112 | _(ANY, lj_buf_putnum, 2, FS, P32, 0) \ |
| 111 | _(ANY, lj_buf_tostr, 1, FL, STR, 0) \ | 113 | _(ANY, lj_buf_tostr, 1, FL, STR, 0) \ |
