aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2012-07-01 22:44:54 +0200
committerMike Pall <mike>2012-07-01 22:44:54 +0200
commitcda3630565ad0f715fb9acd5c208e35b02466e32 (patch)
tree6f876dd779148a2d26e7ed807ea57ecdfc165014 /src
parent89f8c920c652153f690d61b5bede581aad072593 (diff)
downloadluajit-cda3630565ad0f715fb9acd5c208e35b02466e32.tar.gz
luajit-cda3630565ad0f715fb9acd5c208e35b02466e32.tar.bz2
luajit-cda3630565ad0f715fb9acd5c208e35b02466e32.zip
Clean up RegSP handling for parent link instructions.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c112
-rw-r--r--src/lj_snap.c40
-rw-r--r--src/lj_snap.h3
3 files changed, 67 insertions, 88 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 4da1a0a3..e8e823c3 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -87,10 +87,7 @@ typedef struct ASMState {
87 int32_t krefk[RID_NUM_KREF]; 87 int32_t krefk[RID_NUM_KREF];
88#endif 88#endif
89 IRRef1 phireg[RID_MAX]; /* PHI register references. */ 89 IRRef1 phireg[RID_MAX]; /* PHI register references. */
90 uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent slot to RegSP map. */ 90 uint16_t parentmap[LJ_MAX_JSLOTS]; /* Parent instruction to RegSP map. */
91#if LJ_SOFTFP
92 uint16_t parentmaphi[LJ_MAX_JSLOTS]; /* Parent slot to hi RegSP map. */
93#endif
94} ASMState; 91} ASMState;
95 92
96#define IR(ref) (&as->ir[(ref)]) 93#define IR(ref) (&as->ir[(ref)])
@@ -1249,15 +1246,6 @@ static void asm_head_root(ASMState *as)
1249 as->T->topslot = gcref(as->T->startpt)->pt.framesize; 1246 as->T->topslot = gcref(as->T->startpt)->pt.framesize;
1250} 1247}
1251 1248
1252/* Get RegSP for parent slot. */
1253static LJ_AINLINE RegSP asm_head_parentrs(ASMState *as, IRIns *ir)
1254{
1255#if LJ_SOFTFP
1256 if (ir->o == IR_HIOP) return as->parentmaphi[(ir-1)->op1];
1257#endif
1258 return as->parentmap[ir->op1];
1259}
1260
1261/* Head of a side trace. 1249/* Head of a side trace.
1262** 1250**
1263** The current simplistic algorithm requires that all slots inherited 1251** The current simplistic algorithm requires that all slots inherited
@@ -1285,7 +1273,7 @@ static void asm_head_side(ASMState *as)
1285 RegSP rs; 1273 RegSP rs;
1286 lua_assert((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) || 1274 lua_assert((ir->o == IR_SLOAD && (ir->op2 & IRSLOAD_PARENT)) ||
1287 (LJ_SOFTFP && ir->o == IR_HIOP)); 1275 (LJ_SOFTFP && ir->o == IR_HIOP));
1288 rs = asm_head_parentrs(as, ir); 1276 rs = as->parentmap[i - REF_FIRST];
1289 if (ra_hasreg(ir->r)) { 1277 if (ra_hasreg(ir->r)) {
1290 rset_clear(allow, ir->r); 1278 rset_clear(allow, ir->r);
1291 if (ra_hasspill(ir->s)) { 1279 if (ra_hasspill(ir->s)) {
@@ -1325,7 +1313,7 @@ static void asm_head_side(ASMState *as)
1325 Reg r; 1313 Reg r;
1326 RegSP rs; 1314 RegSP rs;
1327 irt_clearmark(ir->t); 1315 irt_clearmark(ir->t);
1328 rs = asm_head_parentrs(as, ir); 1316 rs = as->parentmap[i - REF_FIRST];
1329 if (!ra_hasspill(regsp_spill(rs))) 1317 if (!ra_hasspill(regsp_spill(rs)))
1330 ra_sethint(ir->r, rs); /* Hint may be gone, set it again. */ 1318 ra_sethint(ir->r, rs); /* Hint may be gone, set it again. */
1331 else if (sps_scale(regsp_spill(rs))+spdelta == sps_scale(ir->s)) 1319 else if (sps_scale(regsp_spill(rs))+spdelta == sps_scale(ir->s))
@@ -1362,13 +1350,13 @@ static void asm_head_side(ASMState *as)
1362 RegSet work = ~as->freeset & RSET_ALL; 1350 RegSet work = ~as->freeset & RSET_ALL;
1363 while (work) { 1351 while (work) {
1364 Reg r = rset_pickbot(work); 1352 Reg r = rset_pickbot(work);
1365 IRIns *ir = IR(regcost_ref(as->cost[r])); 1353 IRRef ref = regcost_ref(as->cost[r]);
1366 RegSP rs = asm_head_parentrs(as, ir); 1354 RegSP rs = as->parentmap[ref - REF_FIRST];
1367 rset_clear(work, r); 1355 rset_clear(work, r);
1368 if (ra_hasspill(regsp_spill(rs))) { 1356 if (ra_hasspill(regsp_spill(rs))) {
1369 int32_t ofs = sps_scale(regsp_spill(rs)); 1357 int32_t ofs = sps_scale(regsp_spill(rs));
1370 ra_free(as, r); 1358 ra_free(as, r);
1371 emit_spload(as, ir, r, ofs); 1359 emit_spload(as, IR(ref), r, ofs);
1372 checkmclim(as); 1360 checkmclim(as);
1373 } 1361 }
1374 } 1362 }
@@ -1494,7 +1482,8 @@ static void asm_tail_link(ASMState *as)
1494static void asm_setup_regsp(ASMState *as) 1482static void asm_setup_regsp(ASMState *as)
1495{ 1483{
1496 GCtrace *T = as->T; 1484 GCtrace *T = as->T;
1497 IRRef i, nins; 1485 IRRef nins = T->nins;
1486 IRIns *ir, *lastir;
1498 int inloop; 1487 int inloop;
1499#if LJ_TARGET_ARM 1488#if LJ_TARGET_ARM
1500 uint32_t rload = 0xa6402a64; 1489 uint32_t rload = 0xa6402a64;
@@ -1503,15 +1492,15 @@ static void asm_setup_regsp(ASMState *as)
1503 ra_setup(as); 1492 ra_setup(as);
1504 1493
1505 /* Clear reg/sp for constants. */ 1494 /* Clear reg/sp for constants. */
1506 for (i = T->nk; i < REF_BIAS; i++) 1495 for (ir = IR(T->nk), lastir = IR(REF_BASE); ir < lastir; ir++)
1507 IR(i)->prev = REGSP_INIT; 1496 ir->prev = REGSP_INIT;
1508 1497
1509 /* REF_BASE is used for implicit references to the BASE register. */ 1498 /* REF_BASE is used for implicit references to the BASE register. */
1510 IR(REF_BASE)->prev = REGSP_HINT(RID_BASE); 1499 lastir->prev = REGSP_HINT(RID_BASE);
1511 1500
1512 nins = T->nins; 1501 ir = IR(nins-1);
1513 if (IR(nins-1)->o == IR_RENAME) { 1502 if (ir->o == IR_RENAME) {
1514 do { nins--; } while (IR(nins-1)->o == IR_RENAME); 1503 do { ir--; nins--; } while (ir->o == IR_RENAME);
1515 T->nins = nins; /* Remove any renames left over from ASM restart. */ 1504 T->nins = nins; /* Remove any renames left over from ASM restart. */
1516 } 1505 }
1517 as->snaprename = nins; 1506 as->snaprename = nins;
@@ -1522,34 +1511,34 @@ static void asm_setup_regsp(ASMState *as)
1522 as->orignins = nins; 1511 as->orignins = nins;
1523 as->curins = nins; 1512 as->curins = nins;
1524 1513
1514 /* Setup register hints for parent link instructions. */
1515 ir = IR(REF_FIRST);
1516 if (as->parent) {
1517 uint16_t *p;
1518 lastir = lj_snap_regspmap(as->parent, as->J->exitno, ir);
1519 as->stopins = (lastir-1) - as->ir;
1520 for (p = as->parentmap; ir < lastir; ir++) {
1521 RegSP rs = ir->prev;
1522 *p++ = (uint16_t)rs; /* Copy original parent RegSP to parentmap. */
1523 if (!ra_hasspill(regsp_spill(rs)))
1524 ir->prev = (uint16_t)REGSP_HINT(regsp_reg(rs));
1525 else
1526 ir->prev = REGSP_INIT;
1527 }
1528 }
1529
1525 inloop = 0; 1530 inloop = 0;
1526 as->evenspill = SPS_FIRST; 1531 as->evenspill = SPS_FIRST;
1527 for (i = REF_FIRST; i < nins; i++) { 1532 for (lastir = IR(nins); ir < lastir; ir++) {
1528 IRIns *ir = IR(i);
1529 switch (ir->o) { 1533 switch (ir->o) {
1530 case IR_LOOP: 1534 case IR_LOOP:
1531 inloop = 1; 1535 inloop = 1;
1532 break; 1536 break;
1533 /* Set hints for slot loads from a parent trace. */
1534 case IR_SLOAD:
1535 if ((ir->op2 & IRSLOAD_PARENT)) {
1536 RegSP rs = as->parentmap[ir->op1];
1537 lua_assert(regsp_used(rs));
1538 as->stopins = i;
1539 if (!ra_hasspill(regsp_spill(rs)) && ra_hasreg(regsp_reg(rs))) {
1540 ir->prev = (uint16_t)REGSP_HINT(regsp_reg(rs));
1541 continue;
1542 }
1543 }
1544#if LJ_TARGET_ARM
1545 if ((ir->op2 & IRSLOAD_TYPECHECK) || (ir+1)->o == IR_HIOP) {
1546 ir->prev = (uint16_t)REGSP_HINT((rload & 15));
1547 rload = lj_ror(rload, 4);
1548 continue;
1549 }
1550#endif
1551 break;
1552#if LJ_TARGET_ARM 1537#if LJ_TARGET_ARM
1538 case IR_SLOAD:
1539 if (!((ir->op2 & IRSLOAD_TYPECHECK) || (ir+1)->o == IR_HIOP))
1540 break;
1541 /* fallthrough */
1553 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: 1542 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1554 ir->prev = (uint16_t)REGSP_HINT((rload & 15)); 1543 ir->prev = (uint16_t)REGSP_HINT((rload & 15));
1555 rload = lj_ror(rload, 4); 1544 rload = lj_ror(rload, 4);
@@ -1574,25 +1563,12 @@ static void asm_setup_regsp(ASMState *as)
1574#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI) 1563#if LJ_SOFTFP || (LJ_32 && LJ_HASFFI)
1575 case IR_HIOP: 1564 case IR_HIOP:
1576 switch ((ir-1)->o) { 1565 switch ((ir-1)->o) {
1577#if LJ_SOFTFP 1566#if LJ_SOFTFP && LJ_TARGET_ARM
1578 case IR_SLOAD: 1567 case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1579 if (((ir-1)->op2 & IRSLOAD_PARENT)) {
1580 RegSP rs = as->parentmaphi[(ir-1)->op1];
1581 lua_assert(regsp_used(rs));
1582 as->stopins = i;
1583 if (!ra_hasspill(regsp_spill(rs)) && ra_hasreg(regsp_reg(rs))) {
1584 ir->prev = (uint16_t)REGSP_HINT(regsp_reg(rs));
1585 continue;
1586 }
1587 }
1588#if LJ_TARGET_ARM
1589 /* fallthrough */
1590 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1591 if (ra_hashint((ir-1)->r)) { 1568 if (ra_hashint((ir-1)->r)) {
1592 ir->prev = (ir-1)->prev + 1; 1569 ir->prev = (ir-1)->prev + 1;
1593 continue; 1570 continue;
1594 } 1571 }
1595#endif
1596 break; 1572 break;
1597#endif 1573#endif
1598#if LJ_NEED_FP64 1574#if LJ_NEED_FP64
@@ -1702,7 +1678,8 @@ static void asm_setup_regsp(ASMState *as)
1702 /* fallthrough */ 1678 /* fallthrough */
1703 default: 1679 default:
1704 /* Propagate hints across likely 'op reg, imm' or 'op reg'. */ 1680 /* Propagate hints across likely 'op reg, imm' or 'op reg'. */
1705 if (irref_isk(ir->op2) && !irref_isk(ir->op1)) { 1681 if (irref_isk(ir->op2) && !irref_isk(ir->op1) &&
1682 ra_hashint(regsp_reg(IR(ir->op1)->prev))) {
1706 ir->prev = IR(ir->op1)->prev; 1683 ir->prev = IR(ir->op1)->prev;
1707 continue; 1684 continue;
1708 } 1685 }
@@ -1737,15 +1714,8 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
1737 as->loopref = J->loopref; 1714 as->loopref = J->loopref;
1738 as->realign = NULL; 1715 as->realign = NULL;
1739 as->loopinv = 0; 1716 as->loopinv = 0;
1740 if (J->parent) { 1717 as->parent = J->parent ? traceref(J, J->parent) : NULL;
1741 as->parent = traceref(J, J->parent); 1718
1742 lj_snap_regspmap(as->parentmap, as->parent, J->exitno, 0);
1743#if LJ_SOFTFP
1744 lj_snap_regspmap(as->parentmaphi, as->parent, J->exitno, 1);
1745#endif
1746 } else {
1747 as->parent = NULL;
1748 }
1749 /* Reserve MCode memory. */ 1719 /* Reserve MCode memory. */
1750 as->mctop = origtop = lj_mcode_reserve(J, &as->mcbot); 1720 as->mctop = origtop = lj_mcode_reserve(J, &as->mcbot);
1751 as->mcp = as->mctop; 1721 as->mcp = as->mctop;
diff --git a/src/lj_snap.c b/src/lj_snap.c
index d2e4d95e..3371375a 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -318,27 +318,37 @@ static RegSP snap_renameref(GCtrace *T, SnapNo lim, IRRef ref, RegSP rs)
318 return rs; 318 return rs;
319} 319}
320 320
321/* Convert a snapshot into a linear slot -> RegSP map. 321/* Copy RegSP from parent snapshot to the parent links of the IR. */
322** Note: unused slots are not initialized! 322IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir)
323*/
324void lj_snap_regspmap(uint16_t *rsmap, GCtrace *T, SnapNo snapno, int hi)
325{ 323{
326 SnapShot *snap = &T->snap[snapno]; 324 SnapShot *snap = &T->snap[snapno];
327 MSize n, nent = snap->nent;
328 SnapEntry *map = &T->snapmap[snap->mapofs]; 325 SnapEntry *map = &T->snapmap[snap->mapofs];
329 BloomFilter rfilt = snap_renamefilter(T, snapno); 326 BloomFilter rfilt = snap_renamefilter(T, snapno);
330 for (n = 0; n < nent; n++) { 327 MSize n = 0;
331 SnapEntry sn = map[n]; 328 IRRef ref = 0;
332 IRRef ref = snap_ref(sn); 329 for ( ; ; ir++) {
333 if (!irref_isk(ref) && 330 uint32_t rs;
334 ((LJ_SOFTFP && hi) ? (ref++, (sn & SNAP_SOFTFPNUM)) : 1)) { 331 if (ir->o == IR_SLOAD) {
335 IRIns *ir = &T->ir[ref]; 332 if (!(ir->op2 & IRSLOAD_PARENT)) break;
336 uint32_t rs = ir->prev; 333 for ( ; ; n++) {
337 if (bloomtest(rfilt, ref)) 334 lua_assert(n < snap->nent);
338 rs = snap_renameref(T, snapno, ref, rs); 335 if (snap_slot(map[n]) == ir->op1) {
339 rsmap[snap_slot(sn)] = (uint16_t)rs; 336 ref = snap_ref(map[n++]);
337 break;
338 }
339 }
340 } else if (LJ_SOFTFP && ir->o == IR_HIOP) {
341 ref++;
342 } else {
343 break;
340 } 344 }
345 rs = T->ir[ref].prev;
346 if (bloomtest(rfilt, ref))
347 rs = snap_renameref(T, snapno, ref, rs);
348 ir->prev = (uint16_t)rs;
349 lua_assert(regsp_used(rs));
341 } 350 }
351 return ir;
342} 352}
343 353
344/* Restore a value from the trace exit state. */ 354/* Restore a value from the trace exit state. */
diff --git a/src/lj_snap.h b/src/lj_snap.h
index 9ec1a78e..0c267a9c 100644
--- a/src/lj_snap.h
+++ b/src/lj_snap.h
@@ -13,8 +13,7 @@
13LJ_FUNC void lj_snap_add(jit_State *J); 13LJ_FUNC void lj_snap_add(jit_State *J);
14LJ_FUNC void lj_snap_purge(jit_State *J); 14LJ_FUNC void lj_snap_purge(jit_State *J);
15LJ_FUNC void lj_snap_shrink(jit_State *J); 15LJ_FUNC void lj_snap_shrink(jit_State *J);
16LJ_FUNC void lj_snap_regspmap(uint16_t *rsmap, GCtrace *T, SnapNo snapno, 16LJ_FUNC IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir);
17 int hi);
18LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr); 17LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr);
19LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need); 18LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need);
20LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need); 19LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need);