Added basics of phi optimize phase.
[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 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_register("Testsdflkjsdf");
22         firm_dbg_set_mask(dbgmod, 1);
23         DBG((dbgmod, 1, "Phi coalescing dbg enabled"));
24 }
25
26
27 static INLINE ir_node **pset_to_array(pset *theset) {
28         ir_node **res, *p;
29         int i, count;
30
31         count = pset_count(theset);
32         res = (ir_node **) malloc(count * sizeof(ir_node*));
33         for (i = 0, p = (ir_node *)pset_first(theset); p; p = (ir_node *)pset_next(theset))
34                 res[i++] = p;
35         assert(i == count);
36
37         return res;
38 }
39
40
41 static INLINE pset *clone(pset *theset) {
42         void *p;
43         pset *res;
44
45         res = pset_new_ptr(8);
46         for (p = pset_first(theset); p; p = pset_next(theset))
47                 pset_insert_ptr(res, p);
48
49         return res;
50 }
51
52
53 static void coalesce_locals(pset *phi_class) {
54         int i, count, phi_count, arity, intf_det, phi_col;
55         pset *pc, *intffree;
56         ir_node *phi, *n, *m;
57 //      ir_node **members;
58
59         count = pset_count(phi_class);
60         pc = clone(phi_class);
61 //      members = pset_to_array(phi_class);
62
63         /* how many phi nodes are in this class? */
64         DBG((dbgmod, 1, "Checking phi count\n"));
65         phi_count = 0;
66         for (n = (ir_node *)pset_first(pc); n; n = (ir_node *)pset_next(pc)) {
67                 if (is_Phi(n)) {
68                         phi = n;
69                         phi_count++;
70                 }
71         }
72
73         if (phi_count > 1) {
74                 DBG((dbgmod, 1, "Dropped: Too many phis\n"));
75                 goto exit;
76         }
77         assert(phi_count == 1 && phi);
78
79
80         /* where is the definition of the arguments? */
81         DBG((dbgmod, 1, "Checking arg def\n"));
82         arity = get_irn_arity(phi);
83         for (i = 0; i < arity; ++i) {
84         ir_node *block_of_arg, *block_ith_pred;
85                 ir_node *arg = get_irn_n(phi, i);
86
87                 /* TODO: check next few lines after const node copy placement */
88 //              if (iro_Const == get_irn_opcode(arg) && CONSTS_SPLIT_PHI_CLASSES)
89 //                      continue;
90
91                 block_of_arg = get_nodes_block(arg);
92                 block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(phi), i));
93
94                 if (block_of_arg != block_ith_pred) {
95                         DBG((dbgmod, 1, "Dropped: Arg-def not in pred-block\n"));
96                         goto exit;
97                 }
98         }
99
100
101         /* determine a greedy set of non-interfering members
102          * crucial: starting with the phi node
103          */
104         DBG((dbgmod, 1, "Building greedy non-intfering set\n"));
105         intffree = pset_new_ptr(4);
106
107         pset_remove_ptr(pc, phi);
108         pset_insert_ptr(intffree, phi);
109
110         while (m = (ir_node *)pset_first(pc), m) {
111                 DBG((dbgmod, 1, "Checking %n\n", m));
112                 pset_break(pc);
113                 pset_remove_ptr(pc, m);
114
115                 intf_det = 0;
116                 for (n = (ir_node *)pset_first(intffree); n; n = (ir_node *)pset_next(intffree)) {
117                         DBG((dbgmod, 1, "\t%n", n));
118                         if (phi_ops_interfere(m, n)) {
119                                 DBG((dbgmod, 1, "\tinterf\n"));
120                                 intf_det = 1;
121                         } else {
122                                 DBG((dbgmod, 1, "\tclean\n"));
123                         }
124                 }
125
126                 if (!intf_det) {
127                         DBG((dbgmod, 1, "Added to set\n"));
128                         pset_insert_ptr(intffree, m);
129                 }
130         }
131
132         /*
133          * color the intffree set
134          */
135         DBG((dbgmod, 1, "Coloring...\n"));
136         phi_col = get_irn_color(phi);
137         DBG((dbgmod, 1, "phi-color: %d\n", tgt_col));
138
139
140
141 exit:
142         del_pset(pc);
143 //      free(members);
144 }
145
146
147 void be_phi_coalesce_locals(pset *all_phi_classes) {
148         pset *phi_class;
149
150         DBG((dbgmod, 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"));
151
152         /* determine all phi classes */
153         for (phi_class = (pset *)pset_first(all_phi_classes); phi_class; phi_class = (pset *)pset_next(all_phi_classes))
154                 coalesce_locals(phi_class);
155 }