Commit 89f7b21f by Richard Sandiford Committed by Richard Sandiford

target-insns.def (doloop_begin, doloop_end): New targetm instruction patterns.

gcc/
	* target-insns.def (doloop_begin, doloop_end): New targetm
	instruction patterns.
	* loop-init.c: Include target.h.
	(pass_loop2::gate): Use the new targetm patterns instead of
	HAVE_*/gen_* interface.
	(pass_rtl_doloop::gate): Likewise.
	(pass_rtl_doloop::execute): Remove preprocessor condition.
	* hw-doloop.c: Build unconditionally.
	* loop-doloop.c: Likewise.
	(doloop_optimize): Use the new targetm patterns instead of
	HAVE_*/gen_* interface.
	(doloop_modify): Likewise. Change type of doloop_seq to rtx_insn *.
	* modulo-sched.c (doloop_register_get): Likewise.

From-SVN: r225431
parent f2cf13bd
2015-07-05 Richard Sandiford <richard.sandiford@arm.com> 2015-07-05 Richard Sandiford <richard.sandiford@arm.com>
* target-insns.def (doloop_begin, doloop_end): New targetm
instruction patterns.
* loop-init.c: Include target.h.
(pass_loop2::gate): Use the new targetm patterns instead of
HAVE_*/gen_* interface.
(pass_rtl_doloop::gate): Likewise.
(pass_rtl_doloop::execute): Remove preprocessor condition.
* hw-doloop.c: Build unconditionally.
* loop-doloop.c: Likewise.
(doloop_optimize): Use the new targetm patterns instead of
HAVE_*/gen_* interface.
(doloop_modify): Likewise. Change type of doloop_seq to rtx_insn *.
* modulo-sched.c (doloop_register_get): Likewise.
2015-07-05 Richard Sandiford <richard.sandiford@arm.com>
* target-insns.def (clear_cache): New targetm instruction pattern. * target-insns.def (clear_cache): New targetm instruction pattern.
* builtins.c (expand_builtin___clear_cache): Use it instead of * builtins.c (expand_builtin___clear_cache): Use it instead of
HAVE_*/gen_* interface. HAVE_*/gen_* interface.
......
...@@ -52,8 +52,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -52,8 +52,6 @@ along with GCC; see the file COPYING3. If not see
#include "hw-doloop.h" #include "hw-doloop.h"
#include "dumpfile.h" #include "dumpfile.h"
#ifdef HAVE_doloop_end
/* Dump information collected in LOOPS. */ /* Dump information collected in LOOPS. */
static void static void
dump_hwloops (hwloop_info loops) dump_hwloops (hwloop_info loops)
...@@ -685,4 +683,3 @@ reorg_loops (bool do_reorder, struct hw_doloop_hooks *hooks) ...@@ -685,4 +683,3 @@ reorg_loops (bool do_reorder, struct hw_doloop_hooks *hooks)
if (dump_file) if (dump_file)
print_rtl (dump_file, get_insns ()); print_rtl (dump_file, get_insns ());
} }
#endif
...@@ -80,8 +80,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -80,8 +80,6 @@ along with GCC; see the file COPYING3. If not see
register cannot be used for anything else but doloop -- ??? detect these register cannot be used for anything else but doloop -- ??? detect these
cases). */ cases). */
#ifdef HAVE_doloop_end
/* Return the loop termination condition for PATTERN or zero /* Return the loop termination condition for PATTERN or zero
if it is not a decrement and branch jump insn. */ if it is not a decrement and branch jump insn. */
...@@ -414,7 +412,7 @@ add_test (rtx cond, edge *e, basic_block dest) ...@@ -414,7 +412,7 @@ add_test (rtx cond, edge *e, basic_block dest)
static void static void
doloop_modify (struct loop *loop, struct niter_desc *desc, doloop_modify (struct loop *loop, struct niter_desc *desc,
rtx doloop_seq, rtx condition, rtx count) rtx_insn *doloop_seq, rtx condition, rtx count)
{ {
rtx counter_reg; rtx counter_reg;
rtx tmp, noloop = NULL_RTX; rtx tmp, noloop = NULL_RTX;
...@@ -562,21 +560,9 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, ...@@ -562,21 +560,9 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
/* Some targets (eg, C4x) need to initialize special looping /* Some targets (eg, C4x) need to initialize special looping
registers. */ registers. */
#ifdef HAVE_doloop_begin if (targetm.have_doloop_begin ())
{ if (rtx_insn *seq = targetm.gen_doloop_begin (counter_reg, doloop_seq))
rtx init; emit_insn_after (seq, BB_END (loop_preheader_edge (loop)->src));
init = gen_doloop_begin (counter_reg, doloop_seq);
if (init)
{
start_sequence ();
emit_insn (init);
sequence = get_insns ();
end_sequence ();
emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src));
}
}
#endif
/* Insert the new low-overhead looping insn. */ /* Insert the new low-overhead looping insn. */
emit_jump_insn_after (doloop_seq, BB_END (loop_end)); emit_jump_insn_after (doloop_seq, BB_END (loop_end));
...@@ -612,7 +598,7 @@ static bool ...@@ -612,7 +598,7 @@ static bool
doloop_optimize (struct loop *loop) doloop_optimize (struct loop *loop)
{ {
machine_mode mode; machine_mode mode;
rtx doloop_seq, doloop_pat, doloop_reg; rtx doloop_reg;
rtx count; rtx count;
widest_int iterations, iterations_max; widest_int iterations, iterations_max;
rtx_code_label *start_label; rtx_code_label *start_label;
...@@ -695,7 +681,7 @@ doloop_optimize (struct loop *loop) ...@@ -695,7 +681,7 @@ doloop_optimize (struct loop *loop)
count = copy_rtx (desc->niter_expr); count = copy_rtx (desc->niter_expr);
start_label = block_label (desc->in_edge->dest); start_label = block_label (desc->in_edge->dest);
doloop_reg = gen_reg_rtx (mode); doloop_reg = gen_reg_rtx (mode);
doloop_seq = gen_doloop_end (doloop_reg, start_label); rtx_insn *doloop_seq = targetm.gen_doloop_end (doloop_reg, start_label);
word_mode_size = GET_MODE_PRECISION (word_mode); word_mode_size = GET_MODE_PRECISION (word_mode);
word_mode_max word_mode_max
...@@ -713,7 +699,7 @@ doloop_optimize (struct loop *loop) ...@@ -713,7 +699,7 @@ doloop_optimize (struct loop *loop)
else else
count = lowpart_subreg (word_mode, count, mode); count = lowpart_subreg (word_mode, count, mode);
PUT_MODE (doloop_reg, word_mode); PUT_MODE (doloop_reg, word_mode);
doloop_seq = gen_doloop_end (doloop_reg, start_label); doloop_seq = targetm.gen_doloop_end (doloop_reg, start_label);
} }
if (! doloop_seq) if (! doloop_seq)
{ {
...@@ -724,21 +710,12 @@ doloop_optimize (struct loop *loop) ...@@ -724,21 +710,12 @@ doloop_optimize (struct loop *loop)
} }
/* If multiple instructions were created, the last must be the /* If multiple instructions were created, the last must be the
jump instruction. Also, a raw define_insn may yield a plain jump instruction. */
pattern. */ rtx_insn *doloop_insn = doloop_seq;
doloop_pat = doloop_seq; while (NEXT_INSN (doloop_insn) != NULL_RTX)
if (INSN_P (doloop_pat)) doloop_insn = NEXT_INSN (doloop_insn);
{ if (!JUMP_P (doloop_insn)
rtx_insn *doloop_insn = as_a <rtx_insn *> (doloop_pat); || !(condition = doloop_condition_get (doloop_insn)))
while (NEXT_INSN (doloop_insn) != NULL_RTX)
doloop_insn = NEXT_INSN (doloop_insn);
if (!JUMP_P (doloop_insn))
doloop_insn = NULL;
doloop_pat = doloop_insn;
}
if (! doloop_pat
|| ! (condition = doloop_condition_get (doloop_pat)))
{ {
if (dump_file) if (dump_file)
fprintf (dump_file, "Doloop: Unrecognizable doloop pattern!\n"); fprintf (dump_file, "Doloop: Unrecognizable doloop pattern!\n");
...@@ -767,5 +744,3 @@ doloop_optimize_loops (void) ...@@ -767,5 +744,3 @@ doloop_optimize_loops (void)
verify_loop_structure (); verify_loop_structure ();
#endif #endif
} }
#endif /* HAVE_doloop_end */
...@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-niter.h" #include "tree-ssa-loop-niter.h"
#include "loop-unroll.h" #include "loop-unroll.h"
#include "tree-scalar-evolution.h" #include "tree-scalar-evolution.h"
#include "target.h"
/* Apply FLAGS to the loop state. */ /* Apply FLAGS to the loop state. */
...@@ -377,10 +378,8 @@ pass_loop2::gate (function *fun) ...@@ -377,10 +378,8 @@ pass_loop2::gate (function *fun)
&& (flag_move_loop_invariants && (flag_move_loop_invariants
|| flag_unswitch_loops || flag_unswitch_loops
|| flag_unroll_loops || flag_unroll_loops
#ifdef HAVE_doloop_end || (flag_branch_on_count_reg
|| (flag_branch_on_count_reg && HAVE_doloop_end) && targetm.have_doloop_end ())))
#endif
))
return true; return true;
else else
{ {
...@@ -644,20 +643,14 @@ public: ...@@ -644,20 +643,14 @@ public:
bool bool
pass_rtl_doloop::gate (function *) pass_rtl_doloop::gate (function *)
{ {
#ifdef HAVE_doloop_end return (flag_branch_on_count_reg && targetm.have_doloop_end ());
return (flag_branch_on_count_reg && HAVE_doloop_end);
#else
return false;
#endif
} }
unsigned int unsigned int
pass_rtl_doloop::execute (function *fun ATTRIBUTE_UNUSED) pass_rtl_doloop::execute (function *fun)
{ {
#ifdef HAVE_doloop_end
if (number_of_loops (fun) > 1) if (number_of_loops (fun) > 1)
doloop_optimize_loops (); doloop_optimize_loops ();
#endif
return 0; return 0;
} }
......
...@@ -362,15 +362,17 @@ ps_num_consecutive_stages (partial_schedule_ptr ps, int id) ...@@ -362,15 +362,17 @@ ps_num_consecutive_stages (partial_schedule_ptr ps, int id)
more than one occurrence in the loop besides the control part or the more than one occurrence in the loop besides the control part or the
do-loop pattern is not of the form we expect. */ do-loop pattern is not of the form we expect. */
static rtx static rtx
doloop_register_get (rtx_insn *head ATTRIBUTE_UNUSED, rtx_insn *tail ATTRIBUTE_UNUSED) doloop_register_get (rtx_insn *head, rtx_insn *tail)
{ {
#ifdef HAVE_doloop_end
rtx reg, condition; rtx reg, condition;
rtx_insn *insn, *first_insn_not_to_check; rtx_insn *insn, *first_insn_not_to_check;
if (!JUMP_P (tail)) if (!JUMP_P (tail))
return NULL_RTX; return NULL_RTX;
if (!targetm.code_for_doloop_end)
return NULL_RTX;
/* TODO: Free SMS's dependence on doloop_condition_get. */ /* TODO: Free SMS's dependence on doloop_condition_get. */
condition = doloop_condition_get (tail); condition = doloop_condition_get (tail);
if (! condition) if (! condition)
...@@ -406,9 +408,6 @@ doloop_register_get (rtx_insn *head ATTRIBUTE_UNUSED, rtx_insn *tail ATTRIBUTE_U ...@@ -406,9 +408,6 @@ doloop_register_get (rtx_insn *head ATTRIBUTE_UNUSED, rtx_insn *tail ATTRIBUTE_U
} }
return reg; return reg;
#else
return NULL_RTX;
#endif
} }
/* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
......
...@@ -38,6 +38,8 @@ DEF_TARGET_INSN (canonicalize_funcptr_for_compare, (rtx x0, rtx x1)) ...@@ -38,6 +38,8 @@ DEF_TARGET_INSN (canonicalize_funcptr_for_compare, (rtx x0, rtx x1))
DEF_TARGET_INSN (casesi, (rtx x0, rtx x1, rtx x2, rtx x3, rtx x4)) DEF_TARGET_INSN (casesi, (rtx x0, rtx x1, rtx x2, rtx x3, rtx x4))
DEF_TARGET_INSN (check_stack, (rtx x0)) DEF_TARGET_INSN (check_stack, (rtx x0))
DEF_TARGET_INSN (clear_cache, (rtx x0, rtx x1)) DEF_TARGET_INSN (clear_cache, (rtx x0, rtx x1))
DEF_TARGET_INSN (doloop_begin, (rtx x0, rtx x1))
DEF_TARGET_INSN (doloop_end, (rtx x0, rtx x1))
DEF_TARGET_INSN (epilogue, (void)) DEF_TARGET_INSN (epilogue, (void))
DEF_TARGET_INSN (exception_receiver, (void)) DEF_TARGET_INSN (exception_receiver, (void))
DEF_TARGET_INSN (jump, (rtx x0)) DEF_TARGET_INSN (jump, (rtx x0))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment