A bb's regsin are no longer the same as those of its first instruction;
occasionally the first hop of a block would try to rearrange its registers (due to evicted throughs), resulting in the phi moves copying values into the wrong registers.
This commit is contained in:
parent
edfee33576
commit
81bc2c74c5
|
@ -24,11 +24,9 @@ struct basicblock
|
|||
ARRAYOF(struct vreg) liveins;
|
||||
ARRAYOF(struct vreg) liveouts;
|
||||
|
||||
/* Register assignments on entry and exit. These are *pointers* (because
|
||||
* they just point to the regsin/regsout of the first and last hop
|
||||
* respectively). */
|
||||
register_assignment_t* regsin;
|
||||
register_assignment_t* regsout;
|
||||
/* Register assignments on entry and exit. */
|
||||
register_assignment_t regsin;
|
||||
register_assignment_t* regsout; /* points at regsout of the last insn. */
|
||||
|
||||
bool is_fake : 1;
|
||||
bool is_root : 1;
|
||||
|
|
|
@ -54,7 +54,6 @@ static void wire_up_blocks_ins_outs(void)
|
|||
{
|
||||
struct basicblock* bb = dominance.preorder.item[i];
|
||||
assert(bb->hops.count >= 1);
|
||||
bb->regsin = &bb->hops.item[0]->regsin;
|
||||
bb->regsout = &bb->hops.item[bb->hops.count-1]->regsout;
|
||||
}
|
||||
}
|
||||
|
@ -462,7 +461,7 @@ static void assign_hregs_to_vregs(void)
|
|||
for (i=0; i<dominance.preorder.count; i++)
|
||||
{
|
||||
struct basicblock* bb = dominance.preorder.item[i];
|
||||
register_assignment_t* old = bb->regsin;
|
||||
register_assignment_t* old = &bb->regsin;
|
||||
|
||||
tracef('R', "R: considering block %s\n", bb->name);
|
||||
|
||||
|
@ -568,8 +567,7 @@ static void assign_hregs_to_vregs(void)
|
|||
}
|
||||
tracef('R', "]\n");
|
||||
|
||||
if (j > 0)
|
||||
j += insert_moves(bb, j, old, in);
|
||||
j += insert_moves(bb, j, old, in);
|
||||
|
||||
old = out;
|
||||
}
|
||||
|
@ -692,15 +690,16 @@ static void insert_phi_copies(void)
|
|||
{
|
||||
struct vreg* vreg = bb->phis.item[k].left;
|
||||
struct phi* phi = bb->phis.item[k].right;
|
||||
struct hreg* dest = pmap_findright(bb->regsin, vreg);
|
||||
struct hreg* src = pmap_findright(prevbb->regsout, phi->ir->result);
|
||||
struct hreg* dest = pmap_findright(&bb->regsin, vreg);
|
||||
|
||||
if ((phi->prev == prevbb) && dest)
|
||||
{
|
||||
/* We inserted critical edges to guarantee this. */
|
||||
assert(prevbb->nexts.count == 1);
|
||||
|
||||
tracef('R', "R: map %%%d -> %%%d (%s)\n",
|
||||
phi->ir->result->id,
|
||||
tracef('R', "R: phi map %%%d (%s) -> %%%d (%s)\n",
|
||||
phi->ir->result->id, src->id,
|
||||
vreg->id, dest->id);
|
||||
|
||||
pmap_put(&destregs, dest, phi->ir->result);
|
||||
|
@ -709,12 +708,18 @@ static void insert_phi_copies(void)
|
|||
|
||||
/* Add any non-phi inputs. */
|
||||
|
||||
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 vreg* vreg = bb->regsin->item[k].right;
|
||||
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);
|
||||
|
||||
pmap_add(&destregs, hreg, vreg);
|
||||
}
|
||||
}
|
||||
|
||||
/* The last instruction of a block should be the jump that sends us
|
||||
|
|
Loading…
Reference in a new issue