diff options
| author | Mike Pall <mike> | 2010-12-31 22:50:06 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-31 22:50:06 +0100 |
| commit | ddfa7fc246569f2fb7a664efcca73ac0e047d876 (patch) | |
| tree | bce560dc123963d124c7a86b950b41dde038d309 | |
| parent | 3b47eba9ccf3324f790a90c99f0c50f04ba9ce1e (diff) | |
| download | luajit-ddfa7fc246569f2fb7a664efcca73ac0e047d876.tar.gz luajit-ddfa7fc246569f2fb7a664efcca73ac0e047d876.tar.bz2 luajit-ddfa7fc246569f2fb7a664efcca73ac0e047d876.zip | |
Add conversions for type mismatches in XSTORE forwarding.
| -rw-r--r-- | src/lj_opt_mem.c | 28 |
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 | } |
