X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Floop-doloop.c;h=d1bd28559154bfc2c0bff4ecfd22a540347b68a4;hb=71e7d89442a899c1db36a56329c9c5f01d95417f;hp=6e33a4f9ba014273b7f8199efc18e4418541840f;hpb=7bfc9b7cc90d5fc45847f176852078b1ddd504b1;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 6e33a4f9ba0..d1bd2855915 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -1,5 +1,6 @@ /* Perform doloop optimizations - Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 + Free Software Foundation, Inc. Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz) This file is part of GCC. @@ -290,7 +291,8 @@ add_test (rtx cond, edge *e, basic_block dest) op0 = force_operand (op0, NULL_RTX); op1 = force_operand (op1, NULL_RTX); label = block_label (dest); - do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label); + do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, + NULL_RTX, label, -1); jump = get_last_insn (); if (!jump || !JUMP_P (jump)) @@ -316,13 +318,12 @@ add_test (rtx cond, edge *e, basic_block dest) redirect_edge_and_branch_force (*e, dest); return false; } - + JUMP_LABEL (jump) = label; /* The jump is supposed to handle an unlikely special case. */ - REG_NOTES (jump) - = gen_rtx_EXPR_LIST (REG_BR_PROB, - const0_rtx, REG_NOTES (jump)); + add_reg_note (jump, REG_BR_PROB, const0_rtx); + LABEL_NUSES (label)++; make_edge (bb, dest, (*e)->flags & ~EDGE_FALLTHRU); @@ -333,11 +334,14 @@ add_test (rtx cond, edge *e, basic_block dest) describes the loop, DESC describes the number of iterations of the loop, and DOLOOP_INSN is the low-overhead looping insn to emit at the end of the loop. CONDITION is the condition separated from the - DOLOOP_SEQ. COUNT is the number of iterations of the LOOP. */ + DOLOOP_SEQ. COUNT is the number of iterations of the LOOP. + ZERO_EXTEND_P says to zero extend COUNT after the increment of it to + word_mode from FROM_MODE. */ static void doloop_modify (struct loop *loop, struct niter_desc *desc, - rtx doloop_seq, rtx condition, rtx count) + rtx doloop_seq, rtx condition, rtx count, + bool zero_extend_p, enum machine_mode from_mode) { rtx counter_reg; rtx tmp, noloop = NULL_RTX; @@ -348,6 +352,7 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, bool increment_count; basic_block loop_end = desc->out_edge->src; enum machine_mode mode; + rtx true_prob_val; jump_insn = BB_END (loop_end); @@ -361,6 +366,10 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, fputs (" iterations).\n", dump_file); } + /* Get the probability of the original branch. If it exists we would + need to update REG_BR_PROB of the new jump_insn. */ + true_prob_val = find_reg_note (jump_insn, REG_BR_PROB, NULL_RTX); + /* Discard original jump to continue loop. The original compare result may still be live, so it cannot be discarded explicitly. */ delete_insn (jump_insn); @@ -406,7 +415,11 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, } if (increment_count) - count = simplify_gen_binary (PLUS, mode, count, const1_rtx); + count = simplify_gen_binary (PLUS, from_mode, count, const1_rtx); + + if (zero_extend_p) + count = simplify_gen_unary (ZERO_EXTEND, word_mode, + count, from_mode); /* Insert initialization of the count register into the loop header. */ start_sequence (); @@ -450,7 +463,7 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, set_zero->count = preheader->count; set_zero->frequency = preheader->frequency; } - + if (EDGE_COUNT (set_zero->preds) == 0) { /* All the conditions were simplified to false, remove the @@ -465,7 +478,7 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, sequence = get_insns (); end_sequence (); emit_insn_after (sequence, BB_END (set_zero)); - + set_immediate_dominator (CDI_DOMINATORS, set_zero, recompute_dominator (CDI_DOMINATORS, set_zero)); @@ -512,9 +525,14 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, /* Add a REG_NONNEG note if the actual or estimated maximum number of iterations is non-negative. */ if (nonneg) + add_reg_note (jump_insn, REG_NONNEG, NULL_RTX); + + /* Update the REG_BR_PROB note. */ + if (true_prob_val) { - REG_NOTES (jump_insn) - = gen_rtx_EXPR_LIST (REG_NONNEG, NULL_RTX, REG_NOTES (jump_insn)); + /* Seems safer to use the branch probability. */ + add_reg_note (jump_insn, REG_BR_PROB, + GEN_INT (desc->in_edge->probability)); } } @@ -537,6 +555,7 @@ doloop_optimize (struct loop *loop) struct niter_desc *desc; unsigned word_mode_size; unsigned HOST_WIDE_INT word_mode_max; + bool zero_extend_p = false; if (dump_file) fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num); @@ -576,7 +595,8 @@ doloop_optimize (struct loop *loop) max_cost = COSTS_N_INSNS (PARAM_VALUE (PARAM_MAX_ITERATIONS_COMPUTATION_COST)); - if (rtx_cost (desc->niter_expr, SET) > max_cost) + if (rtx_cost (desc->niter_expr, SET, optimize_loop_for_speed_p (loop)) + > max_cost) { if (dump_file) fprintf (dump_file, @@ -610,8 +630,7 @@ doloop_optimize (struct loop *loop) { if (word_mode_size > GET_MODE_BITSIZE (mode)) { - count = simplify_gen_unary (ZERO_EXTEND, word_mode, - count, mode); + zero_extend_p = true; iterations = simplify_gen_unary (ZERO_EXTEND, word_mode, iterations, mode); iterations_max = simplify_gen_unary (ZERO_EXTEND, word_mode, @@ -655,7 +674,8 @@ doloop_optimize (struct loop *loop) return false; } - doloop_modify (loop, desc, doloop_seq, condition, count); + doloop_modify (loop, desc, doloop_seq, condition, count, + zero_extend_p, mode); return true; }