ljx

FORK: LuaJIT with native 5.2 and 5.3 support
git clone https://git.neptards.moe/neptards/ljx.git
Log | Files | Refs | README

lj_opt_dce.c (2031B)


      1 /*
      2 ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE.
      3 ** Copyright (C) 2005-2016 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     memset(J->bpropcache, 0, sizeof(J->bpropcache));  /* Invalidate cache. */
     73   }
     74 }
     75 
     76 #undef IR
     77 
     78 #endif