X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Funroll.c;h=0d3927632b1bd8a6853493c046067f382f55d8da;hb=5bf4303e2b3e213e573bf72d7b7b05ad78e9b8bb;hp=a666984045f8b4917880f58d22b9afe27229c0ba;hpb=93d3b7de9255c5d822451aba78cf879281803481;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/unroll.c b/gcc/unroll.c index a666984045f..0d3927632b1 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -1,5 +1,5 @@ /* Try to unroll loops, and split induction variables. - Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000 + Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by James E. Wilson, Cygnus Support/UC Berkeley. @@ -206,7 +206,7 @@ static void copy_loop_body PARAMS ((struct loop *, rtx, rtx, struct inline_remap *, rtx, int, enum unroll_types, rtx, rtx, rtx, rtx)); static int find_splittable_regs PARAMS ((const struct loop *, - enum unroll_types, rtx, int)); + enum unroll_types, int)); static int find_splittable_givs PARAMS ((const struct loop *, struct iv_class *, enum unroll_types, rtx, int)); @@ -222,19 +222,16 @@ static rtx ujump_to_loop_cont PARAMS ((rtx, rtx)); /* Try to unroll one loop and split induction variables in the loop. The loop is described by the arguments LOOP and INSN_COUNT. - END_INSERT_BEFORE indicates where insns should be added which need - to be executed when the loop falls through. STRENGTH_REDUCTION_P - indicates whether information generated in the strength reduction - pass is available. + STRENGTH_REDUCTION_P indicates whether information generated in the + strength reduction pass is available. This function is intended to be called from within `strength_reduce' in loop.c. */ void -unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) +unroll_loop (loop, insn_count, strength_reduce_p) struct loop *loop; int insn_count; - rtx end_insert_before; int strength_reduce_p; { struct loop_info *loop_info = LOOP_INFO (loop); @@ -768,7 +765,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) } } } - else if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX))) + if ((note = find_reg_note (insn, REG_LABEL, NULL_RTX))) set_label_in_map (map, CODE_LABEL_NUMBER (XEXP (note, 0)), XEXP (note, 0)); } @@ -841,9 +838,9 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) these pseudo registers have valid regno_first_uid info. */ for (r = FIRST_PSEUDO_REGISTER; r < max_reg_before_loop; ++r) if (REGNO_FIRST_UID (r) > 0 && REGNO_FIRST_UID (r) <= max_uid_for_loop - && uid_luid[REGNO_FIRST_UID (r)] >= copy_start_luid + && REGNO_FIRST_LUID (r) >= copy_start_luid && REGNO_LAST_UID (r) > 0 && REGNO_LAST_UID (r) <= max_uid_for_loop - && uid_luid[REGNO_LAST_UID (r)] <= copy_end_luid) + && REGNO_LAST_LUID (r) <= copy_end_luid) { /* However, we must also check for loop-carried dependencies. If the value the pseudo has at the end of iteration X is @@ -1045,7 +1042,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) sequence = gen_sequence (); end_sequence (); - emit_insn_before (sequence, loop_start); + loop_insn_hoist (loop, sequence); /* Only the last copy of the loop body here needs the exit test, so set copy_end to exclude the compare/branch here, @@ -1163,8 +1160,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) if (splitting_not_safe) temp = 0; else - temp = find_splittable_regs (loop, unroll_type, - end_insert_before, unroll_number); + temp = find_splittable_regs (loop, unroll_type, unroll_number); /* find_splittable_regs may have created some new registers, so must reallocate the reg_map with the new larger size, and must realloc @@ -1184,7 +1180,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) /* Search the list of bivs and givs to find ones which need to be remapped when split, and set their reg_map entry appropriately. */ - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { if (REGNO (bl->biv->src_reg) != bl->regno) map->reg_map[bl->regno] = bl->biv->src_reg; @@ -1197,8 +1193,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p) } /* Use our current register alignment and pointer flags. */ - map->regno_pointer_flag = cfun->emit->regno_pointer_flag; map->regno_pointer_align = cfun->emit->regno_pointer_align; + map->x_regno_reg_rtx = cfun->emit->x_regno_reg_rtx; /* If the loop is being partially unrolled, and the iteration variables are being split, and are being renamed for the split, then must fix up @@ -1385,7 +1381,14 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode) return 1; } - if (loop_info->initial_value == 0) + if (loop_info->iteration_var == 0) + { + if (loop_dump_stream) + fprintf (loop_dump_stream, + "Preconditioning: Could not find iteration variable.\n"); + return 0; + } + else if (loop_info->initial_value == 0) { if (loop_dump_stream) fprintf (loop_dump_stream, @@ -1457,7 +1460,7 @@ precondition_loop_p (loop, initial_value, final_value, increment, mode) /* Fail if loop_info->iteration_var is not live before loop_start, since we need to test its value in the preconditioning code. */ - if (uid_luid[REGNO_FIRST_UID (REGNO (loop_info->iteration_var))] + if (REGNO_FIRST_LUID (REGNO (loop_info->iteration_var)) > INSN_LUID (loop_start)) { if (loop_dump_stream) @@ -1770,7 +1773,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration, unsigned int regno = REGNO (SET_DEST (set)); v = addr_combined_regs[REGNO (SET_DEST (set))]; - bl = ivs->reg_biv_class[REGNO (v->src_reg)]; + bl = REG_IV_CLASS (ivs, REGNO (v->src_reg)); /* Although the giv_inc amount is not needed here, we must call calculate_giv_inc here since it might try to delete the @@ -1912,10 +1915,10 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration, for the biv was stored in the biv's first struct induction entry by find_splittable_regs. */ - if (regno < max_reg_before_loop + if (regno < ivs->n_regs && REG_IV_TYPE (ivs, regno) == BASIC_INDUCT) { - giv_src_reg = ivs->reg_biv_class[regno]->biv->src_reg; + giv_src_reg = REG_IV_CLASS (ivs, regno)->biv->src_reg; giv_dest_reg = giv_src_reg; } @@ -2254,7 +2257,7 @@ copy_loop_body (loop, copy_start, copy_end, map, exit_label, last_iteration, tem = gen_sequence (); end_sequence (); - emit_insn_before (tem, insert_before); + loop_insn_emit_before (loop, 0, insert_before, tem); } /* Emit an insn, using the expand_binop to ensure that a valid insn is @@ -2381,7 +2384,7 @@ fold_rtx_mult_add (mult1, mult2, add1, mode) rtx biv_total_increment (bl) - struct iv_class *bl; + const struct iv_class *bl; { struct induction *v; rtx result; @@ -2431,10 +2434,9 @@ biv_total_increment (bl) times, since multiplies by small integers (1,2,3,4) are very cheap. */ static int -find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) +find_splittable_regs (loop, unroll_type, unroll_number) const struct loop *loop; enum unroll_types unroll_type; - rtx end_insert_before; int unroll_number; { struct loop_ivs *ivs = LOOP_IVS (loop); @@ -2444,10 +2446,8 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) rtx biv_final_value; int biv_splittable; int result = 0; - rtx loop_start = loop->start; - rtx loop_end = loop->end; - for (bl = ivs->loop_iv_list; bl; bl = bl->next) + for (bl = ivs->list; bl; bl = bl->next) { /* Biv_total_increment must return a constant value, otherwise we can not calculate the split values. */ @@ -2469,10 +2469,10 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) biv_final_value = 0; if (unroll_type != UNROLL_COMPLETELY && (loop->exit_count || unroll_type == UNROLL_NAIVE) - && (uid_luid[REGNO_LAST_UID (bl->regno)] >= INSN_LUID (loop_end) + && (REGNO_LAST_LUID (bl->regno) >= INSN_LUID (loop->end) || ! bl->init_insn || INSN_UID (bl->init_insn) >= max_uid_for_loop - || (uid_luid[REGNO_FIRST_UID (bl->regno)] + || (REGNO_FIRST_LUID (bl->regno) < INSN_LUID (bl->init_insn)) || reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set))) && ! (biv_final_value = final_biv_value (loop, bl))) @@ -2512,8 +2512,8 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) rtx tem = gen_reg_rtx (bl->biv->mode); record_base_value (REGNO (tem), bl->biv->add_val, 0); - emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), - loop_start); + loop_insn_hoist (loop, + gen_move_insn (tem, bl->biv->src_reg)); if (loop_dump_stream) fprintf (loop_dump_stream, @@ -2558,9 +2558,8 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) how the loop exits. Otherwise emit the insn after the loop, since this is slightly more efficient. */ if (! loop->exit_count) - emit_insn_before (gen_move_insn (bl->biv->src_reg, - biv_final_value), - end_insert_before); + loop_insn_sink (loop, gen_move_insn (bl->biv->src_reg, + biv_final_value)); else { /* Create a new register to hold the value of the biv, and then @@ -2571,11 +2570,9 @@ find_splittable_regs (loop, unroll_type, end_insert_before, unroll_number) rtx tem = gen_reg_rtx (bl->biv->mode); record_base_value (REGNO (tem), bl->biv->add_val, 0); - emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), - loop_start); - emit_insn_before (gen_move_insn (bl->biv->src_reg, - biv_final_value), - loop_start); + loop_insn_hoist (loop, gen_move_insn (tem, bl->biv->src_reg)); + loop_insn_hoist (loop, gen_move_insn (bl->biv->src_reg, + biv_final_value)); if (loop_dump_stream) fprintf (loop_dump_stream, "Biv %d mapped to %d for split.\n", @@ -2698,7 +2695,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) || (REGNO_FIRST_UID (REGNO (v->dest_reg)) != INSN_UID (XEXP (tem, 0))))) /* Line above always fails if INSN was moved by loop opt. */ - || (uid_luid[REGNO_LAST_UID (REGNO (v->dest_reg))] + || (REGNO_LAST_LUID (REGNO (v->dest_reg)) >= INSN_LUID (loop->end))) && ! (final_value = v->final_value)) continue; @@ -2717,9 +2714,8 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) to its final value before loop start to ensure that this insn will always be executed, no matter how we exit. */ tem = gen_reg_rtx (v->mode); - emit_insn_before (gen_move_insn (tem, v->dest_reg), loop_start); - emit_insn_before (gen_move_insn (v->dest_reg, final_value), - loop_start); + loop_insn_hoist (loop, gen_move_insn (tem, v->dest_reg)); + loop_insn_hoist (loop, gen_move_insn (v->dest_reg, final_value)); if (loop_dump_stream) fprintf (loop_dump_stream, "Giv %d mapped to %d for split.\n", @@ -2752,8 +2748,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) rtx tem = gen_reg_rtx (bl->biv->mode); record_base_value (REGNO (tem), bl->biv->add_val, 0); - emit_insn_before (gen_move_insn (tem, bl->biv->src_reg), - loop->start); + loop_insn_hoist (loop, gen_move_insn (tem, bl->biv->src_reg)); biv_initial_value = tem; } biv_initial_value = extend_value_for_giv (v, biv_initial_value); @@ -2795,8 +2790,8 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) { rtx tem = gen_reg_rtx (v->mode); record_base_value (REGNO (tem), v->add_val, 0); - emit_iv_add_mult (bl->initial_value, v->mult_val, - v->add_val, tem, loop->start); + loop_iv_add_mult_hoist (loop, bl->initial_value, v->mult_val, + v->add_val, tem); value = tem; } @@ -2923,17 +2918,15 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) instruction on machines with complex addressing modes. If we can't recognize it, then delete it and emit insns to calculate the value from scratch. */ - emit_insn_before (gen_rtx_SET (VOIDmode, tem, - copy_rtx (v->new_reg)), - loop->start); + loop_insn_hoist (loop, gen_rtx_SET (VOIDmode, tem, + copy_rtx (v->new_reg))); if (recog_memoized (PREV_INSN (loop->start)) < 0) { rtx sequence, ret; /* We can't use bl->initial_value to compute the initial value, because the loop may have been preconditioned. - We must calculate it from NEW_REG. Try using - force_operand instead of emit_iv_add_mult. */ + We must calculate it from NEW_REG. */ delete_insn (PREV_INSN (loop->start)); start_sequence (); @@ -2942,7 +2935,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) emit_move_insn (tem, ret); sequence = gen_sequence (); end_sequence (); - emit_insn_before (sequence, loop->start); + loop_insn_hoist (loop, sequence); if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3030,7 +3023,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) { int count = 1; if (! v->ignore) - count = ivs->reg_biv_class[REGNO (v->src_reg)]->biv_count; + count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count; splittable_regs_updates[REGNO (v->new_reg)] = count; } @@ -3140,7 +3133,6 @@ final_biv_value (loop, bl) const struct loop *loop; struct iv_class *bl; { - rtx loop_end = loop->end; unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations; rtx increment, tem; @@ -3182,11 +3174,8 @@ final_biv_value (loop, bl) tem = gen_reg_rtx (bl->biv->mode); record_base_value (REGNO (tem), bl->biv->add_val, 0); - /* Make sure loop_end is not the last insn. */ - if (NEXT_INSN (loop_end) == 0) - emit_note_after (NOTE_INSN_DELETED, loop_end); - emit_iv_add_mult (increment, GEN_INT (n_iterations), - bl->initial_value, tem, NEXT_INSN (loop_end)); + loop_iv_add_mult_sink (loop, increment, GEN_INT (n_iterations), + bl->initial_value, tem); if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3222,11 +3211,11 @@ final_giv_value (loop, v) struct iv_class *bl; rtx insn; rtx increment, tem; - rtx insert_before, seq; + rtx seq; rtx loop_end = loop->end; unsigned HOST_WIDE_INT n_iterations = LOOP_INFO (loop)->n_iterations; - bl = ivs->reg_biv_class[REGNO (v->src_reg)]; + bl = REG_IV_CLASS (ivs, REGNO (v->src_reg)); /* The final value for givs which depend on reversed bivs must be calculated differently than for ordinary givs. In this case, there is already an @@ -3279,15 +3268,13 @@ final_giv_value (loop, v) We must search from the insn that sets the giv to the end of the loop to calculate this value. */ - insert_before = NEXT_INSN (loop_end); - /* Put the final biv value in tem. */ tem = gen_reg_rtx (v->mode); record_base_value (REGNO (tem), bl->biv->add_val, 0); - emit_iv_add_mult (extend_value_for_giv (v, increment), - GEN_INT (n_iterations), - extend_value_for_giv (v, bl->initial_value), - tem, insert_before); + loop_iv_add_mult_sink (loop, extend_value_for_giv (v, increment), + GEN_INT (n_iterations), + extend_value_for_giv (v, bl->initial_value), + tem); /* Subtract off extra increments as we find them. */ for (insn = NEXT_INSN (v->insn); insn != loop_end; @@ -3304,12 +3291,12 @@ final_giv_value (loop, v) OPTAB_LIB_WIDEN); seq = gen_sequence (); end_sequence (); - emit_insn_before (seq, insert_before); + loop_insn_sink (loop, seq); } } /* Now calculate the giv's final value. */ - emit_iv_add_mult (tem, v->mult_val, v->add_val, tem, insert_before); + loop_iv_add_mult_sink (loop, tem, v->mult_val, v->add_val, tem); if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3545,7 +3532,7 @@ loop_iterations (loop) will propagate a new pseudo into the old iteration register but this will be marked by having the REG_USERVAR_P bit set. */ - if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements + if ((unsigned) REGNO (iteration_var) >= ivs->n_regs && ! REG_USERVAR_P (iteration_var)) abort (); @@ -3563,7 +3550,7 @@ loop_iterations (loop) /* If this is a new register, can't handle it since we don't have any reg_iv_type entry for it. */ - if ((unsigned) REGNO (iteration_var) >= ivs->reg_iv_type->num_elements) + if ((unsigned) REGNO (iteration_var) >= ivs->n_regs) { if (loop_dump_stream) fprintf (loop_dump_stream, @@ -3591,15 +3578,19 @@ loop_iterations (loop) } else if (REG_IV_TYPE (ivs, REGNO (iteration_var)) == BASIC_INDUCT) { - /* When reg_iv_type / reg_iv_info is resized for biv increments - that are turned into givs, reg_biv_class is not resized. - So check here that we don't make an out-of-bounds access. */ - if (REGNO (iteration_var) >= max_reg_before_loop) + if (REGNO (iteration_var) >= ivs->n_regs) abort (); /* Grab initial value, only useful if it is a constant. */ - bl = ivs->reg_biv_class[REGNO (iteration_var)]; + bl = REG_IV_CLASS (ivs, REGNO (iteration_var)); initial_value = bl->initial_value; + if (!bl->biv->always_executed || bl->biv->maybe_multiple) + { + if (loop_dump_stream) + fprintf (loop_dump_stream, + "Loop iterations: Basic induction var not set once in each iteration.\n"); + return 0; + } increment = biv_total_increment (bl); } @@ -3609,10 +3600,18 @@ loop_iterations (loop) struct induction *v = REG_IV_INFO (ivs, REGNO (iteration_var)); rtx biv_initial_value; - if (REGNO (v->src_reg) >= max_reg_before_loop) + if (REGNO (v->src_reg) >= ivs->n_regs) abort (); - bl = ivs->reg_biv_class[REGNO (v->src_reg)]; + if (!v->always_executed || v->maybe_multiple) + { + if (loop_dump_stream) + fprintf (loop_dump_stream, + "Loop iterations: General induction var not set once in each iteration.\n"); + return 0; + } + + bl = REG_IV_CLASS (ivs, REGNO (v->src_reg)); /* Increment value is mult_val times the increment value of the biv. */ @@ -3855,7 +3854,7 @@ loop_iterations (loop) { fprintf (loop_dump_stream, "Loop iterations: Increment value not constant "); - print_rtl (loop_dump_stream, increment); + print_simple_rtl (loop_dump_stream, increment); fprintf (loop_dump_stream, ".\n"); } return 0; @@ -3869,7 +3868,7 @@ loop_iterations (loop) { fprintf (loop_dump_stream, "Loop iterations: Initial value not constant "); - print_rtl (loop_dump_stream, initial_value); + print_simple_rtl (loop_dump_stream, initial_value); fprintf (loop_dump_stream, ".\n"); } return 0; @@ -3886,7 +3885,7 @@ loop_iterations (loop) { fprintf (loop_dump_stream, "Loop iterations: Final value not constant "); - print_rtl (loop_dump_stream, final_value); + print_simple_rtl (loop_dump_stream, final_value); fprintf (loop_dump_stream, ".\n"); } return 0; @@ -4012,9 +4011,9 @@ remap_split_bivs (loop, x) /* If non-reduced/final-value givs were split, then this would also have to remap those givs also. */ #endif - if (REGNO (x) < max_reg_before_loop + if (REGNO (x) < ivs->n_regs && REG_IV_TYPE (ivs, REGNO (x)) == BASIC_INDUCT) - return ivs->reg_biv_class[REGNO (x)]->biv->src_reg; + return REG_IV_CLASS (ivs, REGNO (x))->biv->src_reg; break; default: