extern void pass_convert_locals_to_ssa(struct procedure* proc);
extern void pass_convert_stack_ops(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_instruction_selector(void);
extern void pass_live_vreg_analysis(void);
--- /dev/null
+#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 : */
+
+
+
{
struct vreg* vreg = bb->phis.item[j].left;
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 constraint* c = pmap_findleft(&used->constraints, vreg);
+ struct phicongruence* c = vreg->congruence;
struct hreg* hreg = allocate_hreg(old, vreg, c->attrs);
tracef('R', "R: import fallback hreg %s for phi input %%%d from %s\n",