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 |