aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-09-01 00:18:00 +0200
committerMike Pall <mike>2010-09-01 00:18:00 +0200
commit8876704e05a33fc91c0b1eb69199d0b8459bd859 (patch)
treeaa9f629cda40280e382c854c7f3c1eb2337f50d3 /src
parent00d10711ae59117922fc916ed8e574226474da3d (diff)
downloadluajit-8876704e05a33fc91c0b1eb69199d0b8459bd859.tar.gz
luajit-8876704e05a33fc91c0b1eb69199d0b8459bd859.tar.bz2
luajit-8876704e05a33fc91c0b1eb69199d0b8459bd859.zip
Improve coalescing of multiple KPRI instructions to KNIL.
Diffstat (limited to 'src')
-rw-r--r--src/lj_parse.c81
1 files changed, 42 insertions, 39 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 2811e6eb..f5f59d03 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -419,14 +419,48 @@ static void expr_discharge(FuncState *fs, ExpDesc *e)
419 e->k = VRELOCABLE; 419 e->k = VRELOCABLE;
420} 420}
421 421
422/* Emit bytecode to set a range of registers to nil. */
423static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
424{
425 if (fs->pc > fs->lasttarget) { /* No jumps to current position? */
426 BCIns *ip = &fs->bcbase[fs->pc-1].ins;
427 BCReg pto, pfrom = bc_a(*ip);
428 switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */
429 case BC_KPRI:
430 if (bc_d(*ip) != ~LJ_TNIL) break;
431 if (from == pfrom) {
432 if (n == 1) return;
433 } else if (from == pfrom+1) {
434 from = pfrom;
435 n++;
436 } else {
437 break;
438 }
439 fs->pc--; /* Drop KPRI. */
440 break;
441 case BC_KNIL:
442 pto = bc_d(*ip);
443 if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */
444 if (from+n-1 > pto)
445 setbc_d(ip, from+n-1); /* Patch previous instruction range. */
446 return;
447 }
448 break;
449 default:
450 break;
451 }
452 }
453 /* Emit new instruction or replace old instruction. */
454 bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
455 BCINS_AD(BC_KNIL, from, from+n-1));
456}
457
422/* Discharge an expression to a specific register. Ignore branches. */ 458/* Discharge an expression to a specific register. Ignore branches. */
423static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) 459static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
424{ 460{
425 BCIns ins; 461 BCIns ins;
426 expr_discharge(fs, e); 462 expr_discharge(fs, e);
427 if (e->k <= VKTRUE) { 463 if (e->k == VKSTR) {
428 ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
429 } else if (e->k == VKSTR) {
430 ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e)); 464 ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
431 } else if (e->k == VKNUM) { 465 } else if (e->k == VKNUM) {
432 lua_Number n = expr_numV(e); 466 lua_Number n = expr_numV(e);
@@ -442,6 +476,11 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
442 if (reg == e->u.s.info) 476 if (reg == e->u.s.info)
443 goto noins; 477 goto noins;
444 ins = BCINS_AD(BC_MOV, reg, e->u.s.info); 478 ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
479 } else if (e->k == VKNIL) {
480 bcemit_nil(fs, reg, 1);
481 goto noins;
482 } else if (e->k <= VKTRUE) {
483 ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
445 } else { 484 } else {
446 lua_assert(e->k == VVOID || e->k == VJMP); 485 lua_assert(e->k == VVOID || e->k == VJMP);
447 return; 486 return;
@@ -577,42 +616,6 @@ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
577 e->k = VNONRELOC; 616 e->k = VNONRELOC;
578} 617}
579 618
580/* Emit bytecode to set a range of registers to nil. */
581static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
582{
583 if (fs->pc > fs->lasttarget) { /* No jumps to current position? */
584 BCIns *ip = &fs->bcbase[fs->pc-1].ins;
585 BCReg pto, pfrom = bc_a(*ip);
586 switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */
587 case BC_KPRI:
588 if (bc_d(*ip) != ~LJ_TNIL) break;
589 if (from == pfrom) {
590 if (n == 1) return;
591 } else if (from == pfrom+1) {
592 from = pfrom;
593 n++;
594 } else {
595 break;
596 }
597 fs->pc--; /* Drop KPRI. */
598 break;
599 case BC_KNIL:
600 pto = bc_d(*ip);
601 if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */
602 if (from+n-1 > pto)
603 setbc_d(ip, from+n-1); /* Patch previous instruction range. */
604 return;
605 }
606 break;
607 default:
608 break;
609 }
610 }
611 /* Emit new instruction or replace old instruction. */
612 bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
613 BCINS_AD(BC_KNIL, from, from+n-1));
614}
615
616/* -- Bytecode emitter for branches --------------------------------------- */ 619/* -- Bytecode emitter for branches --------------------------------------- */
617 620
618/* Emit unconditional branch. */ 621/* Emit unconditional branch. */