diff options
author | Mike Pall <mike> | 2010-09-01 00:18:00 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-09-01 00:18:00 +0200 |
commit | 8876704e05a33fc91c0b1eb69199d0b8459bd859 (patch) | |
tree | aa9f629cda40280e382c854c7f3c1eb2337f50d3 /src | |
parent | 00d10711ae59117922fc916ed8e574226474da3d (diff) | |
download | luajit-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.c | 81 |
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. */ | ||
423 | static 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. */ |
423 | static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | 459 | static 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. */ | ||
581 | static 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. */ |