wrapped debugging modules with DEBUG_ONLY
[libfirm] / ir / ana / phiclass.c
1 /**
2  * @author Daniel Grund
3  * @date 09.08.2005
4  */
5 #ifdef HAVE_CONFIG_H
6 # include "config.h"
7 #endif
8
9 #ifdef HAVE_STDLIB_H
10 # include <stdlib.h>
11 #endif
12
13 #include "debug.h"
14 #include "irgwalk.h"
15 #include "irop_t.h"
16 #include "iredges_t.h"
17 #include "phiclass_t.h"
18
19 DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
20
21 size_t phi_irn_data_offset = 0;
22
23 static void phi_class_build(ir_node *irn, pset *pc) {
24         int i, max;
25         const ir_edge_t *edge;
26
27         /* If irn has a phi class assigned already
28          * return immediately to stop recursion */
29         if (_get_phi_class(irn)) {
30                 DBG((dbg, LEVEL_2, "  already done for %+F\n", irn));
31                 return;
32         }
33
34         /* The initial call to phi_class_build doesn't
35          * provide a pset, so alloc it */
36         if (!pc) {
37                 DBG((dbg, LEVEL_1, "Computing phi class for %+F\n", irn));
38                 assert(is_Phi(irn));
39                 pc = pset_new_ptr(4);
40         }
41
42         /* Add the irn to the phi class */
43         DBG((dbg, LEVEL_1, "  adding %+F\n", irn));
44         pset_insert_ptr(pc, irn);
45         _set_phi_class(irn, pc);
46
47         /* Check the 'neighbour' irns */
48         if (is_Phi(irn) && mode_is_datab(get_irn_mode(irn))) {
49                 /* Add all args of the phi to the phi-class. */
50                  for (i=0, max=get_irn_arity(irn); i<max; ++i) {
51                         DBG((dbg, LEVEL_2, "  checking arg %+F\n", get_irn_n(irn, i)));
52                         phi_class_build(get_irn_n(irn, i), pc);
53                  }
54         }
55
56         /* Add a user of the irn to the class,
57          * iff it is a phi node  */
58         foreach_out_edge(irn, edge) {
59                 ir_node *user = edge->src;
60                 DBG((dbg, LEVEL_2, "  checking user %+F\n", user));
61                 if (is_Phi(user) && mode_is_datab(get_irn_mode(user)))
62                         phi_class_build(user, pc);
63         }
64 }
65
66 static void phi_class_construction_walker(ir_node *node, void *env) {
67         if (is_Phi(node) && mode_is_datab(get_irn_mode(node)))
68                 phi_class_build(node, NULL);
69 }
70
71 static void phi_class_destruction_walker(ir_node *node, void *env) {
72         pset *clss = _get_phi_class(node);
73         if (clss) {
74                 ir_node *n;
75                 for(n = pset_first(clss); n; n = pset_next(clss))
76                         _set_phi_class(n, NULL);
77                 del_pset(clss);
78         }
79 }
80
81 void phi_class_compute(ir_graph *irg) {
82         irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL);
83         irg_walk_graph(irg, phi_class_construction_walker, NULL, NULL);
84 }
85
86 pset *phi_class_compute_by_phis(pset *all_phi_nodes) {
87         int i;
88         ir_node *phi;
89         pset *all_phi_classes = pset_new_ptr_default();
90
91         if (pset_count(all_phi_nodes)) {
92                 ir_graph *irg = get_irn_irg(pset_first(all_phi_nodes));
93                 pset_break(all_phi_nodes);
94                 irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL);
95
96                 for (i = 0, phi=pset_first(all_phi_nodes); phi; phi=pset_next(all_phi_nodes)) {
97                         assert(is_Phi(phi) && mode_is_datab(get_irn_mode(phi)));
98                         phi_class_build(phi, NULL);
99                         pset_insert_ptr(all_phi_classes, _get_phi_class(phi));
100                 }
101         }
102
103         return all_phi_classes;
104 }
105
106 void phi_class_free(ir_graph *irg) {
107         irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL);
108 }
109
110 pset *get_phi_class(const ir_node *irn) {
111         return get_irn_phi_info(irn)->phi_class;
112 }
113
114 void phi_class_init(void) {
115         FIRM_DBG_REGISTER(dbg, "ir.ana.phiclass");
116         phi_irn_data_offset = register_additional_node_data(sizeof(phi_info_t));
117 }