From a71a498df01ba32349bed4e72631433be1ff4a2a Mon Sep 17 00:00:00 2001 From: Adrian Straetling Date: Wed, 25 May 2005 11:52:13 +0000 Subject: [PATCH] loop-doloop.c: Include "target.h". 2005-05-25 Adrian Straetling * loop-doloop.c: Include "target.h". (doloop_valid_p): Move tests to function in targhooks.c. * target.h (struct gcc_target): New target hook "insn_valid_within_doloop". * target-def.h: Define default value for "insn_valid_within_doloop". (TARGET_INITIALIZER): Insert new target hook into initializer. * targhooks.c (default_insn_valid_within_doloop): New function. * targhooks.h (default_insn_valid_within_doloop): Declare. * hooks.c (hook_bool_rtx_true): New function. * hooks.h (hook_bool_rtx_true): Declare. * doc/tm.texi: Add documentation for new target hook. From-SVN: r100143 --- gcc/ChangeLog | 14 ++++++++++++++ gcc/doc/tm.texi | 11 +++++++++++ gcc/hooks.c | 6 ++++++ gcc/hooks.h | 1 + gcc/loop-doloop.c | 26 +++++++------------------- gcc/target-def.h | 5 +++++ gcc/target.h | 3 +++ gcc/targhooks.c | 30 ++++++++++++++++++++++++++++++ gcc/targhooks.h | 2 ++ 9 files changed, 79 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d6aa061f637..5acda30aa5f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-05-25 Adrian Straetling + + * loop-doloop.c: Include "target.h". + (doloop_valid_p): Move tests to function in targhooks.c. + * target.h (struct gcc_target): New target hook + "insn_valid_within_doloop". + * target-def.h: Define default value for "insn_valid_within_doloop". + (TARGET_INITIALIZER): Insert new target hook into initializer. + * targhooks.c (default_insn_valid_within_doloop): New function. + * targhooks.h (default_insn_valid_within_doloop): Declare. + * hooks.c (hook_bool_rtx_true): New function. + * hooks.h (hook_bool_rtx_true): Declare. + * doc/tm.texi: Add documentation for new target hook. + 2005-05-25 Eric Botcazou PR target/21412 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 9e755aaf8af..e541a20d2a9 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -9511,6 +9511,17 @@ simplified expression for the call's result. If @var{ignore} is true the value will be ignored. @end deftypefn +@deftypefn {Target Hook} bool TARGET_INSN_VALID_WITHIN_DOLOOP (rtx @var{insn}) + +Take an instruction in @var{insn} and return true if it is valid within a +low-overhead loop. + +Many targets use special registers for low-overhead looping. This function +should return false for any instruction that clobbers these. +By default, the RTL loop optimizer does not use a present doloop pattern for +loops containing function calls or brach on table instructions. +@end deftypefn + @defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2}) Take a branch insn in @var{branch1} and another in @var{branch2}. diff --git a/gcc/hooks.c b/gcc/hooks.c index 6e6e7c70321..30ba6d100da 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -191,6 +191,12 @@ hook_bool_rtx_false (rtx a ATTRIBUTE_UNUSED) return false; } +bool +hook_bool_rtx_true (rtx a ATTRIBUTE_UNUSED) +{ + return true; +} + bool hook_bool_uintp_uintp_false (unsigned int *a ATTRIBUTE_UNUSED, unsigned int *b ATTRIBUTE_UNUSED) diff --git a/gcc/hooks.h b/gcc/hooks.h index b799a8c0709..b78f4970549 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -35,6 +35,7 @@ extern bool hook_bool_tree_hwi_hwi_tree_false (tree, HOST_WIDE_INT, HOST_WIDE_IN extern bool hook_bool_tree_hwi_hwi_tree_true (tree, HOST_WIDE_INT, HOST_WIDE_INT, tree); extern bool hook_bool_rtx_false (rtx); +extern bool hook_bool_rtx_true (rtx); extern bool hook_bool_uintp_uintp_false (unsigned int *, unsigned int *); extern bool hook_bool_rtx_int_int_intp_false (rtx, int, int, int *); extern bool hook_bool_constcharptr_size_t_false (const char *, size_t); diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c index c6ef37e84d6..4a2bb8774ee 100644 --- a/gcc/loop-doloop.c +++ b/gcc/loop-doloop.c @@ -33,6 +33,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "cfgloop.h" #include "output.h" #include "params.h" +#include "target.h" /* This module is used to modify loops with a determinable number of iterations to use special low-overhead looping instructions. @@ -187,27 +188,14 @@ doloop_valid_p (struct loop *loop, struct niter_desc *desc) insn != NEXT_INSN (BB_END (bb)); insn = NEXT_INSN (insn)) { - /* A called function may clobber any special registers required for - low-overhead looping. */ - if (CALL_P (insn)) - { - if (dump_file) - fprintf (dump_file, "Doloop: Function call in loop.\n"); + /* Different targets have different necessities for low-overhead + looping. Call the back end for each instruction within the loop + to let it decide whether the insn is valid. */ + if (!targetm.insn_valid_within_doloop (insn)) + { result = false; goto cleanup; - } - - /* Some targets (eg, PPC) use the count register for branch on table - instructions. ??? This should be a target specific check. */ - if (JUMP_P (insn) - && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC - || GET_CODE (PATTERN (insn)) == ADDR_VEC)) - { - if (dump_file) - fprintf (dump_file, "Doloop: Computed branch in the loop.\n"); - result = false; - goto cleanup; - } + } } } result = true; diff --git a/gcc/target-def.h b/gcc/target-def.h index 27e851123f2..49e25a168ba 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -137,6 +137,10 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TARGET_HAVE_NAMED_SECTIONS false #endif +#ifndef TARGET_INSN_VALID_WITHIN_DOLOOP +#define TARGET_INSN_VALID_WITHIN_DOLOOP default_insn_valid_within_doloop +#endif + #ifndef TARGET_HAVE_TLS #define TARGET_HAVE_TLS false #endif @@ -553,6 +557,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. TARGET_DWARF_CALLING_CONVENTION, \ TARGET_DWARF_HANDLE_FRAME_UNSPEC, \ TARGET_STDARG_OPTIMIZE_HOOK, \ + TARGET_INSN_VALID_WITHIN_DOLOOP, \ TARGET_CALLS, \ TARGET_CXX, \ TARGET_HAVE_NAMED_SECTIONS, \ diff --git a/gcc/target.h b/gcc/target.h index f141f04095f..38f09b01e05 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -520,6 +520,9 @@ struct gcc_target to be checked for va_list references. */ bool (*stdarg_optimize_hook) (struct stdarg_info *ai, tree lhs, tree rhs); + /* Returns true if target supports the insn within a doloop block. */ + bool (*insn_valid_within_doloop) (rtx); + /* Functions relating to calls - argument passing, returns, etc. */ struct calls { bool (*promote_function_args) (tree fntype); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 2bf11a431eb..1f8b5b76ee7 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -262,6 +262,36 @@ default_scalar_mode_supported_p (enum machine_mode mode) } } +/* TRUE if INSN insn is valid within a low-overhead loop. + + This function checks wheter a given INSN is valid within a low-overhead + loop. A called function may clobber any special registers required for + low-overhead looping. Additionally, some targets (eg, PPC) use the count + register for branch on table instructions. We reject the doloop pattern in + these cases. */ + +bool +default_insn_valid_within_doloop (rtx insn) +{ + if (CALL_P (insn)) + { + if (dump_file) + fprintf (dump_file, "Doloop: Function call in loop.\n"); + return false; + } + + if (JUMP_P (insn) + && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC + || GET_CODE (PATTERN (insn)) == ADDR_VEC)) + { + if (dump_file) + fprintf (dump_file, "Doloop: Computed branch in the loop.\n"); + return false; + } + + return true; +} + bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, diff --git a/gcc/targhooks.h b/gcc/targhooks.h index ae6cf53c2a0..b4906ae1b3a 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -46,6 +46,8 @@ extern void default_unwind_emit (FILE *, rtx); extern bool default_scalar_mode_supported_p (enum machine_mode); +extern bool default_insn_valid_within_doloop (rtx); + /* These are here, and not in hooks.[ch], because not all users of hooks.h include tm.h, and thus we don't have CUMULATIVE_ARGS. */