aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c67
1 files changed, 52 insertions, 15 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 9bce9292..8ff3eaf7 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -782,19 +782,44 @@ static int asm_snap_canremat(ASMState *as)
782static void asm_snap_alloc1(ASMState *as, IRRef ref) 782static void asm_snap_alloc1(ASMState *as, IRRef ref)
783{ 783{
784 IRIns *ir = IR(ref); 784 IRIns *ir = IR(ref);
785 if (!ra_used(ir)) { 785 if (!(ra_used(ir) || ir->r == RID_SUNK)) {
786 RegSet allow = (!LJ_SOFTFP && irt_isnum(ir->t)) ? RSET_FPR : RSET_GPR; 786 if (ir->r == RID_SINK) {
787 /* Get a weak register if we have a free one or can rematerialize. */ 787 ir->r = RID_SUNK;
788 if ((as->freeset & allow) || 788#if LJ_HASFFI
789 (allow == RSET_FPR && asm_snap_canremat(as))) { 789 if (ir->o == IR_CNEWI) { /* Allocate CNEWI value. */
790 Reg r = ra_allocref(as, ref, allow); /* Allocate a register. */ 790 asm_snap_alloc1(as, ir->op2);
791 if (!irt_isphi(ir->t)) 791 if (LJ_32 && (ir+1)->o == IR_HIOP)
792 ra_weak(as, r); /* But mark it as weakly referenced. */ 792 asm_snap_alloc1(as, (ir+1)->op2);
793 checkmclim(as); 793 }
794 RA_DBGX((as, "snapreg $f $r", ref, ir->r)); 794#endif
795 else { /* Allocate stored values for TNEW, TDUP and CNEW. */
796 IRIns *irs;
797 lua_assert(ir->o == IR_TNEW || ir->o == IR_TDUP || ir->o == IR_CNEW);
798 for (irs = IR(as->curins); irs > ir; irs--)
799 if (irs->r == RID_SINK && ir + irs->s == irs) {
800 lua_assert(irs->o == IR_ASTORE || irs->o == IR_HSTORE ||
801 irs->o == IR_FSTORE || irs->o == IR_XSTORE);
802 asm_snap_alloc1(as, irs->op2);
803 if (LJ_32 && (irs+1)->o == IR_HIOP)
804 asm_snap_alloc1(as, (irs+1)->op2);
805 }
806 }
807 } else if (ir->o == IR_CONV && ir->op2 == IRCONV_NUM_INT) {
808 asm_snap_alloc1(as, ir->op1);
795 } else { 809 } else {
796 ra_spill(as, ir); /* Otherwise force a spill slot. */ 810 RegSet allow = (!LJ_SOFTFP && irt_isfp(ir->t)) ? RSET_FPR : RSET_GPR;
797 RA_DBGX((as, "snapspill $f $s", ref, ir->s)); 811 if ((as->freeset & allow) ||
812 (allow == RSET_FPR && asm_snap_canremat(as))) {
813 /* Get a weak register if we have a free one or can rematerialize. */
814 Reg r = ra_allocref(as, ref, allow); /* Allocate a register. */
815 if (!irt_isphi(ir->t))
816 ra_weak(as, r); /* But mark it as weakly referenced. */
817 checkmclim(as);
818 RA_DBGX((as, "snapreg $f $r", ref, ir->r));
819 } else {
820 ra_spill(as, ir); /* Otherwise force a spill slot. */
821 RA_DBGX((as, "snapspill $f $s", ref, ir->s));
822 }
798 } 823 }
799 } 824 }
800} 825}
@@ -848,7 +873,7 @@ static void asm_snap_prep(ASMState *as)
848{ 873{
849 if (as->curins < as->snapref) { 874 if (as->curins < as->snapref) {
850 do { 875 do {
851 lua_assert(as->snapno != 0); 876 if (as->snapno == 0) return; /* Called by sunk stores before snap #0. */
852 as->snapno--; 877 as->snapno--;
853 as->snapref = as->T->snap[as->snapno].ref; 878 as->snapref = as->T->snap[as->snapno].ref;
854 } while (as->curins < as->snapref); 879 } while (as->curins < as->snapref);
@@ -1180,6 +1205,8 @@ static void asm_phi(ASMState *as, IRIns *ir)
1180 RegSet afree = (as->freeset & allow); 1205 RegSet afree = (as->freeset & allow);
1181 IRIns *irl = IR(ir->op1); 1206 IRIns *irl = IR(ir->op1);
1182 IRIns *irr = IR(ir->op2); 1207 IRIns *irr = IR(ir->op2);
1208 if (ir->r == RID_SINK) /* Sink PHI. */
1209 return;
1183 /* Spill slot shuffling is not implemented yet (but rarely needed). */ 1210 /* Spill slot shuffling is not implemented yet (but rarely needed). */
1184 if (ra_hasspill(irl->s) || ra_hasspill(irr->s)) 1211 if (ra_hasspill(irl->s) || ra_hasspill(irr->s))
1185 lj_trace_err(as->J, LJ_TRERR_NYIPHI); 1212 lj_trace_err(as->J, LJ_TRERR_NYIPHI);
@@ -1494,7 +1521,7 @@ static void asm_tail_link(ASMState *as)
1494/* -- Trace setup --------------------------------------------------------- */ 1521/* -- Trace setup --------------------------------------------------------- */
1495 1522
1496/* Clear reg/sp for all instructions and add register hints. */ 1523/* Clear reg/sp for all instructions and add register hints. */
1497static void asm_setup_regsp(ASMState *as) 1524static void asm_setup_regsp(ASMState *as, int sink)
1498{ 1525{
1499 GCtrace *T = as->T; 1526 GCtrace *T = as->T;
1500 IRRef nins = T->nins; 1527 IRRef nins = T->nins;
@@ -1545,6 +1572,14 @@ static void asm_setup_regsp(ASMState *as)
1545 inloop = 0; 1572 inloop = 0;
1546 as->evenspill = SPS_FIRST; 1573 as->evenspill = SPS_FIRST;
1547 for (lastir = IR(nins); ir < lastir; ir++) { 1574 for (lastir = IR(nins); ir < lastir; ir++) {
1575 if (sink) {
1576 if (ir->r == RID_SINK)
1577 continue;
1578 if (ir->r == RID_SUNK) { /* Revert after ASM restart. */
1579 ir->r = RID_SINK;
1580 continue;
1581 }
1582 }
1548 switch (ir->o) { 1583 switch (ir->o) {
1549 case IR_LOOP: 1584 case IR_LOOP:
1550 inloop = 1; 1585 inloop = 1;
@@ -1716,6 +1751,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
1716 ASMState as_; 1751 ASMState as_;
1717 ASMState *as = &as_; 1752 ASMState *as = &as_;
1718 MCode *origtop; 1753 MCode *origtop;
1754 int sink;
1719 1755
1720 /* Ensure an initialized instruction beyond the last one for HIOP checks. */ 1756 /* Ensure an initialized instruction beyond the last one for HIOP checks. */
1721 J->cur.nins = lj_ir_nextins(J); 1757 J->cur.nins = lj_ir_nextins(J);
@@ -1736,6 +1772,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
1736 as->mcp = as->mctop; 1772 as->mcp = as->mctop;
1737 as->mclim = as->mcbot + MCLIM_REDZONE; 1773 as->mclim = as->mcbot + MCLIM_REDZONE;
1738 asm_setup_target(as); 1774 asm_setup_target(as);
1775 sink = (IR(REF_BASE)->prev == 1);
1739 1776
1740 do { 1777 do {
1741 as->mcp = as->mctop; 1778 as->mcp = as->mctop;
@@ -1751,7 +1788,7 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
1751 as->gcsteps = 0; 1788 as->gcsteps = 0;
1752 as->sectref = as->loopref; 1789 as->sectref = as->loopref;
1753 as->fuseref = (as->flags & JIT_F_OPT_FUSE) ? as->loopref : FUSE_DISABLED; 1790 as->fuseref = (as->flags & JIT_F_OPT_FUSE) ? as->loopref : FUSE_DISABLED;
1754 asm_setup_regsp(as); 1791 asm_setup_regsp(as, sink);
1755 if (!as->loopref) 1792 if (!as->loopref)
1756 asm_tail_link(as); 1793 asm_tail_link(as);
1757 1794