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.
This commit is contained in:
David Given 2018-09-08 18:59:55 +02:00
parent b7a1c96986
commit d2c14ca44f
6 changed files with 32 additions and 9 deletions

View file

@ -127,7 +127,7 @@ struct hop* platform_epilogue(void)
return hop; 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); 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; 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 else
goto nomove; 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); 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(!src->is_stacked);
assert(!dest->is_stacked); assert(!dest->is_stacked);
assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS)); assert((src->attrs & TYPE_ATTRS) == (dest->attrs & TYPE_ATTRS));

View file

@ -128,7 +128,7 @@ struct hop* platform_epilogue(void)
return hop; 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); struct hop* hop = new_hop(bb, NULL);

View file

@ -123,7 +123,7 @@ extern void pass_wire_up_return_values(void);
extern void platform_calculate_offsets(void); extern void platform_calculate_offsets(void);
extern struct hop* platform_prologue(void); extern struct hop* platform_prologue(void);
extern struct hop* platform_epilogue(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 struct hop* platform_swap(struct basicblock* bb, struct hreg* src, struct hreg* dest);
extern const char* platform_label(const char* label); extern const char* platform_label(const char* label);

View file

@ -11,6 +11,7 @@ static void make_phimap(void)
{ {
struct basicblock* bb = cfg.preorder.item[i]; struct basicblock* bb = cfg.preorder.item[i];
/* Registers imported through a phi can come from multiple locations. */
for (j=0; j<bb->phis.count; j++) for (j=0; j<bb->phis.count; j++)
{ {
struct vreg* vreg = bb->phis.item[j].left; struct vreg* vreg = bb->phis.item[j].left;

View file

@ -386,16 +386,28 @@ static void find_new_home_for_evicted_register(struct vreg* vreg, struct hreg* s
for (i=0; i<hregs.count; i++) for (i=0; i<hregs.count; i++)
{ {
hreg = hregs.item[i]; hreg = hregs.item[i];
if ((hreg->attrs & srctype) && if (!hreg->is_stacked && (hreg->attrs & srctype) &&
allocatable_through(hreg, vreg)) allocatable_through(hreg, vreg))
{ {
goto found; 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); array_append(&hregs, hreg);
found: found:
@ -617,7 +629,8 @@ static int insert_moves(struct basicblock* bb, int index,
{ {
/* Copy. */ /* 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); pmap_remove(&copies, src, dest);
} }
else else
@ -710,13 +723,17 @@ static void insert_phi_copies(void)
for (k=0; k<bb->regsin.count; k++) for (k=0; k<bb->regsin.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 vreg* vreg = bb->regsin.item[k].right;
struct hreg* src = pmap_findright(prevbb->regsout, vreg); struct hreg* src = pmap_findright(prevbb->regsout, vreg);
if (!pmap_findleft(&bb->phis, vreg)) if (!pmap_findleft(&bb->phis, vreg))
{ {
tracef('R', "R: input map %%%d (%s) -> (%s)\n", tracef('R', "R: input map %%%d (%s) -> (%s)\n",
vreg->id, src->id, hreg->id); 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); pmap_add(&destregs, hreg, vreg);
} }

View file

@ -9,6 +9,7 @@ struct phicongruence
ARRAYOF(struct vreg) vregs; ARRAYOF(struct vreg) vregs;
ARRAYOF(struct hop) definitions; ARRAYOF(struct hop) definitions;
uint32_t type; uint32_t type;
struct hreg* evicted; /* stack slot to evict to */
}; };
struct hreg struct hreg
@ -28,6 +29,7 @@ struct vreg
struct phicongruence* congruence; struct phicongruence* congruence;
struct hop* defined; struct hop* defined;
ARRAYOF(struct hop) used; ARRAYOF(struct hop) used;
struct hreg* evicted; /* stack slot to evict to */
}; };
typedef PMAPOF(struct hreg, struct vreg) register_assignment_t; typedef PMAPOF(struct hreg, struct vreg) register_assignment_t;