| 1 | /* |
|---|---|
| 2 | ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE. |
| 3 | ** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h |
| 4 | */ |
| 5 | |
| 6 | #define lj_opt_dce_c |
| 7 | #define LUA_CORE |
| 8 | |
| 9 | #include "lj_obj.h" |
| 10 | |
| 11 | #if LJ_HASJIT |
| 12 | |
| 13 | #include "lj_ir.h" |
| 14 | #include "lj_jit.h" |
| 15 | #include "lj_iropt.h" |
| 16 | |
| 17 | /* Some local macros to save typing. Undef'd at the end. */ |
| 18 | #define IR(ref) (&J->cur.ir[(ref)]) |
| 19 | |
| 20 | /* Scan through all snapshots and mark all referenced instructions. */ |
| 21 | static void dce_marksnap(jit_State *J) |
| 22 | { |
| 23 | SnapNo i, nsnap = J->cur.nsnap; |
| 24 | for (i = 0; i < nsnap; i++) { |
| 25 | SnapShot *snap = &J->cur.snap[i]; |
| 26 | SnapEntry *map = &J->cur.snapmap[snap->mapofs]; |
| 27 | MSize n, nent = snap->nent; |
| 28 | for (n = 0; n < nent; n++) { |
| 29 | IRRef ref = snap_ref(map[n]); |
| 30 | if (ref >= REF_FIRST) |
| 31 | irt_setmark(IR(ref)->t); |
| 32 | } |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | /* Backwards propagate marks. Replace unused instructions with NOPs. */ |
| 37 | static void dce_propagate(jit_State *J) |
| 38 | { |
| 39 | IRRef1 *pchain[IR__MAX]; |
| 40 | IRRef ins; |
| 41 | uint32_t i; |
| 42 | for (i = 0; i < IR__MAX; i++) pchain[i] = &J->chain[i]; |
| 43 | for (ins = J->cur.nins-1; ins >= REF_FIRST; ins--) { |
| 44 | IRIns *ir = IR(ins); |
| 45 | if (irt_ismarked(ir->t)) { |
| 46 | irt_clearmark(ir->t); |
| 47 | pchain[ir->o] = &ir->prev; |
| 48 | } else if (!ir_sideeff(ir)) { |
| 49 | *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */ |
| 50 | ir->t.irt = IRT_NIL; |
| 51 | ir->o = IR_NOP; /* Replace instruction with NOP. */ |
| 52 | ir->op1 = ir->op2 = 0; |
| 53 | ir->prev = 0; |
| 54 | continue; |
| 55 | } |
| 56 | if (ir->op1 >= REF_FIRST) irt_setmark(IR(ir->op1)->t); |
| 57 | if (ir->op2 >= REF_FIRST) irt_setmark(IR(ir->op2)->t); |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /* Dead Code Elimination. |
| 62 | ** |
| 63 | ** First backpropagate marks for all used instructions. Then replace |
| 64 | ** the unused ones with a NOP. Note that compressing the IR to eliminate |
| 65 | ** the NOPs does not pay off. |
| 66 | */ |
| 67 | void lj_opt_dce(jit_State *J) |
| 68 | { |
| 69 | if ((J->flags & JIT_F_OPT_DCE)) { |
| 70 | dce_marksnap(J); |
| 71 | dce_propagate(J); |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | #undef IR |
| 76 | |
| 77 | #endif |
| 78 |