kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

pass_mir.c (3038B)


      1 #include "opt/opt_internal.h"
      2 
      3 static int mir_view(Func* f, Func* out) {
      4   if (!f || !f->mir) return 0;
      5   *out = *f;
      6   out->blocks = f->mir->blocks;
      7   out->nblocks = f->mir->nblocks;
      8   out->entry = f->mir->entry;
      9   out->emit_order = f->mir->emit_order;
     10   out->emit_order_n = f->mir->emit_order_n;
     11   out->emit_order_cap = f->mir->emit_order_cap;
     12   out->opt_rewritten = 1;
     13   out->mir = NULL;
     14   return 1;
     15 }
     16 
     17 static void mir_commit(Func* f, const Func* view) {
     18   if (!f || !f->mir || !view) return;
     19   f->mir->blocks = view->blocks;
     20   f->mir->nblocks = view->nblocks;
     21   f->mir->entry = view->entry;
     22   f->mir->emit_order = view->emit_order;
     23   f->mir->emit_order_n = view->emit_order_n;
     24   f->mir->emit_order_cap = view->emit_order_cap;
     25 }
     26 
     27 static void mir_verify_reg(Func* f, const char* stage, Reg r, u8 cls,
     28                            const char* what) {
     29   if (r == (Reg)REG_NONE || cls >= OPT_REG_CLASSES || r >= OPT_MAX_HARD_REGS) {
     30     SrcLoc loc = {0, 0, 0};
     31     compiler_panic(f->c, loc, "opt MIR verify %s: bad %s cls%u reg%u",
     32                    stage ? stage : "?", what, (unsigned)cls, (unsigned)r);
     33   }
     34 }
     35 
     36 static void mir_verify_operand(Func* f, Inst* in, Operand* op, int is_def,
     37                                void* arg) {
     38   (void)in;
     39   (void)is_def;
     40   const char* stage = (const char*)arg;
     41   if (!op) return;
     42   if (op->kind == OPK_REG) {
     43     mir_verify_reg(f, stage, op->v.reg, op->cls, "register operand");
     44   } else if (op->kind == OPK_INDIRECT) {
     45     mir_verify_reg(f, stage, op->v.ind.base, RC_INT, "indirect base");
     46     if (op->v.ind.index != (Reg)REG_NONE)
     47       mir_verify_reg(f, stage, op->v.ind.index, RC_INT, "indirect index");
     48   } else if (op->kind == OPK_LOCAL) {
     49     if (op->v.frame_slot == FRAME_SLOT_NONE ||
     50         op->v.frame_slot > f->nframe_slots) {
     51       SrcLoc loc = {0, 0, 0};
     52       compiler_panic(f->c, loc, "opt MIR verify %s: bad frame slot %u",
     53                      stage ? stage : "?", (unsigned)op->v.frame_slot);
     54     }
     55   }
     56 }
     57 
     58 void opt_mir_verify(Func* f, const char* stage) {
     59   Func v;
     60   if (!mir_view(f, &v)) return;
     61   for (u32 b = 0; b < v.nblocks; ++b) {
     62     Block* bl = &v.blocks[b];
     63     for (u32 i = 0; i < bl->ninsts; ++i) {
     64       Inst* in = &bl->insts[i];
     65       if ((IROp)in->op == IR_PHI) {
     66         SrcLoc loc = in->loc;
     67         compiler_panic(f->c, loc, "opt MIR verify %s: phi survived lowering",
     68                        stage ? stage : "?");
     69       }
     70       if ((IROp)in->op == IR_PARAM_DECL) continue;
     71       opt_walk_inst_operands(&v, in, mir_verify_operand, (void*)stage);
     72     }
     73   }
     74 }
     75 
     76 void opt_mir_combine(Func* f) {
     77   Func v;
     78   if (!mir_view(f, &v)) return;
     79   opt_combine(&v);
     80   mir_commit(f, &v);
     81 }
     82 
     83 void opt_mir_dce(Func* f) {
     84   Func v;
     85   if (!mir_view(f, &v)) return;
     86   opt_dce(&v);
     87   mir_commit(f, &v);
     88 }
     89 
     90 void opt_mir_build_cfg(Func* f) {
     91   Func v;
     92   if (!mir_view(f, &v)) return;
     93   opt_build_cfg(&v);
     94   mir_commit(f, &v);
     95 }
     96 
     97 void opt_mir_jump_cleanup(Func* f, OptJumpCleanupStage stage) {
     98   Func v;
     99   if (!mir_view(f, &v)) return;
    100   opt_jump_cleanup(&v, stage);
    101   mir_commit(f, &v);
    102 }