X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Floop.c;h=8e7fae7e6e66c939bf93a6feab9649dcd718b3ac;hb=8c9921a1fc166552f6e416434fd8394a4fc210a3;hp=082464e4160077253823988b509669f7f22db104;hpb=7d5b331123bd8399f5f1d057e90797faa3300b66;p=libfirm diff --git a/ir/opt/loop.c b/ir/opt/loop.c index 082464e41..8e7fae7e6 100644 --- a/ir/opt/loop.c +++ b/ir/opt/loop.c @@ -22,7 +22,6 @@ * @author Christian Helmer * @brief loop inversion and loop unrolling * - * @version $Id$ */ #include "config.h" @@ -49,10 +48,9 @@ #include #include "irbackedge_t.h" -#include "irphase_t.h" +#include "irnodemap.h" #include "irloop_t.h" - DEBUG_ONLY(static firm_dbg_module_t *dbg;) /** @@ -212,7 +210,8 @@ static entry_edge *loop_entries; /* Number of unrolls to perform */ static int unroll_nr; /* Phase is used to keep copies of nodes. */ -static ir_phase *phase; +static ir_nodemap map; +static struct obstack obst; /* Loop operations. */ typedef enum loop_op_t { @@ -496,16 +495,14 @@ static void set_unroll_copy(ir_node *n, int nr, ir_node *cp) unrolling_node_info *info; assert(nr != 0 && "0 reserved"); - info = (unrolling_node_info *)phase_get_irn_data(phase, n); + info = (unrolling_node_info*)ir_nodemap_get(&map, n); if (! info) { - ir_node **arr; + ir_node **arr = NEW_ARR_D(ir_node*, &obst, unroll_nr); + memset(arr, 0, unroll_nr * sizeof(ir_node*)); - info = XMALLOCZ(unrolling_node_info); - arr = NEW_ARR_F(ir_node *, unroll_nr); + info = OALLOCZ(&obst, unrolling_node_info); info->copies = arr; - memset(info->copies, 0, (unroll_nr) * sizeof(ir_node *)); - - phase_set_irn_data(phase, n, info); + ir_nodemap_insert(&map, n, info); } /* Original node */ info->copies[0] = n; @@ -517,7 +514,7 @@ static void set_unroll_copy(ir_node *n, int nr, ir_node *cp) static ir_node *get_unroll_copy(ir_node *n, int nr) { ir_node *cp; - unrolling_node_info *info = (unrolling_node_info *)phase_get_irn_data(phase, n); + unrolling_node_info *info = (unrolling_node_info *)ir_nodemap_get(&map, n); if (! info) return NULL; @@ -531,13 +528,13 @@ static ir_node *get_unroll_copy(ir_node *n, int nr) /* Sets copy cp of node n. */ static void set_inversion_copy(ir_node *n, ir_node *cp) { - phase_set_irn_data(phase, n, cp); + ir_nodemap_insert(&map, n, cp); } /* Getter of copy of n for inversion */ static ir_node *get_inversion_copy(ir_node *n) { - ir_node *cp = (ir_node *)phase_get_irn_data(phase, n); + ir_node *cp = (ir_node *)ir_nodemap_get(&map, n); return cp; } @@ -1310,7 +1307,8 @@ static void loop_inversion(ir_graph *irg) inversion_blocks_in_cc = 0; /* Use phase to keep copy of nodes from the condition chain. */ - phase = new_phase(irg, phase_irn_init_default); + ir_nodemap_init(&map, irg); + obstack_init(&obst); /* Search for condition chains and temporarily save the blocks in an array. */ cc_blocks = NEW_ARR_F(ir_node *, 0); @@ -1355,14 +1353,15 @@ static void loop_inversion(ir_graph *irg) DEL_ARR_F(cur_head_outs); /* Duplicated blocks changed doms */ - clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE); - set_irg_loopinfo_state(irg, loopinfo_cf_inconsistent); + clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE + | IR_GRAPH_STATE_CONSISTENT_LOOPINFO); ++stats.inverted; } /* free */ - phase_free(phase); + obstack_free(&obst, NULL); + ir_nodemap_destroy(&map); DEL_ARR_F(cond_chain_entries); DEL_ARR_F(head_df_loop); @@ -2555,7 +2554,8 @@ static void unroll_loop(void) } /* Use phase to keep copy of nodes from the condition chain. */ - phase = new_phase(current_ir_graph, phase_irn_init_default); + ir_nodemap_init(&map, current_ir_graph); + obstack_init(&obst); /* Copies the loop */ copy_loop(loop_entries, unroll_nr - 1); @@ -2577,6 +2577,8 @@ static void unroll_loop(void) clear_irg_state(current_ir_graph, IR_GRAPH_STATE_CONSISTENT_DOMINANCE); DEL_ARR_F(loop_entries); + obstack_free(&obst, NULL); + ir_nodemap_destroy(&map); } } @@ -2593,8 +2595,8 @@ static void init_analyze(ir_graph *irg, ir_loop *loop) /* Reset loop info */ memset(&loop_info, 0, sizeof(loop_info_t)); - DB((dbg, LEVEL_1, " >>>> current loop includes node %N <<<\n", - get_loop_node(loop, 0))); + DB((dbg, LEVEL_1, " >>>> current loop %ld <<<\n", + get_loop_loop_nr(loop))); /* Collect loop informations: head, node counts. */ irg_walk_graph(irg, get_loop_info, NULL, NULL); @@ -2626,24 +2628,28 @@ static void init_analyze(ir_graph *irg, ir_loop *loop) default: panic("Loop optimization not implemented."); } - DB((dbg, LEVEL_1, " <<<< end of loop with node %N >>>>\n", - get_loop_node(loop, 0))); + DB((dbg, LEVEL_1, " <<<< end of loop with node %ld >>>>\n", + get_loop_loop_nr(loop))); } /* Find innermost loops and add them to loops. */ static void find_innermost_loop(ir_loop *loop) { - /* descend into sons */ - size_t sons = get_loop_n_sons(loop); - - if (sons == 0) { - ARR_APP1(ir_loop *, loops, loop); - } else { - size_t s; - for (s = 0; s < sons; ++s) { - find_innermost_loop(get_loop_son(loop, s)); + bool had_sons = false; + size_t n_elements = get_loop_n_elements(loop); + size_t e; + + for (e = 0; e < n_elements; ++e) { + loop_element element = get_loop_element(loop, e); + if (*element.kind == k_ir_loop) { + find_innermost_loop(element.son); + had_sons = true; } } + + if (!had_sons) { + ARR_APP1(ir_loop*, loops, loop); + } } static void set_loop_params(void) @@ -2669,8 +2675,8 @@ static void set_loop_params(void) void loop_optimization(ir_graph *irg) { ir_loop *loop; - size_t sons, nr; - size_t i; + size_t i; + size_t n_elements; set_loop_params(); @@ -2684,12 +2690,15 @@ void loop_optimization(ir_graph *irg) collect_phiprojs(irg); loop = get_irg_loop(irg); - sons = get_loop_n_sons(loop); loops = NEW_ARR_F(ir_loop *, 0); /* List all inner loops */ - for (nr = 0; nr < sons; ++nr) { - find_innermost_loop(get_loop_son(loop, nr)); + n_elements = get_loop_n_elements(loop); + for (i = 0; i < n_elements; ++i) { + loop_element element = get_loop_element(loop, i); + if (*element.kind != k_ir_loop) + continue; + find_innermost_loop(element.son); } /* Set all links to NULL */ @@ -2738,19 +2747,19 @@ static ir_graph_state_t perform_loop_peeling(ir_graph *irg) return 0; } -optdesc_t opt_unroll_loops = { +static optdesc_t opt_unroll_loops = { "unroll-loops", IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_CONSISTENT_LOOPINFO, perform_loop_unrolling, }; -optdesc_t opt_invert_loops = { +static optdesc_t opt_invert_loops = { "invert-loops", IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_CONSISTENT_LOOPINFO, perform_loop_inversion, }; -optdesc_t opt_peel_loops = { +static optdesc_t opt_peel_loops = { "peel-loops", IR_GRAPH_STATE_CONSISTENT_OUT_EDGES | IR_GRAPH_STATE_CONSISTENT_OUTS | IR_GRAPH_STATE_CONSISTENT_LOOPINFO, perform_loop_peeling,