This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Hookize CASE_VALUES_THRESHOLD
- From: Anatoly Sokolov <aesok at post dot ru>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 24 Apr 2009 03:07:09 +0400
- Subject: [PATCH] Hookize CASE_VALUES_THRESHOLD
Hello.
This patch turns CASE_VALUES_THRESHOLD into a hook.
The patch has been bootstrapped on i686-pc-linux-gnu and regression tested on
i686-pc-linux-gnu, avr (C) and m10300 (C).
Ok for mainline?
2008-03-24 Anatoly Sokolov <aesok@post.ru>
* target.h (struct gcc_target): Add case_values_threshold field.
* target-def.h (TARGET_CASE_VALUES_THRESHOLD): New.
(TARGET_INITIALIZER): Use TARGET_CASE_VALUES_THRESHOLD.
* targhooks.c (default_case_values_threshold): New function.
* targhooks.h (default_case_values_threshold): Declare function.
* stmt.c (expand_case): Use case_values_threshold target hook.
* expr.h (case_values_threshold): Remove declartation.
* expr.c (case_values_threshold): Remove function.
* doc/tm.texi (CASE_VALUES_THRESHOLD): Revise documentation.
* config/avr/avr.h (CASE_VALUES_THRESHOLD): Remove macro.
* config/avr/avr.c (TARGET_CASE_VALUES_THRESHOLD): Define macro.
(avr_case_values_threshold): Declare as static.
* config/avr/avr-protos.h (avr_case_values_threshold): Remove.
* config/avr/mn10300.h (CASE_VALUES_THRESHOLD): Remove macro.
* config/avr/mn10300.c (TARGET_CASE_VALUES_THRESHOLD): Define macro.
(mn10300_case_values_threshold): New function.
Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi (revision 146309)
+++ gcc/doc/tm.texi (working copy)
@@ -9712,12 +9712,12 @@
is in effect.
@end defmac
-@defmac CASE_VALUES_THRESHOLD
-Define this to be the smallest number of different values for which it
+@deftypefn {Target Hook} unsigned int TARGET_CASE_VALUES_THRESHOLD (void)
+This function return the smallest number of different values for which it
is best to use a jump-table instead of a tree of conditional branches.
The default is four for machines with a @code{casesi} instruction and
five otherwise. This is best for most machines.
-@end defmac
+@end deftypefn
@defmac CASE_USE_BIT_TESTS
Define this macro to be a C expression to indicate whether C switch
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c (revision 146309)
+++ gcc/targhooks.c (working copy)
@@ -765,4 +765,17 @@
return ret;
}
+#ifndef HAVE_casesi
+# define HAVE_casesi 0
+#endif
+
+/* If the machine does not have a case insn that compares the bounds,
+ this means extra overhead for dispatch tables, which raises the
+ threshold for using them. */
+
+unsigned int default_case_values_threshold (void)
+{
+ return (HAVE_casesi ? 4 : 5);
+}
+
#include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h (revision 146309)
+++ gcc/targhooks.h (working copy)
@@ -104,3 +104,4 @@
extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
extern bool default_target_option_pragma_parse (tree, tree);
extern bool default_target_option_can_inline_p (tree, tree);
+extern unsigned int default_case_values_threshold (void);
Index: gcc/target.h
===================================================================
--- gcc/target.h (revision 146309)
+++ gcc/target.h (working copy)
@@ -919,6 +919,10 @@
in peephole2. */
bool (* hard_regno_scratch_ok) (unsigned int regno);
+ /* Return the smallest number of different values for which it is best to
+ use a jump-table instead of a tree of conditional branches. */
+ unsigned int (* case_values_threshold) (void);
+
/* Functions specific to the C family of frontends. */
struct c {
/* Return machine mode for non-standard suffix
Index: gcc/expr.c
===================================================================
--- gcc/expr.c (revision 146309)
+++ gcc/expr.c (working copy)
@@ -9886,19 +9886,6 @@
# define CODE_FOR_casesi CODE_FOR_nothing
#endif
-/* If the machine does not have a case insn that compares the bounds,
- this means extra overhead for dispatch tables, which raises the
- threshold for using them. */
-#ifndef CASE_VALUES_THRESHOLD
-#define CASE_VALUES_THRESHOLD (HAVE_casesi ? 4 : 5)
-#endif /* CASE_VALUES_THRESHOLD */
-
-unsigned int
-case_values_threshold (void)
-{
- return CASE_VALUES_THRESHOLD;
-}
-
/* Attempt to generate a casesi instruction. Returns 1 if successful,
0 otherwise (i.e. if there is no casesi instruction). */
int
Index: gcc/expr.h
===================================================================
--- gcc/expr.h (revision 146309)
+++ gcc/expr.h (working copy)
@@ -583,10 +583,6 @@
extern int try_casesi (tree, tree, tree, tree, rtx, rtx, rtx);
extern int try_tablejump (tree, tree, tree, tree, rtx, rtx);
-/* Smallest number of adjacent cases before we use a jump table.
- XXX Should be a target hook. */
-extern unsigned int case_values_threshold (void);
-
/* Functions from alias.c */
#include "alias.h"
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h (revision 146309)
+++ gcc/target-def.h (working copy)
@@ -654,6 +654,10 @@
#define TARGET_HARD_REGNO_SCRATCH_OK default_hard_regno_scratch_ok
#endif
+#ifndef TARGET_CASE_VALUES_THRESHOLD
+#define TARGET_CASE_VALUES_THRESHOLD default_case_values_threshold
+#endif
+
/* C specific. */
#ifndef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix
@@ -918,6 +922,7 @@
TARGET_EXPAND_TO_RTL_HOOK, \
TARGET_INSTANTIATE_DECLS, \
TARGET_HARD_REGNO_SCRATCH_OK, \
+ TARGET_CASE_VALUES_THRESHOLD, \
TARGET_C, \
TARGET_CXX, \
TARGET_EMUTLS, \
Index: gcc/config/avr/avr-protos.h
===================================================================
--- gcc/config/avr/avr-protos.h (revision 146309)
+++ gcc/config/avr/avr-protos.h (working copy)
@@ -39,7 +39,6 @@
extern void gas_output_limited_string (FILE *file, const char *str);
extern void gas_output_ascii (FILE *file, const char *str, size_t length);
extern int avr_hard_regno_rename_ok (unsigned int, unsigned int);
-extern unsigned int avr_case_values_threshold (void);
#ifdef TREE_CODE
extern void asm_output_external (FILE *file, tree decl, char *name);
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c (revision 146309)
+++ gcc/config/avr/avr.c (working copy)
@@ -87,6 +87,7 @@
static struct machine_function * avr_init_machine_status (void);
static rtx avr_builtin_setjmp_frame_value (void);
static bool avr_hard_regno_scratch_ok (unsigned int);
+static unsigned int avr_case_values_threshold (void);
/* Allocate registers from r25 to r8 for parameters for function calls. */
#define FIRST_CUM_REG 26
@@ -359,6 +360,8 @@
#undef TARGET_HARD_REGNO_SCRATCH_OK
#define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
+#undef TARGET_CASE_VALUES_THRESHOLD
+#define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
struct gcc_target targetm = TARGET_INITIALIZER;
Index: gcc/config/avr/avr.h
===================================================================
--- gcc/config/avr/avr.h (revision 146309)
+++ gcc/config/avr/avr.h (working copy)
@@ -734,8 +734,6 @@
#define CASE_VECTOR_MODE HImode
-#define CASE_VALUES_THRESHOLD avr_case_values_threshold ()
-
#undef WORD_REGISTER_OPERATIONS
#define MOVE_MAX 4
Index: gcc/config/mn10300/mn10300.c
===================================================================
--- gcc/config/mn10300/mn10300.c (revision 146309)
+++ gcc/config/mn10300/mn10300.c (working copy)
@@ -80,6 +80,7 @@
const_tree, bool);
static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
tree, bool);
+static unsigned int mn10300_case_values_threshold (void);
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
@@ -119,6 +120,9 @@
#undef TARGET_EXPAND_BUILTIN_VA_START
#define TARGET_EXPAND_BUILTIN_VA_START mn10300_va_start
+#undef TARGET_CASE_VALUES_THRESHOLD
+#define TARGET_CASE_VALUES_THRESHOLD mn10300_case_values_threshold
+
static void mn10300_encode_section_info (tree, rtx, int);
struct gcc_target targetm = TARGET_INITIALIZER;
@@ -2126,3 +2130,15 @@
if (flag_pic)
SYMBOL_REF_FLAG (symbol) = (*targetm.binds_local_p) (decl);
}
+
+/* Dispatch tables on the mn10300 are extremely expensive in terms of code
+ and readonly data size. So we crank up the case threshold value to
+ encourage a series of if/else comparisons to implement many small switch
+ statements. In theory, this value could be increased much more if we
+ were solely optimizing for space, but we keep it "reasonable" to avoid
+ serious code efficiency lossage. */
+
+unsigned int mn10300_case_values_threshold (void)
+{
+ return 6;
+}
\ No newline at end of file
Index: gcc/config/mn10300/mn10300.h
===================================================================
--- gcc/config/mn10300/mn10300.h (revision 146309)
+++ gcc/config/mn10300/mn10300.h (working copy)
@@ -815,13 +815,7 @@
than accessing full words. */
#define SLOW_BYTE_ACCESS 1
-/* Dispatch tables on the mn10300 are extremely expensive in terms of code
- and readonly data size. So we crank up the case threshold value to
- encourage a series of if/else comparisons to implement many small switch
- statements. In theory, this value could be increased much more if we
- were solely optimizing for space, but we keep it "reasonable" to avoid
- serious code efficiency lossage. */
-#define CASE_VALUES_THRESHOLD 6
+#define CASE_VALUES_THRESHOLD mn10300_case_values_threshold ()
#define NO_FUNCTION_CSE
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c (revision 146309)
+++ gcc/stmt.c (working copy)
@@ -2320,7 +2320,7 @@
If the switch-index is a constant, do it this way
because we can optimize it. */
- else if (count < case_values_threshold ()
+ else if (count < targetm.case_values_threshold ()
|| compare_tree_int (range,
(optimize_insn_for_size_p () ? 3 : 10) * count) > 0
/* RANGE may be signed, and really large ranges will show up
Anatoly