From dcb6968e77064d78d0f77ec693f35fdbf65e9b4b Mon Sep 17 00:00:00 2001 From: tyfkda <tyfkda@gmail.com> Date: Thu, 19 Dec 2024 09:31:30 +0900 Subject: [PATCH] Keep original VReg pointer instead of index Also eliminate version. --- src/_debug/dump_ir.c | 103 ++++++++++++++++++++------------------ src/cc/backend/ir.h | 3 +- src/cc/backend/optimize.c | 11 ++++ src/cc/backend/regalloc.c | 12 ++--- src/cc/backend/regalloc.h | 2 +- src/cc/backend/ssa.c | 25 ++++----- 6 files changed, 87 insertions(+), 69 deletions(-) diff --git a/src/_debug/dump_ir.c b/src/_debug/dump_ir.c index 6a02acbb8..a8e7a3440 100644 --- a/src/_debug/dump_ir.c +++ b/src/_debug/dump_ir.c @@ -22,23 +22,30 @@ static bool keep_virtual_register; extern void install_builtins(void); -static void dump_vvreg(FILE *fp, VReg *vreg) { - if (vreg->version == 0) { +static void dump_vvreg(FILE *fp, VReg *vreg, RegAlloc *ra) { + if (vreg->original == vreg) { fprintf(fp, "V%d", vreg->virt); } else { + Vector *versions = ra->vreg_table[vreg->original->virt]; + int version; + for (version = 0; version < versions->len; ++version) { + if (versions->data[version] == vreg) + break; + } + assert(version < versions->len); + char buf[16], *p = buf + sizeof(buf); *(--p) = '\0'; - int version = vreg->version; do { --version; *(--p) = 'a' + (version % 26); version /= 26; } while (version > 0); - fprintf(fp, "v%d%s", vreg->orig_virt, p); + fprintf(fp, "v%d%s", vreg->original->virt, p); } } -static void dump_vreg(FILE *fp, VReg *vreg) { +static void dump_vreg(FILE *fp, VReg *vreg, RegAlloc *ra) { assert(vreg != NULL); assert(!(vreg->flag & VRF_SPILLED)); static const char *kSize[] = {"b", "w", "d", ""}; @@ -56,15 +63,15 @@ static void dump_vreg(FILE *fp, VReg *vreg) { regtype = 'F'; fprintf(fp, "%c%d%s<v%d>", regtype, vreg->phys, kSize[vreg->vsize], vreg->virt); } else { - dump_vvreg(fp, vreg); + dump_vvreg(fp, vreg, ra); } } -static void dump_vreg2(FILE *fp, VReg *vreg) { +static void dump_vreg2(FILE *fp, VReg *vreg, RegAlloc *ra) { if (vreg->flag & VRF_SPILLED) { fprintf(fp, "spilled(v%d)", vreg->virt); } else { - dump_vreg(fp, vreg); + dump_vreg(fp, vreg, ra); } } @@ -80,7 +87,7 @@ static void dump_vregs(FILE *fp, const char *title, Vector *regs, bool newline) fprintf(fp, "]"); } -static void dump_ir(FILE *fp, IR *ir) { +static void dump_ir(FILE *fp, IR *ir, RegAlloc *ra) { static char *kOps[] = { "BOFS", "IOFS", "SOFS", "LOAD", "LOAD_S", "STORE", "STORE_S", "ADD", "SUB", "MUL", "DIV", "MOD", "BITAND", "BITOR", "BITXOR", "LSHIFT", "RSHIFT", "COND", @@ -105,55 +112,55 @@ static void dump_ir(FILE *fp, IR *ir) { } switch (ir->kind) { - case IR_BOFS: { int64_t offset = ir->bofs.frameinfo->offset + ir->bofs.offset; dump_vreg(fp, ir->dst); fprintf(fp, " = &[rbp %c %" PRId64 "]\n", offset >= 0 ? '+' : '-', offset > 0 ? offset : -offset); } break; - case IR_IOFS: dump_vreg(fp, ir->dst); fprintf(fp, " = &%.*s", NAMES(ir->iofs.label)); if (ir->iofs.offset != 0) { int64_t offset = ir->iofs.offset; fprintf(fp, " %c %" PRId64, offset >= 0 ? '+' : '-', offset > 0 ? offset : -offset); } fprintf(fp, "\n"); break; - case IR_SOFS: dump_vreg(fp, ir->dst); fprintf(fp, " = &[rsp %c %" PRId64 "]\n", ir->opr1->fixnum >= 0 ? '+' : '-', ir->opr1->fixnum > 0 ? ir->opr1->fixnum : -ir->opr1->fixnum); break; - case IR_LOAD: dump_vreg(fp, ir->dst); fprintf(fp, " = ["); dump_vreg(fp, ir->opr1); fprintf(fp, "]\n"); break; - case IR_LOAD_S: dump_vreg(fp, ir->dst); fprintf(fp, " = [v%d]\n", ir->opr1->virt); break; - case IR_STORE: fprintf(fp, "["); dump_vreg(fp, ir->opr2); fprintf(fp, "] = "); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_STORE_S:fprintf(fp, "[v%d] = ", ir->opr2->virt); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_ADD: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " + "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_SUB: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " - "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_MUL: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " * "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_DIV: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " / "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_MOD: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " %% "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_BITAND: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " & "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_BITOR: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " | "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_BITXOR: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " ^ "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_LSHIFT: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " << "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_RSHIFT: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, " >> "); dump_vreg(fp, ir->opr2); fprintf(fp, "\n"); break; - case IR_COND: dump_vreg(fp, ir->dst); fprintf(fp, " = "); if (ir->cond.kind != COND_ANY && ir->cond.kind != COND_NONE) {dump_vreg(fp, ir->opr1); fprintf(fp, " %s ", kCond2[ir->cond.kind & (COND_MASK | COND_UNSIGNED)]); dump_vreg(fp, ir->opr2);} fprintf(fp, "\n"); break; - case IR_NEG: dump_vreg(fp, ir->dst); fprintf(fp, " = -"); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_BITNOT: dump_vreg(fp, ir->dst); fprintf(fp, " = ~"); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_CAST: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_MOV: dump_vreg(fp, ir->dst); fprintf(fp, " = "); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_RESULT: if (ir->dst != NULL) { dump_vreg(fp, ir->dst); fprintf(fp, " = "); } dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; - case IR_JMP: if (ir->jmp.cond != COND_ANY && ir->jmp.cond != COND_NONE) {dump_vreg(fp, ir->opr1); fprintf(fp, ", "); dump_vreg(fp, ir->opr2); fprintf(fp, ", ");} fprintf(fp, "%.*s\n", NAMES(ir->jmp.bb->label)); break; + case IR_BOFS: { int64_t offset = ir->bofs.frameinfo->offset + ir->bofs.offset; dump_vreg(fp, ir->dst, ra); fprintf(fp, " = &[rbp %c %" PRId64 "]\n", offset >= 0 ? '+' : '-', offset > 0 ? offset : -offset); } break; + case IR_IOFS: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = &%.*s", NAMES(ir->iofs.label)); if (ir->iofs.offset != 0) { int64_t offset = ir->iofs.offset; fprintf(fp, " %c %" PRId64, offset >= 0 ? '+' : '-', offset > 0 ? offset : -offset); } fprintf(fp, "\n"); break; + case IR_SOFS: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = &[rsp %c %" PRId64 "]\n", ir->opr1->fixnum >= 0 ? '+' : '-', ir->opr1->fixnum > 0 ? ir->opr1->fixnum : -ir->opr1->fixnum); break; + case IR_LOAD: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = ["); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "]\n"); break; + case IR_LOAD_S: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = [v%d]\n", ir->opr1->virt); break; + case IR_STORE: fprintf(fp, "["); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "] = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_STORE_S:fprintf(fp, "[v%d] = ", ir->opr2->virt); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_ADD: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " + "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_SUB: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " - "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_MUL: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " * "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_DIV: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " / "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_MOD: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " %% "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_BITAND: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " & "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_BITOR: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " | "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_BITXOR: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " ^ "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_LSHIFT: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " << "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_RSHIFT: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, " >> "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, "\n"); break; + case IR_COND: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); if (ir->cond.kind != COND_ANY && ir->cond.kind != COND_NONE) {dump_vreg(fp, ir->opr1, ra); fprintf(fp, " %s ", kCond2[ir->cond.kind & (COND_MASK | COND_UNSIGNED)]); dump_vreg(fp, ir->opr2, ra);} fprintf(fp, "\n"); break; + case IR_NEG: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = -"); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_BITNOT: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = ~"); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_CAST: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_MOV: dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_RESULT: if (ir->dst != NULL) { dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); } dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; + case IR_JMP: if (ir->jmp.cond != COND_ANY && ir->jmp.cond != COND_NONE) {dump_vreg(fp, ir->opr1, ra); fprintf(fp, ", "); dump_vreg(fp, ir->opr2, ra); fprintf(fp, ", ");} fprintf(fp, "%.*s\n", NAMES(ir->jmp.bb->label)); break; case IR_TJMP: - dump_vreg(fp, ir->opr1); + dump_vreg(fp, ir->opr1, ra); for (size_t i = 0; i < ir->tjmp.len; ++i) fprintf(fp, "%s%.*s", i == 0 ? ", [" : ", ", NAMES(((BB*)ir->tjmp.bbs[i])->label)); fprintf(fp, "]"); - if (ir->opr2 != NULL) {fprintf(fp, " (tmp="); dump_vreg(fp, ir->opr2); fprintf(fp, ")");} + if (ir->opr2 != NULL) {fprintf(fp, " (tmp="); dump_vreg(fp, ir->opr2, ra); fprintf(fp, ")");} fprintf(fp, "\n"); break; - case IR_PUSHARG: fprintf(fp, "%d, ", ir->pusharg.index); dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; + case IR_PUSHARG: fprintf(fp, "%d, ", ir->pusharg.index); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; case IR_CALL: - if (ir->dst != NULL) { dump_vreg(fp, ir->dst); fprintf(fp, " = "); } + if (ir->dst != NULL) { dump_vreg(fp, ir->dst, ra); fprintf(fp, " = "); } if (ir->call->label != NULL) { fprintf(fp, "%.*s(args=#%d)\n", NAMES(ir->call->label), ir->call->reg_arg_count); } else { - fprintf(fp, "*"); dump_vreg(fp, ir->opr1); fprintf(fp, "(args=#%d)\n", ir->call->reg_arg_count); + fprintf(fp, "*"); dump_vreg(fp, ir->opr1, ra); fprintf(fp, "(args=#%d)\n", ir->call->reg_arg_count); } break; - case IR_SUBSP: dump_vreg(fp, ir->opr1); fprintf(fp, "\n"); break; + case IR_SUBSP: dump_vreg(fp, ir->opr1, ra); fprintf(fp, "\n"); break; case IR_KEEP: - if (ir->dst != NULL) { fprintf(fp, "dst:"); dump_vreg(fp, ir->dst); fprintf(fp, ", "); } + if (ir->dst != NULL) { fprintf(fp, "dst:"); dump_vreg(fp, ir->dst, ra); fprintf(fp, ", "); } if (ir->opr1 != NULL) { - dump_vreg(fp, ir->opr1); + dump_vreg(fp, ir->opr1, ra); if (ir->opr2 != NULL) { fprintf(fp, ", "); - dump_vreg(fp, ir->opr2); + dump_vreg(fp, ir->opr2, ra); } } fprintf(fp, "\n"); @@ -219,9 +226,9 @@ static void dump_func_ir(Function *func) { { fprintf(fp, " V%3d (flag=%x): live %3d - %3d", li->virt, vreg->flag, li->start, li->end); if (keep_virtual_register) { - if (vreg->version > 0) { + if (vreg->original != vreg) { fprintf(fp, ", "); - dump_vvreg(fp, vreg); + dump_vvreg(fp, vreg, ra); } } else { char regtype = vreg->flag & VRF_FLONUM ? 'F' : 'R'; @@ -249,7 +256,7 @@ static void dump_func_ir(Function *func) { VReg *vreg = vregs->data[j]; if (j > 0) fprintf(fp, ", "); - dump_vreg(fp, vreg); + dump_vreg(fp, vreg, ra); fprintf(fp, "(%d)", vreg->virt); } fprintf(fp, "]\n"); @@ -280,13 +287,13 @@ static void dump_func_ir(Function *func) { for (int j = 0; j < bb->phis->len; ++j) { Phi *phi = bb->phis->data[j]; fprintf(fp, " \tPHI "); - dump_vreg2(fp, phi->dst); + dump_vreg2(fp, phi->dst, ra); fprintf(fp, " = {"); for (int i = 0; i < phi->params->len; ++i) { VReg *vreg = phi->params->data[i]; if (i > 0) fprintf(fp, ", "); - dump_vreg2(fp, vreg); + dump_vreg2(fp, vreg, ra); } fprintf(fp, "}\n"); } @@ -295,7 +302,7 @@ static void dump_func_ir(Function *func) { for (int j = 0; j < bb->irs->len; ++j, ++nip) { fprintf(fp, "%6d|\t", nip); IR *ir = bb->irs->data[j]; - dump_ir(fp, ir); + dump_ir(fp, ir, ra); } } fprintf(fp, "\n"); diff --git a/src/cc/backend/ir.h b/src/cc/backend/ir.h index 3b5742090..572152eba 100644 --- a/src/cc/backend/ir.h +++ b/src/cc/backend/ir.h @@ -42,10 +42,9 @@ typedef struct VReg { union { // Non-const: struct { + struct VReg *original; // If this member is same as itself, it is the original. int virt; // Virtual reg no. int phys; // Physical reg no. - int version; // Version number for SSA. - int orig_virt; int reg_param_index; // Index of function parameter through register: -1=non reg param. FrameInfo frame; // FrameInfo for spilled register. }; diff --git a/src/cc/backend/optimize.c b/src/cc/backend/optimize.c index 81eb4e7d6..8a946a4de 100644 --- a/src/cc/backend/optimize.c +++ b/src/cc/backend/optimize.c @@ -193,6 +193,17 @@ static void remove_unused_vregs(RegAlloc *ra, BBContainer *bbcon) { VReg *vreg; if (!vreg_read[i] && (vreg = ra->vregs->data[i]) != NULL) { ra->vregs->data[i] = NULL; + if (vreg->original != vreg) { + assert(vreg->original->virt < ra->original_vreg_count); + Vector *vt = ra->vreg_table[vreg->original->virt]; + int j; + for (j = 0; j < vt->len; ++j) { + if (vt->data[j] == vreg) + break; + } + assert(j < vt->len); + vec_remove_at(vt, j); + } vreg->flag |= VRF_UNUSED; again = true; } diff --git a/src/cc/backend/regalloc.c b/src/cc/backend/regalloc.c index b46876389..488762c85 100644 --- a/src/cc/backend/regalloc.c +++ b/src/cc/backend/regalloc.c @@ -38,9 +38,9 @@ VReg *reg_alloc_spawn(RegAlloc *ra, enum VRegSize vsize, int vflag) { assert(ra != NULL); VReg *vreg = reg_alloc_spawn_raw(vsize, vflag); if (!(vflag & VRF_CONST)) { - vreg->virt = vreg->orig_virt = ra->vregs->len; + vreg->original = vreg; // I am the original. + vreg->virt = ra->vregs->len; vreg->phys = -1; - vreg->version = 0; vreg->reg_param_index = -1; vreg->frame.offset = 0; vec_push(ra->vregs, vreg); @@ -50,10 +50,10 @@ VReg *reg_alloc_spawn(RegAlloc *ra, enum VRegSize vsize, int vflag) { return vreg; } -VReg *reg_alloc_with_version(RegAlloc *ra, VReg *parent, int version) { - VReg *vreg = reg_alloc_spawn(ra, parent->vsize, parent->flag & VRF_MASK); - vreg->orig_virt = parent->virt; - vreg->version = version; +VReg *reg_alloc_with_original(RegAlloc *ra, VReg *original) { + assert(original->original == original); + VReg *vreg = reg_alloc_spawn(ra, original->vsize, original->flag & VRF_MASK); + vreg->original = original; return vreg; } diff --git a/src/cc/backend/regalloc.h b/src/cc/backend/regalloc.h index a00d8aba8..37a79e1e2 100644 --- a/src/cc/backend/regalloc.h +++ b/src/cc/backend/regalloc.h @@ -55,7 +55,7 @@ typedef struct RegAlloc { RegAlloc *new_reg_alloc(const RegAllocSettings *settings); VReg *reg_alloc_spawn_raw(enum VRegSize vsize, int vflag); VReg *reg_alloc_spawn(RegAlloc *ra, enum VRegSize vsize, int vflag); -VReg *reg_alloc_with_version(RegAlloc *ra, VReg *parent, int version); +VReg *reg_alloc_with_original(RegAlloc *ra, VReg *original); VReg *reg_alloc_spawn_const(RegAlloc *ra, int64_t value, enum VRegSize vsize); #ifndef __NO_FLONUM VReg *reg_alloc_spawn_fconst(RegAlloc *ra, double value, enum VRegSize vsize); diff --git a/src/cc/backend/ssa.c b/src/cc/backend/ssa.c index 47ea80ed2..cdfefc16a 100644 --- a/src/cc/backend/ssa.c +++ b/src/cc/backend/ssa.c @@ -12,7 +12,9 @@ #include "table.h" -#define ORIG_VIRT(vreg) ((vreg)->orig_virt >= 0 ? (vreg)->orig_virt : (vreg)->virt) +static inline int ORIG_VIRT(VReg *vreg) { + return vreg->original->virt; +} static inline void assign_new_vregs(RegAlloc *ra, Vector **vreg_table, BB *bb, VReg **vregs) { for (int iir = 0; iir < bb->irs->len; ++iir) { @@ -28,7 +30,7 @@ static inline void assign_new_vregs(RegAlloc *ra, Vector **vreg_table, BB *bb, V Vector *vt = vreg_table[virt]; VReg *dst = ra->vregs->data[virt]; if (vt->len > 0) - ir->dst = dst = reg_alloc_with_version(ra, dst, vt->len); + ir->dst = dst = reg_alloc_with_original(ra, dst); vec_push(vt, dst); vregs[virt] = dst; } @@ -123,7 +125,7 @@ static Vector **ssa_transform(RegAlloc *ra, BBContainer *bbcon) { continue; int virt = ORIG_VIRT(vreg); // `vreg` must be original, though. Vector *vt = vreg_table[virt]; - VReg *newver = reg_alloc_with_version(ra, ra->vregs->data[virt], vt->len); + VReg *newver = reg_alloc_with_original(ra, ra->vregs->data[virt]); bb->in_regs->data[i] = vregs[virt] = newver; vec_push(vt, newver); } @@ -168,14 +170,14 @@ static void insert_phis(BBContainer *bbcon, int original_vreg_count) { BB *from = bb->from_bbs->data[ifrom]; for (int j = 0; j < from->out_regs->len; ++j) { VReg *oreg = from->out_regs->data[j]; - assert(0 <= oreg->orig_virt && oreg->orig_virt < original_vreg_count); - from_vregs[oreg->orig_virt] = oreg; + assert(0 <= ORIG_VIRT(oreg) && ORIG_VIRT(oreg) < original_vreg_count); + from_vregs[ORIG_VIRT(oreg)] = oreg; } for (int j = 0; j < reg_count; ++j) { VReg *vreg = bb->in_regs->data[j]; - assert(0 <= vreg->orig_virt && vreg->orig_virt < original_vreg_count); - VReg *fv = from_vregs[vreg->orig_virt]; + assert(vreg->original != vreg && 0 <= ORIG_VIRT(vreg) && ORIG_VIRT(vreg) < original_vreg_count); + VReg *fv = from_vregs[ORIG_VIRT(vreg)]; vec_push(phi_params->data[j], fv); } } @@ -389,11 +391,10 @@ static void replace_phis(RegAlloc *ra, BB *bb, int ifb, Vector *phis) { Phi *first = cyclic->data[0]; // Allocate temporary vreg. - VReg *parent = first->dst; - assert(parent->orig_virt >= 0); // phi's destination must not be an original virtual register. - Vector *vt = vreg_table[parent->orig_virt]; - VReg *tmp = reg_alloc_with_version(ra, parent, vt->len); - tmp->orig_virt = parent->orig_virt; + assert(first->dst->original != first->dst); // phi's destination must not be an original virtual register. + VReg *original = first->dst->original; + Vector *vt = vreg_table[original->virt]; + VReg *tmp = reg_alloc_with_original(ra, original); vec_push(vt, tmp); for (int j = 0; j < cyclic->len; ++j) {