87168f52948f513e2c36be5daa9e881e0bc26a98
[libfirm] / ir / be / bephicoal.c
1 /**
2  * @author Daniel Grund
3  * @date 04.01.2005
4  */
5
6 #include <stdlib.h>
7
8 #include "debug.h"
9 #include "bechordal.h"
10
11 #include "bera_t.h"
12 #include "bephicongr_t.h"
13 #include "bephicoal_t.h"
14
15
16 static firm_dbg_module_t *dbgmod = NULL;
17
18
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"));
23 }
24
25
26 static INLINE ir_node **pset_to_array(pset *theset) {
27         ir_node **res, *p;
28         int i, count;
29
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))
33                 res[i++] = p;
34         assert(i == count);
35
36         return res;
37 }
38
39
40 static INLINE pset *clone(pset *theset) {
41         void *p;
42         pset *res;
43
44         res = pset_new_ptr(8);
45         for (p = pset_first(theset); p; p = pset_next(theset))
46                 pset_insert_ptr(res, p);
47
48         return res;
49 }
50
51
52 static void coalesce_locals(pset *phi_class, dominfo_t *dominfo) {
53         int i, count, phi_count, arity, intf_det, phi_col, allfree;
54         pset *pc, *intffree;
55         ir_node *phi = NULL, *n, *m;
56 //      ir_node **members;
57
58         count = pset_count(phi_class);
59         pc = clone(phi_class);
60 //      members = pset_to_array(phi_class);
61
62         /* how many phi nodes are in this class? */
63         DBG((dbgmod, 1, "Checking phi count\n"));
64         phi_count = 0;
65         for (n = (ir_node *)pset_first(pc); n; n = (ir_node *)pset_next(pc)) {
66                 if (is_Phi(n)) {
67                         phi = n;
68                         phi_count++;
69                 }
70         }
71
72         if (phi_count > 1) {
73                 DBG((dbgmod, 1, "Dropped: Too many phis\n"));
74                 goto exit;
75         }
76         assert(phi_count == 1 && phi);
77
78
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);
85
86                 /* TODO: check next few lines after const node copy placement */
87 //              if (iro_Const == get_irn_opcode(arg) && CONSTS_SPLIT_PHI_CLASSES)
88 //                      continue;
89
90                 block_of_arg = get_nodes_block(arg);
91                 block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(phi), i));
92
93                 if (block_of_arg != block_ith_pred) {
94                         DBG((dbgmod, 1, "Dropped: Arg-def not in pred-block\n"));
95                         goto exit;
96                 }
97         }
98
99
100         /* determine a greedy set of non-interfering members
101          * crucial: starting with the phi node
102          */
103         DBG((dbgmod, 1, "Building greedy non-interfering set\n"));
104         intffree = pset_new_ptr(4);
105
106         pset_remove_ptr(pc, phi);
107         pset_insert_ptr(intffree, phi);
108
109         while (m = (ir_node *)pset_first(pc), m) {
110                 DBG((dbgmod, 1, "Checking %n\n", m));
111                 pset_break(pc);
112                 pset_remove_ptr(pc, m);
113
114                 intf_det = 0;
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"));
119                                 intf_det = 1;
120                         } else {
121                                 DBG((dbgmod, 1, "\tclean\n"));
122                         }
123                 }
124
125                 if (!intf_det) {
126                         DBG((dbgmod, 1, "Added to set\n"));
127                         pset_insert_ptr(intffree, m);
128                 }
129         }
130
131         /*
132          * color the non interfering set
133          */
134         DBG((dbgmod, 1, "Coloring...\n"));
135         phi_col = get_irn_color(phi);
136         DBG((dbgmod, 1, "phi-color: %d\n", grnfxt));
137
138         /* check if phi color is free in blocks of all members */
139         allfree = 1;
140         for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree)) {
141                 ir_node *block;
142                 if (n == phi)
143                         continue;
144
145                 block = get_nodes_block(n);
146 /* TODO
147                 if (! COLORFREE(block, phi_col)) {
148                         allfree = 0;
149                         break;
150                 }
151 */
152         }
153 /*
154         if (allfree) {
155                 for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree))
156                         set_irn_color(n, phi_col);
157         } else {
158
159         }
160 */
161
162 exit:
163         del_pset(pc);
164 //      free(members);
165 }
166
167
168 void be_phi_coalesce_locals(pset *all_phi_classes, dominfo_t *dominfo) {
169         pset *phi_class;
170
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);
173 }