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. */
21static 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. */
37static 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*/
67void 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