11 #include "iredges_t.h"
12 #include "phiclass_t.h"
14 #define DEBUG_LVL SET_LEVEL_0
15 static firm_dbg_module_t *dbg = NULL;
17 size_t phi_irn_data_offset = 0;
19 static void phi_class_build(ir_node *irn, pset *pc) {
22 /* If irn has a phi class assigned already
23 * return immediately to stop recursion */
24 if (_get_phi_class(irn)) {
25 DBG((dbg, LEVEL_2, " already done for %+F\n", irn));
29 /* The initial call to phi_class_build doesn't
30 * provide a pset, so alloc it */
32 DBG((dbg, LEVEL_1, "Computing phi class for %+F\n", irn));
37 /* Add the irn to the phi class */
38 DBG((dbg, LEVEL_1, " adding %+F\n", irn));
39 pset_insert_ptr(pc, irn);
40 _set_phi_class(irn, pc);
42 /* Check the 'neighbour' irns */
43 if (is_Phi(irn) && mode_is_datab(get_irn_mode(irn))) {
44 /* Add all args of the phi to the phi-class. */
45 for (i=0, max=get_irn_arity(irn); i<max; ++i) {
46 DBG((dbg, LEVEL_2, " checking arg %+F\n", get_irn_n(irn, i)));
47 phi_class_build(get_irn_n(irn, i), pc);
51 /* Add a user of the irn to the class,
52 * iff it is a phi node */
53 const ir_edge_t *edge;
54 foreach_out_edge(irn, edge) {
55 ir_node *user = edge->src;
56 DBG((dbg, LEVEL_2, " checking user %+F\n", user));
57 if (is_Phi(user) && mode_is_datab(get_irn_mode(user)))
58 phi_class_build(user, pc);
62 pset *phi_class_compute_by_phis(pset *all_phi_nodes) {
65 pset *all_phi_classes = pset_new_ptr_default();
67 for (i = 0, phi=pset_first(all_phi_nodes); phi; phi=pset_next(all_phi_nodes)) {
68 assert(is_Phi(phi) && mode_is_datab(get_irn_mode(phi)));
69 phi_class_build(phi, NULL);
70 pset_insert_ptr(all_phi_classes, _get_phi_class(phi));
73 return all_phi_classes;
76 static void phi_class_construction_walker(ir_node *node, void *env) {
77 if (is_Phi(node) && mode_is_datab(get_irn_mode(node)))
78 phi_class_build(node, NULL);
81 static void phi_class_destruction_walker(ir_node *node, void *env) {
82 pset *clss = _get_phi_class(node);
85 _set_phi_class(node, NULL);
89 void phi_class_compute(ir_graph *irg) {
90 irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL);
91 irg_walk_graph(irg, phi_class_construction_walker, NULL, NULL);
94 void phi_class_free(ir_graph *irg) {
95 irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL);
98 pset *get_phi_class(const ir_node *irn) {
99 return get_irn_phi_info(irn)->phi_class;
102 void phi_class_init(void) {
103 dbg = firm_dbg_register("ir.ana.phiclass");
104 firm_dbg_set_mask(dbg, DEBUG_LVL);
105 phi_irn_data_offset = register_additional_node_data(sizeof(phi_info_t));