diff options
author | Mike Pall <mike> | 2012-07-01 22:44:54 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-07-01 22:44:54 +0200 |
commit | cda3630565ad0f715fb9acd5c208e35b02466e32 (patch) | |
tree | 6f876dd779148a2d26e7ed807ea57ecdfc165014 /src | |
parent | 89f8c920c652153f690d61b5bede581aad072593 (diff) | |
download | luajit-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.c | 112 | ||||
-rw-r--r-- | src/lj_snap.c | 40 | ||||
-rw-r--r-- | src/lj_snap.h | 3 |
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. */ | ||
1253 | static 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) | |||
1494 | static void asm_setup_regsp(ASMState *as) | 1482 | static 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! | 322 | IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir) |
323 | */ | ||
324 | void 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 @@ | |||
13 | LJ_FUNC void lj_snap_add(jit_State *J); | 13 | LJ_FUNC void lj_snap_add(jit_State *J); |
14 | LJ_FUNC void lj_snap_purge(jit_State *J); | 14 | LJ_FUNC void lj_snap_purge(jit_State *J); |
15 | LJ_FUNC void lj_snap_shrink(jit_State *J); | 15 | LJ_FUNC void lj_snap_shrink(jit_State *J); |
16 | LJ_FUNC void lj_snap_regspmap(uint16_t *rsmap, GCtrace *T, SnapNo snapno, | 16 | LJ_FUNC IRIns *lj_snap_regspmap(GCtrace *T, SnapNo snapno, IRIns *ir); |
17 | int hi); | ||
18 | LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr); | 17 | LJ_FUNC const BCIns *lj_snap_restore(jit_State *J, void *exptr); |
19 | LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need); | 18 | LJ_FUNC void lj_snap_grow_buf_(jit_State *J, MSize need); |
20 | LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need); | 19 | LJ_FUNC void lj_snap_grow_map_(jit_State *J, MSize need); |