aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/doc/tm.texi11
-rw-r--r--gcc/hooks.c6
-rw-r--r--gcc/hooks.h1
-rw-r--r--gcc/loop-doloop.c26
-rw-r--r--gcc/target-def.h5
-rw-r--r--gcc/target.h3
-rw-r--r--gcc/targhooks.c30
-rw-r--r--gcc/targhooks.h2
9 files changed, 79 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d6aa061..5acda30 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2005-05-25 Adrian Straetling <straetling@de.ibm.com>
+
+ * 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 <ebotcazou@libertysurf.fr>
PR target/21412
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 9e755aa..e541a20 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 6e6e7c7..30ba6d1 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -192,6 +192,12 @@ hook_bool_rtx_false (rtx a ATTRIBUTE_UNUSED)
}
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 b799a8c..b78f497 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 c6ef37e..4a2bb87 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 27e8511..49e25a1 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 f141f04..38f09b0 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 2bf11a4..1f8b5b7 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 ae6cf53..b4906ae 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. */