diff options
Diffstat (limited to 'src/lj_opt_dce.c')
-rw-r--r-- | src/lj_opt_dce.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/lj_opt_dce.c b/src/lj_opt_dce.c new file mode 100644 index 00000000..0cd60830 --- /dev/null +++ b/src/lj_opt_dce.c | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE. | ||
3 | ** Copyright (C) 2005-2009 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 | IRRef2 *map = &J->cur.snapmap[snap->mapofs]; | ||
27 | BCReg s, nslots = snap->nslots; | ||
28 | for (s = 0; s < nslots; s++) { | ||
29 | IRRef ref = snap_ref(map[s]); | ||
30 | if (!irref_isk(ref)) | ||
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 (!(irt_isguard(ir->t) || irm_sideeff(lj_ir_mode[ir->o]))) { | ||
49 | *pchain[ir->o] = ir->prev; /* Reroute original instruction chain. */ | ||
50 | *pchain[IR_NOP] = (IRRef1)ins; | ||
51 | ir->t.irt = IRT_NIL; | ||
52 | ir->o = IR_NOP; /* Replace instruction with NOP. */ | ||
53 | ir->op1 = ir->op2 = 0; | ||
54 | pchain[IR_NOP] = &ir->prev; | ||
55 | continue; | ||
56 | } | ||
57 | if (!irref_isk(ir->op1)) irt_setmark(IR(ir->op1)->t); | ||
58 | if (!irref_isk(ir->op2)) irt_setmark(IR(ir->op2)->t); | ||
59 | } | ||
60 | *pchain[IR_NOP] = 0; /* Terminate NOP chain. */ | ||
61 | } | ||
62 | |||
63 | /* Dead Code Elimination. | ||
64 | ** | ||
65 | ** First backpropagate marks for all used instructions. Then replace | ||
66 | ** the unused ones with a NOP. Note that compressing the IR to eliminate | ||
67 | ** the NOPs does not pay off. | ||
68 | */ | ||
69 | void lj_opt_dce(jit_State *J) | ||
70 | { | ||
71 | if ((J->flags & JIT_F_OPT_DCE)) { | ||
72 | dce_marksnap(J); | ||
73 | dce_propagate(J); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | #undef IR | ||
78 | |||
79 | #endif | ||