diff options
Diffstat (limited to 'gcc/loop.c')
-rw-r--r-- | gcc/loop.c | 94 |
1 files changed, 72 insertions, 22 deletions
@@ -34,8 +34,8 @@ Boston, MA 02111-1307, USA. */ Most of the complexity is in heuristics to decide when it is worth while to do these things. */ -#include <stdio.h> #include "config.h" +#include <stdio.h> #include "rtl.h" #include "obstack.h" #include "expr.h" @@ -286,7 +286,9 @@ static void count_loop_regs_set (); static void note_addr_stored (); static int loop_reg_used_before_p (); static void scan_loop (); +#if 0 static void replace_call_address (); +#endif static rtx skip_consec_insns (); static int libcall_benefit (); static void ignore_some_movables (); @@ -817,11 +819,9 @@ scan_loop (loop_start, end, nregs) && n_times_set[REGNO (SET_DEST (set))] == 1 && ! side_effects_p (SET_SRC (set)) && ! find_reg_note (p, REG_RETVAL, NULL_RTX) -#ifdef SMALL_REGISTER_CLASSES - && ! (SMALL_REGISTER_CLASSES - && GET_CODE (SET_SRC (set)) == REG - && REGNO (SET_SRC (set)) < FIRST_PSEUDO_REGISTER) -#endif + && (! SMALL_REGISTER_CLASSES + || (! (GET_CODE (SET_SRC (set)) == REG + && REGNO (SET_SRC (set)) < FIRST_PSEUDO_REGISTER))) /* This test is not redundant; SET_SRC (set) might be a call-clobbered register and the life of REGNO might span a call. */ @@ -1084,6 +1084,9 @@ record_excess_regs (in_this, not_in_this, output) && ! reg_mentioned_p (in_this, not_in_this)) *output = gen_rtx (EXPR_LIST, VOIDmode, in_this, *output); return; + + default: + break; } fmt = GET_RTX_FORMAT (code); @@ -1171,6 +1174,9 @@ reg_in_basic_block_p (insn, reg) case BARRIER: /* It's the end of the basic block, so we lose. */ return 0; + + default: + break; } } @@ -2122,6 +2128,9 @@ replace_call_address (x, reg, addr) abort (); XEXP (x, 0) = addr; return; + + default: + break; } fmt = GET_RTX_FORMAT (code); @@ -2170,6 +2179,9 @@ count_nonfixed_reads (x) case MEM: return ((invariant_p (XEXP (x, 0)) != 1) + count_nonfixed_reads (XEXP (x, 0))); + + default: + break; } value = 0; @@ -2352,6 +2364,8 @@ find_and_verify_loops (f) current_loop = loop_outer_loop[current_loop]; break; + default: + break; } /* Note that this will mark the NOTE_INSN_LOOP_END note as being in the @@ -2891,6 +2905,10 @@ invariant_p (x) /* Don't mess with insns declared volatile. */ if (MEM_VOLATILE_P (x)) return 0; + break; + + default: + break; } fmt = GET_RTX_FORMAT (code); @@ -4381,14 +4399,8 @@ valid_initial_value_p (x, insn, call_seen, loop_start) /* Don't use call-clobbered registers across a call which clobbers it. On some machines, don't use any hard registers at all. */ if (REGNO (x) < FIRST_PSEUDO_REGISTER - && ( -#ifdef SMALL_REGISTER_CLASSES - SMALL_REGISTER_CLASSES -#else - 0 -#endif - || (call_used_regs[REGNO (x)] && call_seen)) - ) + && (SMALL_REGISTER_CLASSES + || (call_used_regs[REGNO (x)] && call_seen))) return 0; /* Don't use registers that have been clobbered before the start of the @@ -4459,8 +4471,11 @@ find_mem_givs (x, insn, not_every_iteration, loop_start, loop_end) v->mem_mode = GET_MODE (x); } - return; } + return; + + default: + break; } /* Recursively scan the subexpressions for other mem refs. */ @@ -5547,6 +5562,9 @@ simplify_giv_expr (x, benefit) tem = gen_rtx (MINUS, mode, tem, v->derive_adjustment); return simplify_giv_expr (tem, benefit); } + + default: + break; } /* Fall through to general case. */ @@ -6163,21 +6181,47 @@ check_dbra_loop (loop_end, insn_count, loop_start) fprintf (loop_dump_stream, "Can reverse loop\n"); /* Now check other conditions: - initial_value must be zero, - final_value % add_val == 0, so that when reversed, the - biv will be zero on the last iteration. + + The increment must be a constant and the comparison code + must be LT. This test can probably be improved since +/- 1 in the constant can be obtained by changing LT to LE and vice versa; this is confusing. */ - if (comparison && bl->initial_value == const0_rtx + if (comparison && GET_CODE (XEXP (comparison, 1)) == CONST_INT /* LE gets turned into LT */ - && GET_CODE (comparison) == LT - && (INTVAL (XEXP (comparison, 1)) - % INTVAL (bl->biv->add_val)) == 0) + && GET_CODE (comparison) == LT) { + HOST_WIDE_INT add_val, comparison_val; + rtx initial_value; + + add_val = INTVAL (bl->biv->add_val); + comparison_val = INTVAL (XEXP (comparison, 1)); + initial_value = bl->initial_value; + + /* Normalize the initial value if it has no other use + except as a counter. This will allow a few more loops + to be reversed. */ + if (no_use_except_counting) + { + comparison_val = comparison_val - INTVAL (bl->initial_value); + initial_value = const0_rtx; + } + + /* If the initial value is not zero, or if the comparison + value is not an exact multiple of the increment, then we + can not reverse this loop. */ + if (initial_value != const0_rtx + || (comparison_val % add_val) != 0) + return 0; + + /* Reset these in case we normalized the initial value + and comparison value above. */ + bl->initial_value = initial_value; + XEXP (comparison, 1) = GEN_INT (comparison_val); + /* Register will always be nonnegative, with value 0 on last iteration if loop reversed */ @@ -6690,6 +6734,9 @@ maybe_eliminate_biv_1 (x, insn, bl, eliminate_p, where) if (v->giv_type == DEST_ADDR && v->location == &XEXP (x, 0)) return 1; break; + + default: + break; } /* See if any subexpression fails elimination. */ @@ -7007,6 +7054,9 @@ get_condition (jump, earliest) if (uconst_val != 0) code = GTU, op1 = GEN_INT (uconst_val - 1); break; + + default: + break; } } |