diff options
author | Mike Pall <mike> | 2011-02-03 04:13:51 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-03 04:22:27 +0100 |
commit | df65b8b419c12327254dec0df116c62525aaabad (patch) | |
tree | b4ba6ea2841692123b49b3033420dbb7282cbcd6 /src/lj_asm.c | |
parent | 1027018b2135caf45057c3d3b3da03ffb0c6add3 (diff) | |
download | luajit-df65b8b419c12327254dec0df116c62525aaabad.tar.gz luajit-df65b8b419c12327254dec0df116c62525aaabad.tar.bz2 luajit-df65b8b419c12327254dec0df116c62525aaabad.zip |
FFI: Rename IR_CNEWP to IR_CNEWI and use it to box 64 bit integers.
Generates smaller IR and DCE eliminates many intermediate boxes.
Needs allocation sinking to eliminate the boxes kept alive by PHIs.
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r-- | src/lj_asm.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 8864c9a3..77b55f0c 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -2518,7 +2518,7 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
2518 | { | 2518 | { |
2519 | CTState *cts = ctype_ctsG(J2G(as->J)); | 2519 | CTState *cts = ctype_ctsG(J2G(as->J)); |
2520 | CTypeID typeid = (CTypeID)IR(ir->op1)->i; | 2520 | CTypeID typeid = (CTypeID)IR(ir->op1)->i; |
2521 | CTSize sz = (ir->o == IR_CNEWP || ir->op2 == REF_NIL) ? | 2521 | CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ? |
2522 | lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i; | 2522 | lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i; |
2523 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; | 2523 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; |
2524 | IRRef args[2]; | 2524 | IRRef args[2]; |
@@ -2529,33 +2529,45 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
2529 | as->gcsteps++; | 2529 | as->gcsteps++; |
2530 | asm_setupresult(as, ir, ci); /* GCcdata * */ | 2530 | asm_setupresult(as, ir, ci); /* GCcdata * */ |
2531 | 2531 | ||
2532 | /* Initialize pointer cdata object. */ | 2532 | /* Initialize immutable cdata object. */ |
2533 | if (ir->o == IR_CNEWP) { | 2533 | if (ir->o == IR_CNEWI) { |
2534 | RegSet allow = (RSET_GPR & ~RSET_SCRATCH); | ||
2535 | #if LJ_64 | ||
2536 | Reg r64 = sz == 8 ? REX_64 : 0; | ||
2534 | if (irref_isk(ir->op2)) { | 2537 | if (irref_isk(ir->op2)) { |
2535 | IRIns *irk = IR(ir->op2); | 2538 | IRIns *irk = IR(ir->op2); |
2536 | #if LJ_64 | 2539 | uint64_t k = irk->o == IR_KINT64 ? ir_k64(irk)->u64 : |
2537 | if (irk->o == IR_KINT64) { | 2540 | (uint64_t)(uint32_t)irk->i; |
2538 | uint64_t k = ir_k64(irk)->u64; | 2541 | if (sz == 4 || checki32((int64_t)k)) { |
2539 | lua_assert(sz == 8); | 2542 | emit_i32(as, (int32_t)k); |
2540 | if (checki32((int64_t)k)) { | 2543 | emit_rmro(as, XO_MOVmi, r64, RID_RET, sizeof(GCcdata)); |
2541 | emit_i32(as, (int32_t)k); | ||
2542 | emit_rmro(as, XO_MOVmi, REX_64, RID_RET, sizeof(GCcdata)); | ||
2543 | } else { | ||
2544 | emit_movtomro(as, RID_ECX|REX_64, RID_RET, sizeof(GCcdata)); | ||
2545 | emit_loadu64(as, RID_ECX, k); | ||
2546 | } | ||
2547 | } else { | 2544 | } else { |
2548 | #endif | 2545 | emit_movtomro(as, RID_ECX + r64, RID_RET, sizeof(GCcdata)); |
2549 | lua_assert(sz == 4); | 2546 | emit_loadu64(as, RID_ECX, k); |
2550 | emit_movmroi(as, RID_RET, sizeof(GCcdata), irk->i); | ||
2551 | #if LJ_64 | ||
2552 | } | 2547 | } |
2553 | #endif | ||
2554 | } else { | 2548 | } else { |
2555 | Reg r = ra_alloc1(as, ir->op2, (RSET_GPR & ~RSET_SCRATCH)); | 2549 | Reg r = ra_alloc1(as, ir->op2, allow); |
2556 | emit_movtomro(as, r + ((LJ_64 && sz == 8) ? REX_64 : 0), | 2550 | emit_movtomro(as, r + r64, RID_RET, sizeof(GCcdata)); |
2557 | RID_RET, sizeof(GCcdata)); | 2551 | } |
2552 | #else | ||
2553 | int32_t ofs = sizeof(GCcdata); | ||
2554 | if (LJ_HASFFI && sz == 8) { | ||
2555 | ofs += 4; ir++; | ||
2556 | lua_assert(ir->o == IR_HIOP); | ||
2558 | } | 2557 | } |
2558 | do { | ||
2559 | if (irref_isk(ir->op2)) { | ||
2560 | emit_movmroi(as, RID_RET, ofs, IR(ir->op2)->i); | ||
2561 | } else { | ||
2562 | Reg r = ra_alloc1(as, ir->op2, allow); | ||
2563 | emit_movtomro(as, r, RID_RET, ofs); | ||
2564 | rset_clear(allow, r); | ||
2565 | } | ||
2566 | if (!LJ_HASFFI || ofs == sizeof(GCcdata)) break; | ||
2567 | ofs -= 4; ir--; | ||
2568 | } while (1); | ||
2569 | #endif | ||
2570 | lua_assert(sz == 4 || (sz == 8 && (LJ_64 || LJ_HASFFI))); | ||
2559 | } | 2571 | } |
2560 | 2572 | ||
2561 | /* Combine initialization of marked, gct and typeid. */ | 2573 | /* Combine initialization of marked, gct and typeid. */ |
@@ -3289,6 +3301,9 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
3289 | if (!uselo) | 3301 | if (!uselo) |
3290 | ra_allocref(as, ir->op1, RID2RSET(RID_RET)); /* Mark call as used. */ | 3302 | ra_allocref(as, ir->op1, RID2RSET(RID_RET)); /* Mark call as used. */ |
3291 | break; | 3303 | break; |
3304 | case IR_CNEWI: | ||
3305 | /* Nothing to do here. Handled by CNEWI itself. */ | ||
3306 | break; | ||
3292 | default: lua_assert(0); break; | 3307 | default: lua_assert(0); break; |
3293 | } | 3308 | } |
3294 | #else | 3309 | #else |
@@ -4057,7 +4072,7 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
4057 | case IR_SNEW: asm_snew(as, ir); break; | 4072 | case IR_SNEW: asm_snew(as, ir); break; |
4058 | case IR_TNEW: asm_tnew(as, ir); break; | 4073 | case IR_TNEW: asm_tnew(as, ir); break; |
4059 | case IR_TDUP: asm_tdup(as, ir); break; | 4074 | case IR_TDUP: asm_tdup(as, ir); break; |
4060 | case IR_CNEW: case IR_CNEWP: asm_cnew(as, ir); break; | 4075 | case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break; |
4061 | 4076 | ||
4062 | /* Write barriers. */ | 4077 | /* Write barriers. */ |
4063 | case IR_TBAR: asm_tbar(as, ir); break; | 4078 | case IR_TBAR: asm_tbar(as, ir); break; |
@@ -4164,8 +4179,10 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T) | |||
4164 | } | 4179 | } |
4165 | #if LJ_32 && LJ_HASFFI | 4180 | #if LJ_32 && LJ_HASFFI |
4166 | case IR_HIOP: | 4181 | case IR_HIOP: |
4167 | if ((ir-1)->o == IR_CALLN) | 4182 | if ((ir-1)->o == IR_CALLN) { |
4168 | ir->prev = REGSP_HINT(RID_RETHI); | 4183 | ir->prev = REGSP_HINT(RID_RETHI); |
4184 | continue; | ||
4185 | } | ||
4169 | break; | 4186 | break; |
4170 | #endif | 4187 | #endif |
4171 | /* C calls evict all scratch regs and return results in RID_RET. */ | 4188 | /* C calls evict all scratch regs and return results in RID_RET. */ |
@@ -4174,7 +4191,7 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T) | |||
4174 | if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ | 4191 | if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ |
4175 | as->evenspill = 3; | 4192 | as->evenspill = 3; |
4176 | #endif | 4193 | #endif |
4177 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWP: case IR_TOSTR: | 4194 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: |
4178 | ir->prev = REGSP_HINT(RID_RET); | 4195 | ir->prev = REGSP_HINT(RID_RET); |
4179 | if (inloop) | 4196 | if (inloop) |
4180 | as->modset = RSET_SCRATCH; | 4197 | as->modset = RSET_SCRATCH; |