src/lj_opt_dce.c - luajit-2.0-src

Functions defined

Macros defined

Source code

  1. /*
  2. ** DCE: Dead Code Elimination. Pre-LOOP only -- ASM already performs DCE.
  3. ** Copyright (C) 2005-2015 Mike Pall. See Copyright Notice in luajit.h
  4. */

  5. #define lj_opt_dce_c
  6. #define LUA_CORE

  7. #include "lj_obj.h"

  8. #if LJ_HASJIT

  9. #include "lj_ir.h"
  10. #include "lj_jit.h"
  11. #include "lj_iropt.h"

  12. /* Some local macros to save typing. Undef'd at the end. */
  13. #define IR(ref)                (&J->cur.ir[(ref)])

  14. /* Scan through all snapshots and mark all referenced instructions. */
  15. static void dce_marksnap(jit_State *J)
  16. {
  17.   SnapNo i, nsnap = J->cur.nsnap;
  18.   for (i = 0; i < nsnap; i++) {
  19.     SnapShot *snap = &J->cur.snap[i];
  20.     SnapEntry *map = &J->cur.snapmap[snap->mapofs];
  21.     MSize n, nent = snap->nent;
  22.     for (n = 0; n < nent; n++) {
  23.       IRRef ref = snap_ref(map[n]);
  24.       if (ref >= REF_FIRST)
  25.         irt_setmark(IR(ref)->t);
  26.     }
  27.   }
  28. }

  29. /* Backwards propagate marks. Replace unused instructions with NOPs. */
  30. static void dce_propagate(jit_State *J)
  31. {
  32.   IRRef1 *pchain[IR__MAX];
  33.   IRRef ins;
  34.   uint32_t i;
  35.   for (i = 0; i < IR__MAX; i++) pchain[i] = &J->chain[i];
  36.   for (ins = J->cur.nins-1; ins >= REF_FIRST; ins--) {
  37.     IRIns *ir = IR(ins);
  38.     if (irt_ismarked(ir->t)) {
  39.       irt_clearmark(ir->t);
  40.       pchain[ir->o] = &ir->prev;
  41.     } else if (!ir_sideeff(ir)) {
  42.       *pchain[ir->o] = ir->prev;  /* Reroute original instruction chain. */
  43.       ir->t.irt = IRT_NIL;
  44.       ir->o = IR_NOP;  /* Replace instruction with NOP. */
  45.       ir->op1 = ir->op2 = 0;
  46.       ir->prev = 0;
  47.       continue;
  48.     }
  49.     if (ir->op1 >= REF_FIRST) irt_setmark(IR(ir->op1)->t);
  50.     if (ir->op2 >= REF_FIRST) irt_setmark(IR(ir->op2)->t);
  51.   }
  52. }

  53. /* Dead Code Elimination.
  54. **
  55. ** First backpropagate marks for all used instructions. Then replace
  56. ** the unused ones with a NOP. Note that compressing the IR to eliminate
  57. ** the NOPs does not pay off.
  58. */
  59. void lj_opt_dce(jit_State *J)
  60. {
  61.   if ((J->flags & JIT_F_OPT_DCE)) {
  62.     dce_marksnap(J);
  63.     dce_propagate(J);
  64.     memset(J->bpropcache, 0, sizeof(J->bpropcache));  /* Invalidate cache. */
  65.   }
  66. }

  67. #undef IR

  68. #endif