From: Richard Sandiford Date: Sun, 5 Jul 2015 08:01:48 +0000 (+0000) Subject: target-insns.def (doloop_begin, doloop_end): New targetm instruction patterns. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=89f7b21fb0dfb2b9c7339b44035df76e2265d489;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0fa9747d68..3aa6ee1fddb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-07-05 Richard Sandiford + + * 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 * target-insns.def (clear_cache): New targetm instruction pattern. diff --git a/gcc/hw-doloop.c b/gcc/hw-doloop.c index e00c3d75a8c..2341bc6576d 100644 --- a/gcc/hw-doloop.c +++ b/gcc/hw-doloop.c @@ -52,8 +52,6 @@ along with GCC; see the file COPYING3. If not see #include "hw-doloop.h" #include "dumpfile.h" -#ifdef HAVE_doloop_end - /* Dump information collected in LOOPS. */ static void dump_hwloops (hwloop_info loops) @@ -685,4 +683,3 @@ reorg_loops (bool do_reorder, struct hw_doloop_hooks *hooks) if (dump_file) print_rtl (dump_file, get_insns ()); } -#endif diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index 38303f54595..7da5ab322c7 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -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 cases). */ -#ifdef HAVE_doloop_end - /* Return the loop termination condition for PATTERN or zero if it is not a decrement and branch jump insn. */ @@ -414,7 +412,7 @@ add_test (rtx cond, edge *e, basic_block dest) static void 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 tmp, noloop = NULL_RTX; @@ -562,21 +560,9 @@ doloop_modify (struct loop *loop, struct niter_desc *desc, /* Some targets (eg, C4x) need to initialize special looping registers. */ -#ifdef HAVE_doloop_begin - { - rtx init; - - 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 + if (targetm.have_doloop_begin ()) + if (rtx_insn *seq = targetm.gen_doloop_begin (counter_reg, doloop_seq)) + emit_insn_after (seq, BB_END (loop_preheader_edge (loop)->src)); /* Insert the new low-overhead looping insn. */ emit_jump_insn_after (doloop_seq, BB_END (loop_end)); @@ -612,7 +598,7 @@ static bool doloop_optimize (struct loop *loop) { machine_mode mode; - rtx doloop_seq, doloop_pat, doloop_reg; + rtx doloop_reg; rtx count; widest_int iterations, iterations_max; rtx_code_label *start_label; @@ -695,7 +681,7 @@ doloop_optimize (struct loop *loop) count = copy_rtx (desc->niter_expr); start_label = block_label (desc->in_edge->dest); 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_max @@ -713,7 +699,7 @@ doloop_optimize (struct loop *loop) else count = lowpart_subreg (word_mode, count, 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) { @@ -724,21 +710,12 @@ doloop_optimize (struct loop *loop) } /* If multiple instructions were created, the last must be the - jump instruction. Also, a raw define_insn may yield a plain - pattern. */ - doloop_pat = doloop_seq; - if (INSN_P (doloop_pat)) - { - rtx_insn *doloop_insn = as_a (doloop_pat); - 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))) + jump instruction. */ + rtx_insn *doloop_insn = doloop_seq; + while (NEXT_INSN (doloop_insn) != NULL_RTX) + doloop_insn = NEXT_INSN (doloop_insn); + if (!JUMP_P (doloop_insn) + || !(condition = doloop_condition_get (doloop_insn))) { if (dump_file) fprintf (dump_file, "Doloop: Unrecognizable doloop pattern!\n"); @@ -767,5 +744,3 @@ doloop_optimize_loops (void) verify_loop_structure (); #endif } -#endif /* HAVE_doloop_end */ - diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 5959145b969..85957770b3b 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-loop-niter.h" #include "loop-unroll.h" #include "tree-scalar-evolution.h" +#include "target.h" /* Apply FLAGS to the loop state. */ @@ -377,10 +378,8 @@ pass_loop2::gate (function *fun) && (flag_move_loop_invariants || flag_unswitch_loops || flag_unroll_loops -#ifdef HAVE_doloop_end - || (flag_branch_on_count_reg && HAVE_doloop_end) -#endif - )) + || (flag_branch_on_count_reg + && targetm.have_doloop_end ()))) return true; else { @@ -644,20 +643,14 @@ public: bool pass_rtl_doloop::gate (function *) { -#ifdef HAVE_doloop_end - return (flag_branch_on_count_reg && HAVE_doloop_end); -#else - return false; -#endif + return (flag_branch_on_count_reg && targetm.have_doloop_end ()); } 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) doloop_optimize_loops (); -#endif return 0; } diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index 60b39f81d18..193fb07aefd 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -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 do-loop pattern is not of the form we expect. */ 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_insn *insn, *first_insn_not_to_check; if (!JUMP_P (tail)) return NULL_RTX; + if (!targetm.code_for_doloop_end) + return NULL_RTX; + /* TODO: Free SMS's dependence on doloop_condition_get. */ condition = doloop_condition_get (tail); if (! condition) @@ -406,9 +408,6 @@ doloop_register_get (rtx_insn *head ATTRIBUTE_UNUSED, rtx_insn *tail ATTRIBUTE_U } return reg; -#else - return NULL_RTX; -#endif } /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so diff --git a/gcc/target-insns.def b/gcc/target-insns.def index 2a9b23bafe6..b5b249211e7 100644 --- a/gcc/target-insns.def +++ b/gcc/target-insns.def @@ -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 (check_stack, (rtx x0)) 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 (exception_receiver, (void)) DEF_TARGET_INSN (jump, (rtx x0))