Skip to content

Commit

Permalink
Separate const-vregs management
Browse files Browse the repository at this point in the history
And share a register if the value is same.
  • Loading branch information
tyfkda committed Oct 13, 2023
1 parent 83183e2 commit 054fda0
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 25 deletions.
2 changes: 0 additions & 2 deletions src/_debug/dump_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,6 @@ static void dump_func_ir(Function *func) {
case LI_SPILL:
fprintf(fp, " V%3d (flag=%x): live %3d - %3d (spilled, offset=%d)\n", li->virt, vreg->flag, li->start, li->end, vreg->frame.offset);
break;
case LI_CONST:
continue;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/cc/backend/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,8 +737,8 @@ static void map_virtual_to_physical_registers(RegAlloc *ra) {
VReg *vreg = ra->vregs->data[i];
if (vreg == NULL)
continue;
if (!(vreg->flag & VRF_CONST))
vreg->phys = ra->intervals[vreg->virt].phys;
assert(!(vreg->flag & VRF_CONST) && vreg->virt >= 0);
vreg->phys = ra->intervals[vreg->virt].phys;
}
}

Expand Down
4 changes: 1 addition & 3 deletions src/cc/backend/ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@ static IR *new_ir(enum IrKind kind) {
}

VReg *new_const_vreg(int64_t value, enum VRegSize vsize, int vflag) {
VReg *vreg = reg_alloc_spawn(curra, vsize, vflag | VRF_CONST);
vreg->fixnum = value;
return vreg;
return reg_alloc_spawn_const(curra, value, vsize, vflag);
}

VReg *new_ir_bop(enum IrKind kind, VReg *opr1, VReg *opr2, enum VRegSize vsize) {
Expand Down
2 changes: 1 addition & 1 deletion src/cc/backend/optimize.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static void remove_unused_vregs(RegAlloc *ra, BBContainer *bbcon) {
VReg *operands[] = {ir->opr1, ir->opr2};
for (int k = 0; k < 2; ++k) {
VReg *vreg = operands[k];
if (vreg != NULL)
if (vreg != NULL && !(vreg->flag & VRF_CONST))
vreg_read[vreg->virt] = true;
}
}
Expand Down
48 changes: 33 additions & 15 deletions src/cc/backend/regalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ RegAlloc *new_reg_alloc(const RegAllocSettings *settings) {
assert(settings->phys_max < (int)(sizeof(ra->used_reg_bits) * CHAR_BIT));
ra->settings = settings;
ra->vregs = new_vector();
ra->consts = new_vector();
ra->intervals = NULL;
ra->sorted_intervals = NULL;
ra->used_reg_bits = 0;
Expand All @@ -24,19 +25,39 @@ RegAlloc *new_reg_alloc(const RegAllocSettings *settings) {
return ra;
}

VReg *reg_alloc_spawn(RegAlloc *ra, enum VRegSize vsize, int vflag) {
int vreg_no = ra->vregs->len;

static VReg *alloc_vreg(enum VRegSize vsize, int vflag) {
VReg *vreg = malloc_or_die(sizeof(*vreg));
vreg->virt = vreg_no;
vreg->virt = -1;
vreg->phys = -1;
vreg->fixnum = 0;
vreg->vsize = vsize;
vreg->flag = vflag;
vreg->reg_param_index = -1;
vreg->frame.offset = 0;
return vreg;
}

VReg *reg_alloc_spawn(RegAlloc *ra, enum VRegSize vsize, int vflag) {
VReg *vreg = alloc_vreg(vsize, vflag);
if (!(vflag & VRF_CONST)) {
vreg->virt = ra->vregs->len;
vec_push(ra->vregs, vreg);
} else {
vec_push(ra->consts, vreg);
}
return vreg;
}

vec_push(ra->vregs, vreg);
VReg *reg_alloc_spawn_const(RegAlloc *ra, int64_t value, enum VRegSize vsize, int vflag) {
vflag |= VRF_CONST;
for (int i = 0; i < ra->consts->len; ++i) {
VReg *v = ra->consts->data[i];
if (v->fixnum == value && v->vsize == vsize && v->flag == vflag)
return v;
}

VReg *vreg = reg_alloc_spawn(ra, vsize, vflag);
vreg->fixnum = value;
return vreg;
}

Expand Down Expand Up @@ -385,20 +406,20 @@ static int insert_load_store_spilled_irs(RegAlloc *ra, BBContainer *bbcon) {
continue;
}

if (ir->opr1 != NULL && (flag & 1) != 0 &&
!(ir->opr1->flag & VRF_CONST) && (ir->opr1->flag & VRF_SPILLED)) {
if (ir->opr1 != NULL && (flag & 1) != 0 && (ir->opr1->flag & VRF_SPILLED)) {
assert(!(ir->opr1->flag & VRF_CONST));
j = insert_tmp_reg(ra, irs, j, ir->opr1);
++inserted;
}

if (ir->opr2 != NULL && (flag & 2) != 0 &&
!(ir->opr2->flag & VRF_CONST) && (ir->opr2->flag & VRF_SPILLED)) {
if (ir->opr2 != NULL && (flag & 2) != 0 && (ir->opr2->flag & VRF_SPILLED)) {
assert(!(ir->opr2->flag & VRF_CONST));
j = insert_tmp_reg(ra, irs, j, ir->opr2);
++inserted;
}

if (ir->dst != NULL && (flag & 4) != 0 &&
!(ir->dst->flag & VRF_CONST) && (ir->dst->flag & VRF_SPILLED)) {
if (ir->dst != NULL && (flag & 4) != 0 && (ir->dst->flag & VRF_SPILLED)) {
assert(!(ir->dst->flag & VRF_CONST));
j = insert_tmp_reg(ra, irs, j, ir->dst);
++inserted;
}
Expand All @@ -424,10 +445,7 @@ void alloc_physical_registers(RegAlloc *ra, BBContainer *bbcon) {
if (vreg == NULL)
continue;

if (vreg->flag & VRF_CONST) {
li->state = LI_CONST;
continue;
}
assert(!(vreg->flag & VRF_CONST));

if (vreg->flag & VRF_SPILLED) {
li->state = LI_SPILL;
Expand Down
5 changes: 3 additions & 2 deletions src/cc/backend/regalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ typedef struct Vector Vector;
enum LiveIntervalState {
LI_NORMAL,
LI_SPILL,
LI_CONST,
};

typedef struct LiveInterval {
Expand All @@ -41,7 +40,8 @@ typedef struct RegAllocSettings {

typedef struct RegAlloc {
const RegAllocSettings *settings;
Vector *vregs; // <VReg*>
Vector *vregs; // <VReg*>, non-const vregs
Vector *consts; // <VReg*>, const vregs
LiveInterval *intervals; // size=vregs->len
LiveInterval **sorted_intervals;

Expand All @@ -52,4 +52,5 @@ typedef struct RegAlloc {

RegAlloc *new_reg_alloc(const RegAllocSettings *settings);
VReg *reg_alloc_spawn(RegAlloc *ra, enum VRegSize vsize, int vflag);
VReg *reg_alloc_spawn_const(RegAlloc *ra, int64_t value, enum VRegSize vsize, int vflag);
void alloc_physical_registers(RegAlloc *ra, BBContainer *bbcon);

0 comments on commit 054fda0

Please sign in to comment.