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 }