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:
parent
b7a1c96986
commit
d2c14ca44f
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ static void make_phimap(void)
|
|||
{
|
||||
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++)
|
||||
{
|
||||
struct vreg* vreg = bb->phis.item[j].left;
|
||||
|
|
|
@ -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++)
|
||||
{
|
||||
hreg = hregs.item[i];
|
||||
if ((hreg->attrs & 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; 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 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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue