X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Floop_unrolling.c;h=564d44a6471f7cd38bdbb145f947eed18eca14d4;hb=98c8808ee1d34300860bb78185558e1731a99368;hp=db2d6722eecc014dd3d7571af1a6cbb69e4e6312;hpb=a346e6ebbd106566b8426d310fae5958751f82db;p=libfirm diff --git a/ir/opt/loop_unrolling.c b/ir/opt/loop_unrolling.c index db2d6722e..564d44a64 100644 --- a/ir/opt/loop_unrolling.c +++ b/ir/opt/loop_unrolling.c @@ -35,6 +35,7 @@ # include "irgopt_t.h" # include "irnode_t.h" # include "irouts.h" +# include "trouts.h" # include "hashptr.h" # include "pset.h" # include "strength_red.h" @@ -444,7 +445,7 @@ static void copy_loop_body(set *l_n, induct_var_info *info, int unroll_factor) { int i; - copies_t *value, *info_op, *phi, *loop_h, key, *value_block; + copies_t *value, *info_op, *phi, *loop_h = NULL, key, *value_block; ir_node *loop_head = get_loop_node(info->l_itervar_phi, 0); @@ -454,13 +455,13 @@ copy_loop_body(set *l_n, induct_var_info *info, int unroll_factor) else if (is_Phi_in_loop_head(value->irn, loop_head)) phi = value; else if (copy_loop_head){ - /* If the loop head must be copied. */ + /* The loop head must be copied. */ for (i = 0; i < unroll_factor - 1; i++){ copy_node(value->irn, NULL); value->copy[i] = get_irn_link(value->irn); } } else { - /* If the loop head and its nodes mustn't be copied. */ + /* The loop head and its nodes must not be copied. */ if((value->irn->op == op_Block && value->irn != loop_head) || (value->irn->op != op_Block && @@ -663,7 +664,7 @@ new_after_loop_block (set *l_n, ir_node* block, copies_t *loop_in, int unroll_fa static void new_after_loop_node(set *l_n, set *loop_outs, ir_node *node, copies_t *loop_in, int unroll_factor) { - ir_node *pred, *block_pred, *node_block, *new_phi; + ir_node *pred, *block_pred = NULL, *node_block, *new_phi; int phi = 0, old_preds, new_preds, all_new_preds, p, q, i, s; copies_t key, *value = NULL; ir_node **all_in; @@ -705,10 +706,11 @@ new_after_loop_node(set *l_n, set *loop_outs, ir_node *node, copies_t *loop_in, if (get_irn_op(block_pred) == op_Proj) { if (get_Proj_pred(block_pred) == pred) - break; + break; } - else + else { block_pred = NULL; + } } if (! block_pred) return; @@ -813,10 +815,11 @@ set_loop_outs(set *l_n, set *loop_outs, set *loop_endblock_outs, induct_var_info * Called from a post walker. * * @param n An IR node. - * @param env Free environment pointer. + * @param env points to a result */ static void do_loop_unroll(ir_node *n, void *env) { + int *unroll_done = env; induct_var_info info; copies_t *value; set *loop_nodes, *loop_outs, *loop_endblock_outs; @@ -884,9 +887,11 @@ static void do_loop_unroll(ir_node *n, void *env) unroll_factor = 2; else return; - printf("\nloop unrolling with factor %d \n", unroll_factor); + if (get_firm_verbosity()) + printf("\nloop unrolling with factor %d \n", unroll_factor); - DDMG(get_irn_irg(n)); + /* ok, we will do unrolling */ + *unroll_done += 1; /* The unroll factor must be less than 4. */ assert(unroll_factor <= MAX_UNROLL); @@ -921,10 +926,8 @@ static void do_loop_unroll(ir_node *n, void *env) /* Set the backedge of the loop head. */ for (value = set_first(loop_nodes); value != NULL; value = set_next(loop_nodes)) { - if(value->irn == backedge_jmp){ - + if (value->irn == backedge_jmp) set_Block_cfgpred(loop_head, backedge_pos, value->copy[unroll_factor-2]); - } } set_loop_outs(loop_nodes, loop_outs, loop_endblock_outs, &info, unroll_factor); } @@ -933,6 +936,7 @@ static void do_loop_unroll(ir_node *n, void *env) void optimize_loop_unrolling(ir_graph *irg /* unroll factor, max body size */) { ir_graph *rem; + int unroll_done = 0; if ( !get_opt_loop_unrolling()) return; @@ -953,7 +957,16 @@ void optimize_loop_unrolling(ir_graph *irg /* unroll factor, max body size */) collect_phiprojs(irg); /* -- Search expressions that can be optimized -- */ - irg_walk_graph(irg, NULL, do_loop_unroll, NULL); + irg_walk_graph(irg, NULL, do_loop_unroll, &unroll_done); + + if (unroll_done) { + /* unrolling was done, all info is invalid */ + set_irg_dom_inconsistent(irg); + set_irg_outs_inconsistent(irg); + set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_inconsistent); + set_trouts_inconsistent(); + set_irg_callee_info_state(irg, irg_callee_info_inconsistent); + } current_ir_graph = rem; }