summaryrefslogtreecommitdiff
path: root/src/lj_opt_mem.c
diff options
context:
space:
mode:
authorMike Pall <mike>2010-12-31 22:50:06 +0100
committerMike Pall <mike>2010-12-31 22:50:06 +0100
commitddfa7fc246569f2fb7a664efcca73ac0e047d876 (patch)
treebce560dc123963d124c7a86b950b41dde038d309 /src/lj_opt_mem.c
parent3b47eba9ccf3324f790a90c99f0c50f04ba9ce1e (diff)
downloadluajit-ddfa7fc246569f2fb7a664efcca73ac0e047d876.tar.gz
luajit-ddfa7fc246569f2fb7a664efcca73ac0e047d876.tar.bz2
luajit-ddfa7fc246569f2fb7a664efcca73ac0e047d876.zip
Add conversions for type mismatches in XSTORE forwarding.
Diffstat (limited to 'src/lj_opt_mem.c')
-rw-r--r--src/lj_opt_mem.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c
index 5aa5d8b9..6633867e 100644
--- a/src/lj_opt_mem.c
+++ b/src/lj_opt_mem.c
@@ -567,7 +567,7 @@ static AliasRet aa_xref(jit_State *J, IRIns *refa, IRIns *xa, IRIns *xb)
567 if (irt_sametype(xa->t, xb->t)) { 567 if (irt_sametype(xa->t, xb->t)) {
568 if (refa == refb) 568 if (refa == refb)
569 return ALIAS_MUST; /* Shortcut for same refs with identical type. */ 569 return ALIAS_MUST; /* Shortcut for same refs with identical type. */
570 } else if (!(irt_typerange(xa->t, IRT_I8, IRT_INT) && 570 } else if (!(irt_typerange(xa->t, IRT_I8, IRT_U64) &&
571 ((xa->t.irt - IRT_I8) ^ (xb->t.irt - IRT_I8)) == 1)) { 571 ((xa->t.irt - IRT_I8) ^ (xb->t.irt - IRT_I8)) == 1)) {
572 return ALIAS_NO; 572 return ALIAS_NO;
573 } 573 }
@@ -592,11 +592,7 @@ static AliasRet aa_xref(jit_State *J, IRIns *refa, IRIns *xa, IRIns *xb)
592 /* This assumes strictly-typed, non-overlapping accesses. */ 592 /* This assumes strictly-typed, non-overlapping accesses. */
593 if (ofsa != ofsb) 593 if (ofsa != ofsb)
594 return ALIAS_NO; /* base+-o1 vs. base+-o2 and o1 != o2. */ 594 return ALIAS_NO; /* base+-o1 vs. base+-o2 and o1 != o2. */
595 /* Unsigned vs. signed access to the same address. 595 return ALIAS_MUST; /* Unsigned vs. signed access to the same address. */
596 ** Really ALIAS_MUST, but store forwarding would lose the type.
597 ** This is rare, so return ALIAS_MAY for now.
598 */
599 return ALIAS_MAY;
600 } 596 }
601 /* NYI: structural disambiguation. */ 597 /* NYI: structural disambiguation. */
602 return aa_cnew(J, basea, baseb); /* Try to disambiguate allocations. */ 598 return aa_cnew(J, basea, baseb); /* Try to disambiguate allocations. */
@@ -682,7 +678,25 @@ retry:
682 switch (aa_xref(J, xr, fins, store)) { 678 switch (aa_xref(J, xr, fins, store)) {
683 case ALIAS_NO: break; /* Continue searching. */ 679 case ALIAS_NO: break; /* Continue searching. */
684 case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ 680 case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */
685 case ALIAS_MUST: return store->op2; /* Store forwarding. */ 681 case ALIAS_MUST:
682 /* Emit conversion if the loaded type doesn't match the forwarded type. */
683 if (!irt_sametype(fins->t, IR(store->op2)->t)) {
684 IRType st = irt_type(fins->t);
685 if (st == IRT_I8 || st == IRT_I16) { /* Trunc + sign-extend. */
686 st |= IRCONV_SEXT;
687 } else if (st == IRT_U8 || st == IRT_U16) { /* Trunc + zero-extend. */
688 } else if (st == IRT_INT && irt_isu32(IR(store->op2)->t)) {
689 st = IRT_U32; /* Needs dummy CONV.int.u32. */
690 } else { /* I64/U64 are boxed, U32 is hidden behind a CONV.num.u32. */
691 goto store_fwd;
692 }
693 fins->ot = IRTI(IR_CONV);
694 fins->op1 = store->op2;
695 fins->op2 = (IRT_INT<<5)|st;
696 return RETRYFOLD;
697 }
698 store_fwd:
699 return store->op2; /* Store forwarding. */
686 } 700 }
687 ref = store->prev; 701 ref = store->prev;
688 } 702 }