12 #include "bephicongr_t.h"
13 #include "bephicoal_t.h"
16 static firm_dbg_module_t *dbgmod = NULL;
19 void be_phi_coal_init(void) {
20 dbgmod = firm_dbg_register("Phi coalescing");
21 firm_dbg_set_mask(dbgmod, 1);
22 DBG((dbgmod, 1, "Phi coalescing dbg enabled"));
26 static INLINE ir_node **pset_to_array(pset *theset) {
30 count = pset_count(theset);
31 res = (ir_node **) malloc(count * sizeof(ir_node*));
32 for (i = 0, p = (ir_node *)pset_first(theset); p; p = (ir_node *)pset_next(theset))
40 static INLINE pset *clone(pset *theset) {
44 res = pset_new_ptr(8);
45 for (p = pset_first(theset); p; p = pset_next(theset))
46 pset_insert_ptr(res, p);
52 static void coalesce_locals(pset *phi_class, dominfo_t *dominfo) {
53 int i, count, phi_count, arity, intf_det, phi_col, allfree;
55 ir_node *phi = NULL, *n, *m;
58 count = pset_count(phi_class);
59 pc = clone(phi_class);
60 // members = pset_to_array(phi_class);
62 /* how many phi nodes are in this class? */
63 DBG((dbgmod, 1, "Checking phi count\n"));
65 for (n = (ir_node *)pset_first(pc); n; n = (ir_node *)pset_next(pc)) {
73 DBG((dbgmod, 1, "Dropped: Too many phis\n"));
76 assert(phi_count == 1 && phi);
79 /* where is the definition of the arguments? */
80 DBG((dbgmod, 1, "Checking arg def\n"));
81 arity = get_irn_arity(phi);
82 for (i = 0; i < arity; ++i) {
83 ir_node *block_of_arg, *block_ith_pred;
84 ir_node *arg = get_irn_n(phi, i);
86 /* TODO: check next few lines after const node copy placement */
87 // if (iro_Const == get_irn_opcode(arg) && CONSTS_SPLIT_PHI_CLASSES)
90 block_of_arg = get_nodes_block(arg);
91 block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(phi), i));
93 if (block_of_arg != block_ith_pred) {
94 DBG((dbgmod, 1, "Dropped: Arg-def not in pred-block\n"));
100 /* determine a greedy set of non-interfering members
101 * crucial: starting with the phi node
103 DBG((dbgmod, 1, "Building greedy non-interfering set\n"));
104 intffree = pset_new_ptr(4);
106 pset_remove_ptr(pc, phi);
107 pset_insert_ptr(intffree, phi);
109 while (m = (ir_node *)pset_first(pc), m) {
110 DBG((dbgmod, 1, "Checking %n\n", m));
112 pset_remove_ptr(pc, m);
115 for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree)) {
116 DBG((dbgmod, 1, "\t%n", n));
117 if (phi_ops_interfere(m, n)) {
118 DBG((dbgmod, 1, "\tinterf\n"));
121 DBG((dbgmod, 1, "\tclean\n"));
126 DBG((dbgmod, 1, "Added to set\n"));
127 pset_insert_ptr(intffree, m);
132 * color the non interfering set
134 DBG((dbgmod, 1, "Coloring...\n"));
135 phi_col = get_irn_color(phi);
136 DBG((dbgmod, 1, "phi-color: %d\n", grnfxt));
138 /* check if phi color is free in blocks of all members */
140 for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree)) {
145 block = get_nodes_block(n);
147 if (! COLORFREE(block, phi_col)) {
155 for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree))
156 set_irn_color(n, phi_col);
168 void be_phi_coalesce_locals(pset *all_phi_classes, dominfo_t *dominfo) {
171 for (phi_class = (pset *)pset_first(all_phi_classes); phi_class; phi_class = (pset *)pset_next(all_phi_classes))
172 coalesce_locals(phi_class, dominfo);