X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Floop-doloop.c;h=448bb723a55e7a67507ec282cbe98e1766a9f10b;hb=45b44d0a8af9fe510bbacb40a7f9b0eaec9557fd;hp=7b9d168157a3143f13e7e79b31dde93d1ec9fa76;hpb=2ce55c0b803ad9417408f3e20fd7901cf4d200ea;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 7b9d168157a..448bb723a55 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -1,12 +1,12 @@ /* Perform doloop optimizations - Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. + Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz) This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "config.h" #include "system.h" @@ -70,35 +69,59 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA if it is not a decrement and branch jump insn. */ rtx -doloop_condition_get (rtx pattern) +doloop_condition_get (rtx doloop_pat) { rtx cmp; rtx inc; rtx reg; rtx inc_src; rtx condition; + rtx pattern; - /* The canonical doloop pattern we expect is: + /* The canonical doloop pattern we expect has one of the following + forms: - (parallel [(set (pc) (if_then_else (condition) - (label_ref (label)) - (pc))) - (set (reg) (plus (reg) (const_int -1))) - (additional clobbers and uses)]) + 1) (parallel [(set (pc) (if_then_else (condition) + (label_ref (label)) + (pc))) + (set (reg) (plus (reg) (const_int -1))) + (additional clobbers and uses)]) - Some targets (IA-64) wrap the set of the loop counter in - an if_then_else too. + The branch must be the first entry of the parallel (also required + by jump.c), and the second entry of the parallel must be a set of + the loop counter register. Some targets (IA-64) wrap the set of + the loop counter in an if_then_else too. - In summary, the branch must be the first entry of the - parallel (also required by jump.c), and the second - entry of the parallel must be a set of the loop counter - register. */ + 2) (set (reg) (plus (reg) (const_int -1)) + (set (pc) (if_then_else (reg != 0) + (label_ref (label)) + (pc))). */ + + pattern = PATTERN (doloop_pat); if (GET_CODE (pattern) != PARALLEL) - return 0; + { + rtx cond; - cmp = XVECEXP (pattern, 0, 0); - inc = XVECEXP (pattern, 0, 1); + /* We expect the decrement to immediately precede the branch. */ + + if ((PREV_INSN (doloop_pat) == NULL_RTX) + || !INSN_P (PREV_INSN (doloop_pat))) + return 0; + + cmp = pattern; + inc = PATTERN (PREV_INSN (doloop_pat)); + /* We expect the condition to be of the form (reg != 0) */ + cond = XEXP (SET_SRC (cmp), 0); + if (GET_CODE (cond) != NE || XEXP (cond, 1) != const0_rtx) + return 0; + + } + else + { + cmp = XVECEXP (pattern, 0, 0); + inc = XVECEXP (pattern, 0, 1); + } /* Check for (set (reg) (something)). */ if (GET_CODE (inc) != SET) @@ -140,7 +163,29 @@ doloop_condition_get (rtx pattern) if ((XEXP (condition, 0) == reg) || (GET_CODE (XEXP (condition, 0)) == PLUS && XEXP (XEXP (condition, 0), 0) == reg)) + { + if (GET_CODE (pattern) != PARALLEL) + /* The second form we expect: + + (set (reg) (plus (reg) (const_int -1)) + (set (pc) (if_then_else (reg != 0) + (label_ref (label)) + (pc))). + + is equivalent to the following: + + (parallel [(set (pc) (if_then_else (reg != 1) + (label_ref (label)) + (pc))) + (set (reg) (plus (reg) (const_int -1))) + (additional clobbers and uses)]) + + So we return that form instead. + */ + condition = gen_rtx_fmt_ee (NE, VOIDmode, inc_src, const1_rtx); + return condition; + } /* ??? If a machine uses a funny comparison, we could return a canonicalized form here. */ @@ -248,7 +293,7 @@ add_test (rtx cond, edge *e, basic_block dest) do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label); jump = get_last_insn (); - if (!JUMP_P (jump)) + if (!jump || !JUMP_P (jump)) { /* The condition is always false and the jump was optimized out. */ end_sequence (); @@ -257,7 +302,11 @@ add_test (rtx cond, edge *e, basic_block dest) seq = get_insns (); end_sequence (); - bb = loop_split_edge_with (*e, seq); + + /* There always is at least the jump insn in the sequence. */ + gcc_assert (seq != NULL_RTX); + + bb = split_edge_and_insert (*e, seq); *e = single_succ_edge (bb); if (any_uncondjump_p (jump)) @@ -299,6 +348,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); @@ -312,6 +362,10 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, fputs (" iterations).\n", dump_file); } + /* Get the probabilty 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); @@ -372,9 +426,9 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, rtx ass = copy_rtx (desc->noloop_assumptions); basic_block preheader = loop_preheader_edge (loop)->src; basic_block set_zero - = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX); + = split_edge (loop_preheader_edge (loop)); basic_block new_preheader - = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX); + = split_edge (loop_preheader_edge (loop)); edge te; /* Expand the condition testing the assumptions and if it does not pass, @@ -406,7 +460,6 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, { /* All the conditions were simplified to false, remove the unreachable set_zero block. */ - remove_bb_from_loops (set_zero); delete_basic_block (set_zero); } else @@ -419,13 +472,13 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, emit_insn_after (sequence, BB_END (set_zero)); set_immediate_dominator (CDI_DOMINATORS, set_zero, - recount_dominator (CDI_DOMINATORS, - set_zero)); + recompute_dominator (CDI_DOMINATORS, + set_zero)); } set_immediate_dominator (CDI_DOMINATORS, new_preheader, - recount_dominator (CDI_DOMINATORS, - new_preheader)); + recompute_dominator (CDI_DOMINATORS, + new_preheader)); } /* Some targets (eg, C4x) need to initialize special looping @@ -468,6 +521,15 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, REG_NOTES (jump_insn) = gen_rtx_EXPR_LIST (REG_NONNEG, NULL_RTX, REG_NOTES (jump_insn)); } + /* Update the REG_BR_PROB note. */ + if (true_prob_val) + { + /* Seems safer to use the branch probability. */ + REG_NOTES (jump_insn) = + gen_rtx_EXPR_LIST (REG_BR_PROB, + GEN_INT (desc->in_edge->probability), + REG_NOTES (jump_insn)); + } } /* Process loop described by LOOP validating that the loop is suitable for @@ -595,9 +657,7 @@ doloop_optimize (struct loop *loop) { while (NEXT_INSN (doloop_pat) != NULL_RTX) doloop_pat = NEXT_INSN (doloop_pat); - if (JUMP_P (doloop_pat)) - doloop_pat = PATTERN (doloop_pat); - else + if (!JUMP_P (doloop_pat)) doloop_pat = NULL_RTX; } @@ -613,20 +673,16 @@ doloop_optimize (struct loop *loop) return true; } -/* This is the main entry point. Process all LOOPS using doloop_optimize. */ +/* This is the main entry point. Process all loops using doloop_optimize. */ void -doloop_optimize_loops (struct loops *loops) +doloop_optimize_loops (void) { - unsigned i; + loop_iterator li; struct loop *loop; - for (i = 1; i < loops->num; i++) + FOR_EACH_LOOP (li, loop, 0) { - loop = loops->parray[i]; - if (!loop) - continue; - doloop_optimize (loop); } @@ -634,7 +690,7 @@ doloop_optimize_loops (struct loops *loops) #ifdef ENABLE_CHECKING verify_dominators (CDI_DOMINATORS); - verify_loop_structure (loops); + verify_loop_structure (); #endif } #endif /* HAVE_doloop_end */