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