diff options
author | Mike Pall <mike> | 2010-12-12 23:09:26 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-12-12 23:09:26 +0100 |
commit | 9666cf52ce240ac60fa97efc1ff2f98d82f25846 (patch) | |
tree | 36131a572742c1dccbc9ddb64c460a9ec9fba5b3 /src/lj_opt_mem.c | |
parent | 74317fa0efce58c8cedaae29315113ff609d14fe (diff) | |
download | luajit-9666cf52ce240ac60fa97efc1ff2f98d82f25846.tar.gz luajit-9666cf52ce240ac60fa97efc1ff2f98d82f25846.tar.bz2 luajit-9666cf52ce240ac60fa97efc1ff2f98d82f25846.zip |
Fix type-based alias analysis for XLOAD/XSTORE.
Diffstat (limited to 'src/lj_opt_mem.c')
-rw-r--r-- | src/lj_opt_mem.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index ec080697..c7e8df60 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c | |||
@@ -526,20 +526,22 @@ doemit: | |||
526 | /* -- XLOAD forwarding and XSTORE elimination ----------------------------- */ | 526 | /* -- XLOAD forwarding and XSTORE elimination ----------------------------- */ |
527 | 527 | ||
528 | /* Alias analysis for XLOAD/XSTORE. */ | 528 | /* Alias analysis for XLOAD/XSTORE. */ |
529 | static AliasRet aa_xref(jit_State *J, IRIns *refa, IRIns *refb) | 529 | static AliasRet aa_xref(jit_State *J, IRIns *xa, IRIns *xb) |
530 | { | 530 | { |
531 | ptrdiff_t ofsa = 0, ofsb = 0; | 531 | ptrdiff_t ofsa = 0, ofsb = 0; |
532 | IRIns *refa = IR(xa->op1), *refb = IR(xb->op1); | ||
532 | IRIns *basea = refa, *baseb = refb; | 533 | IRIns *basea = refa, *baseb = refb; |
533 | if (refa == refb) | ||
534 | return ALIAS_MUST; /* Shortcut for same refs. */ | ||
535 | /* This implements (very) strict aliasing rules. | 534 | /* This implements (very) strict aliasing rules. |
536 | ** Different types do NOT alias, except for differences in signedness. | 535 | ** Different types do NOT alias, except for differences in signedness. |
537 | ** NYI: this also prevents type punning through unions. | 536 | ** NYI: this also prevents type punning through unions. |
538 | */ | 537 | */ |
539 | if (!(irt_sametype(refa->t, refb->t) || | 538 | if (irt_sametype(xa->t, xb->t)) { |
540 | (irt_typerange(refa->t, IRT_I8, IRT_INT) && | 539 | if (refa == refb) |
541 | ((refa->t.irt - IRT_I8) ^ (refb->t.irt - IRT_I8)) == 1))) | 540 | return ALIAS_MUST; /* Shortcut for same refs with identical type. */ |
541 | } else if (!(irt_typerange(xa->t, IRT_I8, IRT_INT) && | ||
542 | ((xa->t.irt - IRT_I8) ^ (xb->t.irt - IRT_I8)) == 1)) { | ||
542 | return ALIAS_NO; | 543 | return ALIAS_NO; |
544 | } | ||
543 | /* Offset-based disambiguation. */ | 545 | /* Offset-based disambiguation. */ |
544 | if (refa->o == IR_ADD && irref_isk(refa->op2)) { | 546 | if (refa->o == IR_ADD && irref_isk(refa->op2)) { |
545 | IRIns *irk = IR(refa->op2); | 547 | IRIns *irk = IR(refa->op2); |
@@ -577,7 +579,6 @@ TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J) | |||
577 | { | 579 | { |
578 | IRRef xref = fins->op1; | 580 | IRRef xref = fins->op1; |
579 | IRRef lim = xref; /* Search limit. */ | 581 | IRRef lim = xref; /* Search limit. */ |
580 | IRIns *xr = IR(xref); | ||
581 | IRRef ref; | 582 | IRRef ref; |
582 | 583 | ||
583 | if ((fins->op2 & IRXLOAD_READONLY)) | 584 | if ((fins->op2 & IRXLOAD_READONLY)) |
@@ -587,7 +588,7 @@ TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J) | |||
587 | ref = J->chain[IR_XSTORE]; | 588 | ref = J->chain[IR_XSTORE]; |
588 | while (ref > xref) { | 589 | while (ref > xref) { |
589 | IRIns *store = IR(ref); | 590 | IRIns *store = IR(ref); |
590 | switch (aa_xref(J, xr, IR(store->op1))) { | 591 | switch (aa_xref(J, fins, store)) { |
591 | case ALIAS_NO: break; /* Continue searching. */ | 592 | case ALIAS_NO: break; /* Continue searching. */ |
592 | case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ | 593 | case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ |
593 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ | 594 | case ALIAS_MUST: return store->op2; /* Store forwarding. */ |
@@ -612,12 +613,11 @@ TRef LJ_FASTCALL lj_opt_dse_xstore(jit_State *J) | |||
612 | { | 613 | { |
613 | IRRef xref = fins->op1; | 614 | IRRef xref = fins->op1; |
614 | IRRef val = fins->op2; /* Stored value reference. */ | 615 | IRRef val = fins->op2; /* Stored value reference. */ |
615 | IRIns *xr = IR(xref); | ||
616 | IRRef1 *refp = &J->chain[IR_XSTORE]; | 616 | IRRef1 *refp = &J->chain[IR_XSTORE]; |
617 | IRRef ref = *refp; | 617 | IRRef ref = *refp; |
618 | while (ref > xref) { /* Search for redundant or conflicting stores. */ | 618 | while (ref > xref) { /* Search for redundant or conflicting stores. */ |
619 | IRIns *store = IR(ref); | 619 | IRIns *store = IR(ref); |
620 | switch (aa_xref(J, xr, IR(store->op1))) { | 620 | switch (aa_xref(J, fins, store)) { |
621 | case ALIAS_NO: | 621 | case ALIAS_NO: |
622 | break; /* Continue searching. */ | 622 | break; /* Continue searching. */ |
623 | case ALIAS_MAY: | 623 | case ALIAS_MAY: |