From: Christian Würdig Date: Fri, 9 Feb 2007 10:26:26 +0000 (+0000) Subject: made phiclass an ir_phase object X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=839873eddcfdfabdfa0fc384d94f30603f37b4a8;p=libfirm made phiclass an ir_phase object removed redundant file [r8615] --- diff --git a/ir/ana/phiclass.c b/ir/ana/phiclass.c index af8284e29..0daa2287a 100644 --- a/ir/ana/phiclass.c +++ b/ir/ana/phiclass.c @@ -1,6 +1,7 @@ /** - * @author Daniel Grund - * @date 09.08.2005 + * @author Daniel Grund, Christian Wuerdig + * @cvsid $Id$ + * @date 09.08.2005 */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -10,108 +11,198 @@ # include #endif +#include "irnode.h" #include "debug.h" #include "irgwalk.h" #include "irop_t.h" #include "iredges_t.h" #include "phiclass_t.h" +#include "irphase_t.h" + +struct _phi_classes_t { + phase_t ph; /* The phase object holding the irn data */ + pset *all_phi_classes; /* A set containing all Phi classes */ + ir_graph *irg; /* The irg this is all about */ + DEBUG_ONLY(firm_dbg_module_t *dbg); +}; + +typedef struct _irn_phi_class_t { + ir_node **phi_cls; /* the array of node pointers representing the class */ +} irn_phi_class_t; + +static INLINE ir_node **_get_phi_class(phase_t *ph, const ir_node *irn) { + irn_phi_class_t *ipc = phase_get_irn_data(ph, irn); + return ipc->phi_cls; +} -DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;) +static INLINE void _set_phi_class(phase_t *ph, ir_node *irn, ir_node **cls) { + irn_phi_class_t *ipc = phase_get_irn_data(ph, irn); + ipc->phi_cls = cls; +} -size_t phi_irn_data_offset = 0; +/* initialize data structure for given irn in given phase */ +static void *irn_phi_class_init(phase_t *ph, ir_node *irn, void *data) { + irn_phi_class_t *ipc = data ? data : phase_alloc(ph, sizeof(ipc[0])); + memset(ipc, 0, sizeof(ipc[0])); + return ipc; +} -static void phi_class_build(ir_node *irn, pset *pc) { - int i, max; +/** + * Builds the phi class, starting from. + * @param phi_classes The phi class object + * @param irn The to start from + * @param pc The phi class this irn should be put into. + * Set to NULL if you want a new one. + */ +static void phi_class_build(phi_classes_t *phi_classes, ir_node *irn, ir_node **pc) { const ir_edge_t *edge; /* If irn has a phi class assigned already * return immediately to stop recursion */ - if (_get_phi_class(irn)) { - DBG((dbg, LEVEL_2, " already done for %+F\n", irn)); + if (_get_phi_class(&phi_classes->ph, irn)) { + DBG((phi_classes->dbg, LEVEL_2, " already done for %+F\n", irn)); return; } /* The initial call to phi_class_build doesn't - * provide a pset, so alloc it */ - if (!pc) { - DBG((dbg, LEVEL_1, "Computing phi class for %+F\n", irn)); + * provide a nodeset, so alloc it */ + if (! pc) { + DBG((phi_classes->dbg, LEVEL_1, "Computing phi class for %+F\n", irn)); assert(is_Phi(irn)); - pc = pset_new_ptr(4); + pc = NEW_ARR_F(ir_node *, 0); } /* Add the irn to the phi class */ - DBG((dbg, LEVEL_1, " adding %+F\n", irn)); - pset_insert_ptr(pc, irn); - _set_phi_class(irn, pc); + DBG((phi_classes->dbg, LEVEL_1, " adding %+F\n", irn)); + ARR_APP1(ir_node *, pc, irn); + _set_phi_class(&phi_classes->ph, irn, pc); /* Check the 'neighbour' irns */ if (is_Phi(irn) && mode_is_datab(get_irn_mode(irn))) { + int i; + /* Add all args of the phi to the phi-class. */ - for (i=0, max=get_irn_arity(irn); i= 0; --i) { + ir_node *op = get_irn_n(irn, i); + DBG((phi_classes->dbg, LEVEL_2, " checking arg %+F\n", op)); + phi_class_build(phi_classes, op, pc); + } } /* Add a user of the irn to the class, * iff it is a phi node */ foreach_out_edge(irn, edge) { ir_node *user = edge->src; - DBG((dbg, LEVEL_2, " checking user %+F\n", user)); + DBG((phi_classes->dbg, LEVEL_2, " checking user %+F\n", user)); if (is_Phi(user) && mode_is_datab(get_irn_mode(user))) - phi_class_build(user, pc); + phi_class_build(phi_classes, user, pc); } } +/** + * Call by a walker. If @p node is Phi, it build the Phi class starting from this node. + */ static void phi_class_construction_walker(ir_node *node, void *env) { - if (is_Phi(node) && mode_is_datab(get_irn_mode(node))) - phi_class_build(node, NULL); -} - -static void phi_class_destruction_walker(ir_node *node, void *env) { - pset *clss = _get_phi_class(node); - if (clss) { - ir_node *n; - for(n = pset_first(clss); n; n = pset_next(clss)) - _set_phi_class(n, NULL); - del_pset(clss); + phi_classes_t *pc = env; + if (is_Phi(node) && mode_is_datab(get_irn_mode(node))) { + phi_class_build(pc, node, NULL); + pset_insert_ptr(pc->all_phi_classes, _get_phi_class(&pc->ph, node)); } } -void phi_class_compute(ir_graph *irg) { - irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL); - irg_walk_graph(irg, phi_class_construction_walker, NULL, NULL); +/** + * Walk over the irg and build the Phi classes. + */ +static void phi_class_compute(phi_classes_t *pc) { + irg_walk_graph(pc->irg, phi_class_construction_walker, NULL, pc); } -pset *phi_class_compute_by_phis(pset *all_phi_nodes) { - int i; - ir_node *phi; - pset *all_phi_classes = pset_new_ptr_default(); - +/** + * Build the Phi classes for the set of given Phis. + */ +static void phi_class_compute_by_phis(phi_classes_t *pc, pset *all_phi_nodes) { if (pset_count(all_phi_nodes)) { - ir_graph *irg = get_irn_irg(pset_first(all_phi_nodes)); - pset_break(all_phi_nodes); - irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL); + ir_node *phi; + + foreach_pset(all_phi_nodes, phi) { + ir_node **irn_pc = _get_phi_class(&pc->ph, phi); - for (i = 0, phi=pset_first(all_phi_nodes); phi; phi=pset_next(all_phi_nodes)) { assert(is_Phi(phi) && mode_is_datab(get_irn_mode(phi))); - phi_class_build(phi, NULL); - pset_insert_ptr(all_phi_classes, _get_phi_class(phi)); + + if (! irn_pc) { + phi_class_build(pc, phi, NULL); + pset_insert_ptr(pc->all_phi_classes, _get_phi_class(&pc->ph, phi)); + } } } +} + +/** + * Return the array containing all nodes assigned to the same Phi class as @p irn. + */ +ir_node **get_phi_class(phi_classes_t *pc, const ir_node *irn) { + return _get_phi_class(&pc->ph, irn); +} - return all_phi_classes; +/** + * Assigns a new array of nodes representing the new Phi class to @p irn. + */ +void set_phi_class(phi_classes_t *pc, ir_node *irn, ir_node **cls) { + _set_phi_class(&pc->ph, irn, cls); } -void phi_class_free(ir_graph *irg) { - irg_walk_graph(irg, phi_class_destruction_walker, NULL, NULL); +/** + * Returns a set containing all computed Phi classes. + */ +pset *get_all_phi_classes(phi_classes_t *pc) { + return pc->all_phi_classes; +} + +/** + * Builds the Phi classes for all Phis in @p irg. + * @return The Phi class object for the @p irg. + */ +phi_classes_t *phi_class_new_from_irg(ir_graph *irg) { + phi_classes_t *res = xmalloc(sizeof(*res)); + + FIRM_DBG_REGISTER(res->dbg, "ir.ana.phiclass"); + phase_init(&res->ph, "phi_classes", irg, PHASE_DEFAULT_GROWTH, irn_phi_class_init); + + res->irg = irg; + res->all_phi_classes = pset_new_ptr(5); + + phi_class_compute(res); + + return res; } -pset *get_phi_class(const ir_node *irn) { - return get_irn_phi_info(irn)->phi_class; +/** + * Builds all Phi classes for the given set of Phis. + * @return The Phis class object for @p all_phis. + */ +phi_classes_t *phi_class_new_from_set(ir_graph *irg, pset *all_phis) { + phi_classes_t *res = xmalloc(sizeof(*res)); + + FIRM_DBG_REGISTER(res->dbg, "ir.ana.phiclass"); + phase_init(&res->ph, "phi_classes", irg, PHASE_DEFAULT_GROWTH, irn_phi_class_init); + + res->irg = irg; + res->all_phi_classes = pset_new_ptr(5); + + phi_class_compute_by_phis(res, all_phis); + + return res; } -void phi_class_init(void) { - FIRM_DBG_REGISTER(dbg, "ir.ana.phiclass"); - phi_irn_data_offset = register_additional_node_data(sizeof(phi_info_t)); +/** + * Free all allocated data. + */ +void phi_class_free(phi_classes_t *pc) { + ir_node **ipc; + foreach_pset(pc->all_phi_classes, ipc) { + DEL_ARR_F(ipc); + } + del_pset(pc->all_phi_classes); + phase_free(&pc->ph); + xfree(pc); } diff --git a/ir/ana/phiclass.h b/ir/ana/phiclass.h index 44a5a2640..d32b8e29e 100644 --- a/ir/ana/phiclass.h +++ b/ir/ana/phiclass.h @@ -1,48 +1,49 @@ /** * Analysis to compute phi congruence classes. * @author Daniel Grund - * @date 15.01.2005 + * @cvsid $Id$ + * @date 15.01.2005 */ -#ifndef _BEPHICONGR_H -#define _BEPHICONGR_H +#ifndef _PHICLASS_H_ +#define _PHICLASS_H_ #include "pset.h" #include "irgraph.h" #include "irnode.h" +typedef struct _phi_classes_t phi_classes_t; + +/** + * Return the array containing all nodes assigned to the same Phi class as @p irn. + */ +ir_node **get_phi_class(phi_classes_t *pc, const ir_node *irn); + /** - * Initialize data structures + * Assigns a new array of nodes representing the new Phi class to @p irn. */ -void phi_class_init(void); +void set_phi_class(phi_classes_t *pc, ir_node *irn, ir_node **cls); /** - * Computes all phi classes of an irg. - * @param irg The ir-graph to compute the classes for. - * @return Sets the internal data structures. + * Returns a set containing all computed Phi classes. */ -void phi_class_compute(ir_graph *irg); +pset *get_all_phi_classes(phi_classes_t *pc); /** - * Computes all phi classes of an irg. All phi nodes of this irg must be - * contained in @p all_phi_nodes. Otherwise the results may be wrong. - * @param all_phi_nodes All phi nodes of an irg. - * @return A set containing all phi classes as psets + * Builds the Phi classes for all Phis in @p irg. + * @return The Phi class object for the @p irg. */ -pset *phi_class_compute_by_phis(pset *all_phi_nodes); +phi_classes_t *phi_class_new_from_irg(ir_graph *irg); /** - * Throws away all allocated memory for phi classes of an irg. - * @param irg The ir-graph to free recources for. - * @return Frees the internal data structures. + * Builds all Phi classes for the given set of Phis. + * @return The Phis class object for @p all_phis. */ -void phi_class_free(ir_graph *irg); +phi_classes_t *phi_class_new_from_set(ir_graph *irg, pset *all_phis); /** - * @param irn A node to get the phi class for - * @return A pset containing all members of the phi class @p irn belongs to. - * If @p irn is not member of a phi class NULL is returned. + * Free all allocated data. */ -pset *get_phi_class(const ir_node *irn); +void phi_class_free(phi_classes_t *pc); -#endif +#endif /* _PHICLASS_H_ */ diff --git a/ir/ana/phiclass_t.h b/ir/ana/phiclass_t.h deleted file mode 100644 index 5367c4de8..000000000 --- a/ir/ana/phiclass_t.h +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Analysis to conmpute phi congruence classes. - * @author Daniel Grund - * @date 09.08.2005 - */ - -#ifndef _BEPHICONGR_T_H -#define _BEPHICONGR_T_H - -#include "phiclass.h" - -typedef struct _phi_info_t { - pset *phi_class; /**< A set containing all members of the - phi congruence class of this irn */ -} phi_info_t; - -extern size_t phi_irn_data_offset; - -#define get_irn_phi_info(irn) get_irn_data(irn, phi_info_t, phi_irn_data_offset) -#define _get_phi_class(irn) get_irn_phi_info(irn)->phi_class -#define _set_phi_class(irn,cls) get_irn_phi_info(irn)->phi_class = cls - -#endif