From d2c14ca44fedab72dd41d430754a96a8522fd063 Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 8 Sep 2018 18:59:55 +0200 Subject: [PATCH] Precisely one stack hreg gets allocated for each vreg/congruence group for eviction; this prevents us from having to worry about moving values from stack slot to stack slot, which is hard. --- mach/mips/mcg/platform.c | 5 ++++- mach/powerpc/mcg/platform.c | 2 +- mach/proto/mcg/mcg.h | 2 +- mach/proto/mcg/pass_phigroups.c | 3 ++- mach/proto/mcg/pass_registerallocator.c | 27 ++++++++++++++++++++----- mach/proto/mcg/reg.h | 2 ++ 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/mach/mips/mcg/platform.c b/mach/mips/mcg/platform.c index ab0032664..0b7ee65bb 100644 --- a/mach/mips/mcg/platform.c +++ b/mach/mips/mcg/platform.c @@ -127,7 +127,7 @@ struct hop* platform_epilogue(void) return hop; } -struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest) +struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest) { struct hop* hop = new_hop(bb, NULL); @@ -280,6 +280,8 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* goto nomove; } } + else if (src->is_stacked && dest->is_stacked) + fatal("tried to move stacked object %%%d of type 0x%x from %s to %s", vreg->id, type, src->id, dest->id); else goto nomove; } @@ -294,6 +296,7 @@ struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* { struct hop* hop = new_hop(bb, NULL); + tracef('R', "R: swap of %s to %s\n", src->id, dest->id); assert(!src->is_stacked); assert(!dest->is_stacked); assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS)); diff --git a/mach/powerpc/mcg/platform.c b/mach/powerpc/mcg/platform.c index 65b158cac..706797250 100644 --- a/mach/powerpc/mcg/platform.c +++ b/mach/powerpc/mcg/platform.c @@ -128,7 +128,7 @@ struct hop* platform_epilogue(void) return hop; } -struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest) +struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest) { struct hop* hop = new_hop(bb, NULL); diff --git a/mach/proto/mcg/mcg.h b/mach/proto/mcg/mcg.h index 540f5799c..b813b7973 100644 --- a/mach/proto/mcg/mcg.h +++ b/mach/proto/mcg/mcg.h @@ -123,7 +123,7 @@ extern void pass_wire_up_return_values(void); extern void platform_calculate_offsets(void); extern struct hop* platform_prologue(void); extern struct hop* platform_epilogue(void); -extern struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg* dest); +extern struct hop* platform_move(struct basicblock* bb, struct vreg* vreg, struct hreg* src, struct hreg* dest); extern struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest); extern const char* platform_label(const char* label); diff --git a/mach/proto/mcg/pass_phigroups.c b/mach/proto/mcg/pass_phigroups.c index e57378ad4..abb892445 100644 --- a/mach/proto/mcg/pass_phigroups.c +++ b/mach/proto/mcg/pass_phigroups.c @@ -10,7 +10,8 @@ static void make_phimap(void) for (i=0; iphis.count; j++) { struct vreg* vreg = bb->phis.item[j].left; diff --git a/mach/proto/mcg/pass_registerallocator.c b/mach/proto/mcg/pass_registerallocator.c index a5436bc73..0a25fc4f0 100644 --- a/mach/proto/mcg/pass_registerallocator.c +++ b/mach/proto/mcg/pass_registerallocator.c @@ -386,16 +386,28 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s for (i=0; iattrs & srctype) && + if (!hreg->is_stacked && (hreg->attrs & srctype) && allocatable_through(hreg, vreg)) { goto found; } } - /* No more registers --- allocate a stack slot. */ + /* No more registers --- allocate a stack slot. Ensure that we use the same stack + * slot for this vreg throughout the function. */ - hreg = new_stacked_hreg(srctype); + hreg = vreg->evicted; + if (!hreg) + { + if (vreg->congruence) + hreg = vreg->evicted = vreg->congruence->evicted; + if (!hreg) + { + hreg = vreg->evicted = new_stacked_hreg(srctype); + if (vreg->congruence) + vreg->congruence->evicted = hreg; + } + } array_append(&hregs, hreg); found: @@ -617,7 +629,8 @@ static int insert_moves(struct basicblock* bb, int index, { /* Copy. */ - hop = platform_move(bb, src, dest); + struct vreg* vreg = pmap_findleft(srcregs, src); + hop = platform_move(bb, vreg, src, dest); pmap_remove(&copies, src, dest); } else @@ -710,13 +723,17 @@ static void insert_phi_copies(void) for (k=0; kregsin.count; k++) { - struct hreg*hreg = bb->regsin.item[k].left; + struct hreg* hreg = bb->regsin.item[k].left; struct vreg* vreg = bb->regsin.item[k].right; struct hreg* src = pmap_findright(prevbb->regsout, vreg); if (!pmap_findleft(&bb->phis, vreg)) { tracef('R', "R: input map %%%d (%s) -> (%s)\n", vreg->id, src->id, hreg->id); + if ((src->id != hreg->id) && src->is_stacked && hreg->is_stacked) + fatal("vreg %%%d is stacked in %s on entry to %s, but is passed in in %s from %s", + vreg->id, hreg->id, bb->name, + src->id, prevbb->name); pmap_add(&destregs, hreg, vreg); } diff --git a/mach/proto/mcg/reg.h b/mach/proto/mcg/reg.h index 00c8220b5..b3f231494 100644 --- a/mach/proto/mcg/reg.h +++ b/mach/proto/mcg/reg.h @@ -9,6 +9,7 @@ struct phicongruence ARRAYOF(struct vreg) vregs; ARRAYOF(struct hop) definitions; uint32_t type; + struct hreg* evicted; /* stack slot to evict to */ }; struct hreg @@ -28,6 +29,7 @@ struct vreg struct phicongruence* congruence; struct hop* defined; ARRAYOF(struct hop) used; + struct hreg* evicted; /* stack slot to evict to */ }; typedef PMAPOF(struct hreg, struct vreg) register_assignment_t;