Calculate phi congruency groups; use them to solve the
importing-hreg-from-the-future problem (probably poorly).
This commit is contained in:
parent
ff58a6100f
commit
fac12aae32
|
@ -104,6 +104,7 @@ extern void tb_regvar(struct procedure* proc, arith offset, int size, int type,
|
||||||
extern void pass_convert_locals_to_ssa(struct procedure* proc);
|
extern void pass_convert_locals_to_ssa(struct procedure* proc);
|
||||||
extern void pass_convert_stack_ops(struct procedure* proc);
|
extern void pass_convert_stack_ops(struct procedure* proc);
|
||||||
extern void pass_eliminate_trivial_blocks(struct procedure* proc);
|
extern void pass_eliminate_trivial_blocks(struct procedure* proc);
|
||||||
|
extern void pass_find_phi_congruence_groups(void);
|
||||||
extern void pass_group_irs(struct procedure* proc);
|
extern void pass_group_irs(struct procedure* proc);
|
||||||
extern void pass_instruction_selector(void);
|
extern void pass_instruction_selector(void);
|
||||||
extern void pass_live_vreg_analysis(void);
|
extern void pass_live_vreg_analysis(void);
|
||||||
|
|
85
mach/proto/mcg/pass_phigroups.c
Normal file
85
mach/proto/mcg/pass_phigroups.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include "mcg.h"
|
||||||
|
|
||||||
|
static PMAPOF(struct vreg, struct vreg) phimap;
|
||||||
|
|
||||||
|
static void make_phimap(void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
phimap.count = 0;
|
||||||
|
for (i=0; i<cfg.preorder.count; i++)
|
||||||
|
{
|
||||||
|
struct basicblock* bb = cfg.preorder.item[i];
|
||||||
|
|
||||||
|
for (j=0; j<bb->phis.count; j++)
|
||||||
|
{
|
||||||
|
struct vreg* vreg = bb->phis.item[j].left;
|
||||||
|
struct phi* phi = bb->phis.item[j].right;
|
||||||
|
struct vreg* prevvreg = phi->ir->result;
|
||||||
|
|
||||||
|
pmap_add(&phimap, vreg, prevvreg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recursively_associate_group(struct phicongruence* c, struct vreg* vreg)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
vreg->congruence = c;
|
||||||
|
array_appendu(&c->vregs, vreg);
|
||||||
|
tracef('V', "V: %%%d is a member of congruence group %d\n",
|
||||||
|
vreg->id, c->id);
|
||||||
|
|
||||||
|
if (vreg->defined)
|
||||||
|
{
|
||||||
|
struct constraint* constraint = pmap_findleft(&vreg->defined->constraints, vreg);
|
||||||
|
if ((c->attrs == 0) || (constraint->attrs < c->attrs))
|
||||||
|
c->attrs = constraint->attrs;
|
||||||
|
|
||||||
|
array_appendu(&c->definitions, vreg->defined);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
struct vreg* child = pmap_findleft(&phimap, vreg);
|
||||||
|
if (!child)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pmap_remove(&phimap, vreg, child);
|
||||||
|
recursively_associate_group(c, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
struct vreg* child = pmap_findright(&phimap, vreg);
|
||||||
|
if (!child)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pmap_remove(&phimap, child, vreg);
|
||||||
|
recursively_associate_group(c, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void associate_groups(void)
|
||||||
|
{
|
||||||
|
static int number = 0;
|
||||||
|
|
||||||
|
while (phimap.count > 0)
|
||||||
|
{
|
||||||
|
struct phicongruence* c = calloc(1, sizeof(*c));
|
||||||
|
c->id = number++;
|
||||||
|
recursively_associate_group(c, phimap.item[0].left);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void pass_find_phi_congruence_groups(void)
|
||||||
|
{
|
||||||
|
make_phimap();
|
||||||
|
associate_groups();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vim: set sw=4 ts=4 expandtab : */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -164,10 +164,9 @@ void pass_register_allocator(void)
|
||||||
{
|
{
|
||||||
struct vreg* vreg = bb->phis.item[j].left;
|
struct vreg* vreg = bb->phis.item[j].left;
|
||||||
struct phi* phi = bb->phis.item[j].right;
|
struct phi* phi = bb->phis.item[j].right;
|
||||||
if (!pmap_findright(old, vreg) && (vreg->used.count > 0))
|
if (!pmap_findright(old, vreg))
|
||||||
{
|
{
|
||||||
struct hop* used = vreg->used.item[0];
|
struct phicongruence* c = vreg->congruence;
|
||||||
struct constraint* c = pmap_findleft(&used->constraints, vreg);
|
|
||||||
struct hreg* hreg = allocate_hreg(old, vreg, c->attrs);
|
struct hreg* hreg = allocate_hreg(old, vreg, c->attrs);
|
||||||
|
|
||||||
tracef('R', "R: import fallback hreg %s for phi input %%%d from %s\n",
|
tracef('R', "R: import fallback hreg %s for phi input %%%d from %s\n",
|
||||||
|
|
|
@ -168,6 +168,7 @@ void procedure_compile(struct procedure* proc)
|
||||||
|
|
||||||
pass_instruction_selector();
|
pass_instruction_selector();
|
||||||
print_hops('7', proc);
|
print_hops('7', proc);
|
||||||
|
pass_find_phi_congruence_groups();
|
||||||
pass_live_vreg_analysis();
|
pass_live_vreg_analysis();
|
||||||
print_hops('8', proc);
|
print_hops('8', proc);
|
||||||
pass_register_allocator();
|
pass_register_allocator();
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
|
|
||||||
#define WITH_ATTR(a) (1<<(a))
|
#define WITH_ATTR(a) (1<<(a))
|
||||||
|
|
||||||
|
struct phicongruence
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
ARRAYOF(struct vreg) vregs;
|
||||||
|
ARRAYOF(struct hop) definitions;
|
||||||
|
uint32_t attrs;
|
||||||
|
};
|
||||||
|
|
||||||
struct hreg
|
struct hreg
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
|
@ -14,6 +22,7 @@ struct hreg
|
||||||
struct vreg
|
struct vreg
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
struct phicongruence* congruence;
|
||||||
struct hop* defined;
|
struct hop* defined;
|
||||||
ARRAYOF(struct hop) used;
|
ARRAYOF(struct hop) used;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue