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
6 changed files with 32 additions and 9 deletions
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue