aboutsummaryrefslogtreecommitdiff
path: root/gcc/loop.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2000-07-30 16:58:03 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-07-30 16:58:03 -0700
commit5527bf14a5a334ea3509a3dd927b070bc92fb363 (patch)
treef605097b66b55020e4f570dfecd70e09c3318697 /gcc/loop.c
parent1cf0acdd19587bcfc635db6688b6a7143f0cadfe (diff)
downloadgcc-5527bf14a5a334ea3509a3dd927b070bc92fb363.zip
gcc-5527bf14a5a334ea3509a3dd927b070bc92fb363.tar.gz
gcc-5527bf14a5a334ea3509a3dd927b070bc92fb363.tar.bz2
Makefile.in (OBJS): Add doloop.o.
* Makefile.in (OBJS): Add doloop.o. * doloop.c: New file. * final.c (insn_current_reference_address): Return 0 before final. * flags.h (flag_branch_on_count_reg): Fix typos in commentary. * jump.c (any_uncondjump_p): Likewise. * loop.c (indirect_jump_in_function): Make static. (strength_reduce): Call doloop_optimize. (insert_bct, instrument_loop_bct): Remove. * loop.h (doloop_optimize): Prototype. * recog.c (split_all_insns): Split all INSN_P. * toplev.c (flag_branch_on_count_reg): Default on. * config/c4x/c4x.c (c4x_optimization_options): Don't set flag_branch_on_count_reg. * config/i386/i386.c (override_options): Likewise. * config/rs6000/rs6000.c (optimization_options): Likewise. * config/i386/i386.md (decrement_and_branch_on_count): Remove. (doloop_end): New. (dbra_ge): Remove, as well as all it's splitters. * config/rs6000/rs6000.md (decrement_and_branch_on_count): Remove. (doloop_end): New. * config/ia64/ia64-protos.h (ar_lc_reg_operand): Declare. (ia64_register_move_cost): Declare. * config/ia64/ia64.c (ar_lc_reg_operand): New. (struct ia64_frame_info): Add ar_size. (ia64_compute_frame_size): Set it. (save_restore_insns): Save and restore ar.lc. (ia64_register_move_cost): New, moved from header file. Handle application registers. (REG_AR_PFS, REG_AR_EC): Remove. Replace with AR_*_REGNUM numbers. (emit_insn_group_barriers): Special case doloop_end_internal. (ia64_epilogue_uses): Mark ar.lc live at end. * config/ia64/ia64.h (AR_CCV_REGNUM, AR_LC_REGNUM): New registers. (AR_EC_REGNUM, AR_PFS_REGNUM): New registers. (FIRST_PSEUDO_REGISTER): Make room. (AR_M_REGNO_P, AR_I_REGNO_P, AR_REGNO_P): New. (FIXED_REGISTERS, CALL_USED_REGISTERS): Update. (REG_ALLOC_ORDER): Update. (HARD_REGNO_MODE_OK): Update. (REGISTER_NAMES): Update. (enum reg_class): Add AR_M_REGS and AR_I_REGS. (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Update. (REGNO_REG_CLASS): Update. (LEGITIMATE_ADDRESS_DISP): Displacement range is 9 bits, not 10. (REGISTER_MOVE_COST): Move out of line. (PREDICATE_CODES): Update. * config/ia64/ia64.md (movdi patterns): Handle ar register classes. (addsi3_plus1_alt, adddi3_plus1_alt): New. (shladd_elim splitter): Allow constants in the predicate. (doloop_end, doloop_end_internal): New. From-SVN: r35358
Diffstat (limited to 'gcc/loop.c')
-rw-r--r--gcc/loop.c306
1 files changed, 6 insertions, 300 deletions
diff --git a/gcc/loop.c b/gcc/loop.c
index 2fb4855..f812b2e 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -327,16 +327,8 @@ typedef struct rtx_pair {
&& INSN_LUID (INSN) >= INSN_LUID (START) \
&& INSN_LUID (INSN) <= INSN_LUID (END))
-#ifdef HAVE_decrement_and_branch_on_count
-/* Test whether BCT applicable and safe. */
-static void insert_bct PARAMS ((struct loop *));
-
-/* Auxiliary function that inserts the BCT pattern into the loop. */
-static void instrument_loop_bct PARAMS ((rtx, rtx, rtx));
-#endif /* HAVE_decrement_and_branch_on_count */
-
/* Indirect_jump_in_function is computed once per function. */
-int indirect_jump_in_function = 0;
+static int indirect_jump_in_function;
static int indirect_jump_in_function_p PARAMS ((rtx));
static int compute_luids PARAMS ((rtx, rtx, int));
@@ -5025,12 +5017,10 @@ strength_reduce (loop, insn_count, flags)
&& unrolled_insn_copies <= insn_count))
unroll_loop (loop, insn_count, end_insert_before, 1);
-#ifdef HAVE_decrement_and_branch_on_count
- /* Instrument the loop with BCT insn. */
- if (HAVE_decrement_and_branch_on_count && (flags & LOOP_BCT)
- && flag_branch_on_count_reg)
- insert_bct (loop);
-#endif /* HAVE_decrement_and_branch_on_count */
+#ifdef HAVE_doloop_end
+ if (HAVE_doloop_end && (flags & LOOP_BCT) && flag_branch_on_count_reg)
+ doloop_optimize (loop);
+#endif /* HAVE_doloop_end */
if (loop_dump_stream)
fprintf (loop_dump_stream, "\n");
@@ -9187,6 +9177,7 @@ canonicalize_condition (insn, cond, reverse, earliest, want_reg)
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
}
+
/* Given a jump insn JUMP, return the condition that will cause it to branch
to its JUMP_LABEL. If the condition cannot be understood, or is an
inequality floating-point comparison which needs to be reversed, 0 will
@@ -9242,291 +9233,6 @@ get_condition_for_loop (loop, x)
XEXP (comparison, 1), XEXP (comparison, 0));
}
-#ifdef HAVE_decrement_and_branch_on_count
-/* Instrument loop for insertion of bct instruction. We distinguish between
- loops with compile-time bounds and those with run-time bounds.
- Information from loop_iterations() is used to compute compile-time bounds.
- Run-time bounds should use loop preconditioning, but currently ignored.
- */
-
-static void
-insert_bct (loop)
- struct loop *loop;
-{
- unsigned HOST_WIDE_INT n_iterations;
- rtx loop_start = loop->start;
- rtx loop_end = loop->end;
- struct loop_info *loop_info = LOOP_INFO (loop);
- int loop_num = loop->num;
-
-#if 0
- int increment_direction, compare_direction;
- /* If the loop condition is <= or >=, the number of iteration
- is 1 more than the range of the bounds of the loop. */
- int add_iteration = 0;
- enum machine_mode loop_var_mode = word_mode;
-#endif
-
- /* It's impossible to instrument a competely unrolled loop. */
- if (loop_info->unroll_number == loop_info->n_iterations)
- return;
-
- /* Make sure that the count register is not in use. */
- if (loop_info->used_count_register)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT instrumentation failed: count register already in use\n",
- loop_num);
- return;
- }
-
- /* Make sure that the function has no indirect jumps. */
- if (indirect_jump_in_function)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT instrumentation failed: indirect jump in function\n",
- loop_num);
- return;
- }
-
- /* Make sure that the last loop insn is a conditional jump. */
- if (GET_CODE (PREV_INSN (loop_end)) != JUMP_INSN
- || ! onlyjump_p (PREV_INSN (loop_end))
- || ! any_condjump_p (PREV_INSN (loop_end)))
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT instrumentation failed: invalid jump at loop end\n",
- loop_num);
- return;
- }
-
- /* Make sure that the loop does not contain a function call
- (the count register might be altered by the called function). */
- if (loop_info->has_call)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT instrumentation failed: function call in loop\n",
- loop_num);
- return;
- }
-
- /* Make sure that the loop does not jump via a table.
- (the count register might be used to perform the branch on table). */
- if (loop_info->has_tablejump)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT instrumentation failed: computed branch in the loop\n",
- loop_num);
- return;
- }
-
- /* Account for loop unrolling in instrumented iteration count. */
- if (loop_info->unroll_number > 1)
- n_iterations = loop_info->n_iterations / loop_info->unroll_number;
- else
- n_iterations = loop_info->n_iterations;
-
- if (n_iterations != 0 && n_iterations < 3)
- {
- /* Allow an enclosing outer loop to benefit if possible. */
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: Too few iterations to benefit from BCT optimization\n",
- loop_num);
- return;
- }
-
- /* Try to instrument the loop. */
-
- /* Handle the simpler case, where the bounds are known at compile time. */
- if (n_iterations > 0)
- {
- struct loop *outer_loop;
- struct loop_info *outer_loop_info;
-
- /* Mark all enclosing loops that they cannot use count register. */
- for (outer_loop = loop; outer_loop; outer_loop = outer_loop->outer)
- {
- outer_loop_info = LOOP_INFO (outer_loop);
- outer_loop_info->used_count_register = 1;
- }
- instrument_loop_bct (loop_start, loop_end, GEN_INT (n_iterations));
- return;
- }
-
- /* Handle the more complex case, that the bounds are NOT known
- at compile time. In this case we generate run_time calculation
- of the number of iterations. */
-
- if (loop_info->iteration_var == 0)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT Runtime Instrumentation failed: no loop iteration variable found\n",
- loop_num);
- return;
- }
-
- if (GET_MODE_CLASS (GET_MODE (loop_info->iteration_var)) != MODE_INT
- || GET_MODE_SIZE (GET_MODE (loop_info->iteration_var)) != UNITS_PER_WORD)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT Runtime Instrumentation failed: loop variable not integer\n",
- loop_num);
- return;
- }
-
- /* With runtime bounds, if the compare is of the form '!=' we give up */
- if (loop_info->comparison_code == NE)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct %d: BCT Runtime Instrumentation failed: runtime bounds with != comparison\n",
- loop_num);
- return;
- }
-/* Use common loop preconditioning code instead. */
-#if 0
- else
- {
- /* We rely on the existence of run-time guard to ensure that the
- loop executes at least once. */
- rtx sequence;
- rtx iterations_num_reg;
-
- unsigned HOST_WIDE_INT increment_value_abs
- = INTVAL (increment) * increment_direction;
-
- /* make sure that the increment is a power of two, otherwise (an
- expensive) divide is needed. */
- if (exact_log2 (increment_value_abs) == -1)
- {
- if (loop_dump_stream)
- fprintf (loop_dump_stream,
- "insert_bct: not instrumenting BCT because the increment is not power of 2\n");
- return;
- }
-
- /* compute the number of iterations */
- start_sequence ();
- {
- rtx temp_reg;
-
- /* Again, the number of iterations is calculated by:
- ;
- ; compare-val - initial-val + (increment -1) + additional-iteration
- ; num_iterations = -----------------------------------------------------------------
- ; increment
- */
- /* ??? Do we have to call copy_rtx here before passing rtx to
- expand_binop? */
- if (compare_direction > 0)
- {
- /* <, <= :the loop variable is increasing */
- temp_reg = expand_binop (loop_var_mode, sub_optab,
- comparison_value, initial_value,
- NULL_RTX, 0, OPTAB_LIB_WIDEN);
- }
- else
- {
- temp_reg = expand_binop (loop_var_mode, sub_optab,
- initial_value, comparison_value,
- NULL_RTX, 0, OPTAB_LIB_WIDEN);
- }
-
- if (increment_value_abs - 1 + add_iteration != 0)
- temp_reg = expand_binop (loop_var_mode, add_optab, temp_reg,
- GEN_INT (increment_value_abs - 1
- + add_iteration),
- NULL_RTX, 0, OPTAB_LIB_WIDEN);
-
- if (increment_value_abs != 1)
- iterations_num_reg = expand_binop (loop_var_mode, asr_optab,
- temp_reg,
- GEN_INT (exact_log2 (increment_value_abs)),
- NULL_RTX, 0, OPTAB_LIB_WIDEN);
- else
- iterations_num_reg = temp_reg;
- }
- sequence = gen_sequence ();
- end_sequence ();
- emit_insn_before (sequence, loop_start);
- instrument_loop_bct (loop_start, loop_end, iterations_num_reg);
- }
-
- return;
-#endif /* Complex case */
-}
-
-/* Instrument loop by inserting a bct in it as follows:
- 1. A new counter register is created.
- 2. In the head of the loop the new variable is initialized to the value
- passed in the loop_num_iterations parameter.
- 3. At the end of the loop, comparison of the register with 0 is generated.
- The created comparison follows the pattern defined for the
- decrement_and_branch_on_count insn, so this insn will be generated.
- 4. The branch on the old variable are deleted. The compare must remain
- because it might be used elsewhere. If the loop-variable or condition
- register are used elsewhere, they will be eliminated by flow. */
-
-static void
-instrument_loop_bct (loop_start, loop_end, loop_num_iterations)
- rtx loop_start, loop_end;
- rtx loop_num_iterations;
-{
- rtx counter_reg;
- rtx start_label;
- rtx sequence;
-
- if (HAVE_decrement_and_branch_on_count)
- {
- if (loop_dump_stream)
- {
- fputs ("instrument_bct: Inserting BCT (", loop_dump_stream);
- if (GET_CODE (loop_num_iterations) == CONST_INT)
- fprintf (loop_dump_stream, HOST_WIDE_INT_PRINT_DEC,
- INTVAL (loop_num_iterations));
- else
- fputs ("runtime", loop_dump_stream);
- fputs (" iterations)", loop_dump_stream);
- }
-
- /* Discard original jump to continue loop. Original compare result
- may still be live, so it cannot be discarded explicitly. */
- delete_insn (PREV_INSN (loop_end));
-
- /* Insert the label which will delimit the start of the loop. */
- start_label = gen_label_rtx ();
- emit_label_after (start_label, loop_start);
-
- /* Insert initialization of the count register into the loop header. */
- start_sequence ();
- counter_reg = gen_reg_rtx (word_mode);
- emit_insn (gen_move_insn (counter_reg, loop_num_iterations));
- sequence = gen_sequence ();
- end_sequence ();
- emit_insn_before (sequence, loop_start);
-
- /* Insert new comparison on the count register instead of the
- old one, generating the needed BCT pattern (that will be
- later recognized by assembly generation phase). */
- sequence = emit_jump_insn_before (
- gen_decrement_and_branch_on_count (counter_reg, start_label),
- loop_end);
-
- if (GET_CODE (sequence) != JUMP_INSN)
- abort ();
- JUMP_LABEL (sequence) = start_label;
- LABEL_NUSES (start_label)++;
- }
-}
-#endif /* HAVE_decrement_and_branch_on_count */
/* Scan the function and determine whether it has indirect (computed) jumps.