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);
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;
}
{
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));
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);
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);
for (i=0; i<cfg.preorder.count; 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++)
{
struct vreg* vreg = bb->phis.item[j].left;
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. */
-
- hreg = new_stacked_hreg(srctype);
+ /* No more registers --- allocate a stack slot. Ensure that we use the same stack
+ * slot for this vreg throughout the function. */
+
+ 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:
{
/* 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
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);
}
ARRAYOF(struct vreg) vregs;
ARRAYOF(struct hop) definitions;
uint32_t type;
+ struct hreg* evicted; /* stack slot to evict to */
};
struct hreg
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;