X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fdead_code_elimination.c;h=f356f79a46a80b96a6d9629904ff081d085e85c4;hb=63c22f8a9964eaedaa6ab509de10cca18604709e;hp=cd969565133a867310130b3ff3a17f1d91cbadfd;hpb=c8e1cf6a41fa2077058cce740783ab78990ac0ab;p=libfirm diff --git a/ir/opt/dead_code_elimination.c b/ir/opt/dead_code_elimination.c index cd9695651..f356f79a4 100644 --- a/ir/opt/dead_code_elimination.c +++ b/ir/opt/dead_code_elimination.c @@ -21,7 +21,6 @@ * @file * @brief Dead node elimination * @author Michael Beck, Goetz Lindenmaier - * @version $Id: opt_inline.c 27265 2010-03-07 15:13:00Z matze $ * * Strictly speaking dead node elimination is unnecessary in firm - everthying * which is not used can't be found by any walker. @@ -34,7 +33,6 @@ #include "iroptimize.h" #include "irnode_t.h" #include "irgraph_t.h" -#include "irphase_t.h" #include "iredges_t.h" #include "irhooks.h" #include "irtools.h" @@ -46,9 +44,6 @@ #include "irpass.h" #include "pmap.h" -/** a pointer to the new phases */ -static ir_phase *new_phases[PHASE_LAST + 1]; - /** * Reroute the inputs of a node from nodes in the old graph to copied nodes in * the new graph @@ -61,75 +56,33 @@ static void rewire_inputs(ir_node *node, void *env) static void copy_node_dce(ir_node *node, void *env) { - int i; ir_node *new_node = exact_copy(node); - ir_graph *irg = get_irn_irg(new_node); (void) env; /* preserve the node numbers for easier debugging */ new_node->node_nr = node->node_nr; - /* copy phase information for this node */ - for (i = 0; i <= PHASE_LAST; i++) { - ir_phase *phase = irg_get_phase(irg, i); - if (phase == NULL) - continue; - if (!phase_get_irn_data(phase, node)) - continue; - phase_set_irn_data(new_phases[i], new_node, - phase_get_irn_data(phase, node)); - } - set_irn_link(node, new_node); - hook_dead_node_elim_subst(irg, node, new_node); } /** - * Copies the graph reachable from current_ir_graph->end to the obstack - * in current_ir_graph and fixes the environment. - * Then fixes the fields in current_ir_graph containing nodes of the - * graph. + * Copies the graph reachable from the End node to the obstack + * in irg. Then fixes the fields containing nodes of the graph. * * @param copy_node_nr If non-zero, the node number will be copied */ static void copy_graph_env(ir_graph *irg) { + ir_node *anchor = irg->anchor; ir_node *new_anchor; - int i; - - /* init the new_phases array */ - /* TODO: this is wrong, it should only allocate a new data_ptr inside - * the phase! */ - for (i = 0; i <= PHASE_LAST; i++) { - ir_phase *old_ph = irg_get_phase(irg, i); - if (old_ph == NULL) { - new_phases[i] = NULL; - } else { - new_phases[i] = new_phase(irg, old_ph->data_init); - new_phases[i]->priv = old_ph->priv; - } - } /* copy nodes */ - irg_walk_anchors(irg, copy_node_dce, rewire_inputs, NULL); + irg_walk_in_or_dep(anchor, copy_node_dce, rewire_inputs, NULL); /* fix the anchor */ - new_anchor = get_irn_link(irg->anchor); + new_anchor = (ir_node*)get_irn_link(anchor); assert(new_anchor != NULL); irg->anchor = new_anchor; - - /* copy the new phases into the irg */ - for (i = 0; i <= PHASE_LAST; i++) { - ir_phase *old_ph = irg_get_phase(irg, i); - if (old_ph == NULL) - continue; - - /* Matze: commented out for now: This is a memory leak, but for a real - * fix we must not create new phases here, but reuse the old phases - * and just create a new data array */ - /* phase_free(old_ph); */ - irg->phases[i] = new_phases[i]; - } } /** @@ -142,7 +95,6 @@ static void copy_graph_env(ir_graph *irg) */ void dead_node_elimination(ir_graph *irg) { - ir_graph *rem; struct obstack *graveyard_obst = NULL; struct obstack *rebirth_obst = NULL; @@ -151,18 +103,13 @@ void dead_node_elimination(ir_graph *irg) /* inform statistics that we started a dead-node elimination run */ hook_dead_node_elim(irg, 1); - /* Remember external state of current_ir_graph. */ - rem = current_ir_graph; - current_ir_graph = irg; - - assert(get_irg_phase_state(irg) != phase_building); - /* Handle graph state */ free_callee_info(irg); free_irg_outs(irg); free_trouts(); free_loop_information(irg); - set_irg_doms_inconsistent(irg); + free_vrp_data(irg); + clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); /* A quiet place, where the old obstack can rest in peace, until it will be cremated. */ @@ -186,130 +133,9 @@ void dead_node_elimination(ir_graph *irg) /* inform statistics that the run is over */ hook_dead_node_elim(irg, 0); - - current_ir_graph = rem; } ir_graph_pass_t *dead_node_elimination_pass(const char *name) { return def_graph_pass(name ? name : "dce", dead_node_elimination); } - - -/* - __ _ __ __ - (_ __ o _ | \/ |_ - __)|_| | \_/ | \_/(/_ |_/\__|__ - - The following stuff implements a facility that automatically patches - registered ir_node pointers to the new node when a dead node elimination - occurs. - - Warning: This is considered a hack - try hard to avoid this! -*/ - -struct survive_dce_t { - struct obstack obst; - pmap *places; - pmap *new_places; - hook_entry_t dead_node_elim; - hook_entry_t dead_node_elim_subst; -}; - -typedef struct survive_dce_list_t { - struct survive_dce_list_t *next; - ir_node **place; -} survive_dce_list_t; - -static void dead_node_hook(void *context, ir_graph *irg, int start) -{ - survive_dce_t *sd = context; - (void) irg; - - /* Create a new map before the dead node elimination is performed. */ - if (start) { - sd->new_places = pmap_create_ex(pmap_count(sd->places)); - } else { - /* Patch back all nodes if dead node elimination is over and something is to be done. */ - pmap_destroy(sd->places); - sd->places = sd->new_places; - sd->new_places = NULL; - } -} - -/** - * Hook called when dead node elimination replaces old by nw. - */ -static void dead_node_subst_hook(void *context, ir_graph *irg, ir_node *old, ir_node *nw) -{ - survive_dce_t *sd = context; - survive_dce_list_t *list = pmap_get(sd->places, old); - (void) irg; - - /* If the node is to be patched back, write the new address to all registered locations. */ - if (list) { - survive_dce_list_t *p; - - for (p = list; p; p = p->next) - *(p->place) = nw; - - pmap_insert(sd->new_places, nw, list); - } -} - -/** - * Make a new Survive DCE environment. - */ -survive_dce_t *new_survive_dce(void) -{ - survive_dce_t *res = XMALLOC(survive_dce_t); - obstack_init(&res->obst); - res->places = pmap_create(); - res->new_places = NULL; - - res->dead_node_elim.hook._hook_dead_node_elim = dead_node_hook; - res->dead_node_elim.context = res; - res->dead_node_elim.next = NULL; - - res->dead_node_elim_subst.hook._hook_dead_node_elim_subst = dead_node_subst_hook; - res->dead_node_elim_subst.context = res; - res->dead_node_elim_subst.next = NULL; - - register_hook(hook_dead_node_elim, &res->dead_node_elim); - register_hook(hook_dead_node_elim_subst, &res->dead_node_elim_subst); - return res; -} - -/** - * Free a Survive DCE environment. - */ -void free_survive_dce(survive_dce_t *sd) -{ - obstack_free(&sd->obst, NULL); - pmap_destroy(sd->places); - unregister_hook(hook_dead_node_elim, &sd->dead_node_elim); - unregister_hook(hook_dead_node_elim_subst, &sd->dead_node_elim_subst); - xfree(sd); -} - -/** - * Register a node pointer to be patched upon DCE. - * When DCE occurs, the node pointer specified by @p place will be - * patched to the new address of the node it is pointing to. - * - * @param sd The Survive DCE environment. - * @param place The address of the node pointer. - */ -void survive_dce_register_irn(survive_dce_t *sd, ir_node **place) -{ - if (*place != NULL) { - ir_node *irn = *place; - survive_dce_list_t *curr = pmap_get(sd->places, irn); - survive_dce_list_t *nw = OALLOC(&sd->obst, survive_dce_list_t); - - nw->next = curr; - nw->place = place; - - pmap_insert(sd->places, irn, nw); - } -}