In looking at some improvements to the powerpc, we wanted to change the default for when a table jump is generated vs. a series of if statements. Now, we could just add a powerpc specific TARGET_CASE_VALUES_THRESHOLD, but I tend to think that these should be settable on all/most ports with --param.
At present, there are only two ports (avr and mn10300) that define their own TARGET_CASE_VALUES_THRESHOLD hook. My first patch does not remove the target hook and modify the avr/mn10300 ports to use maybe_set_param_value, but that can be done if desired. The patch adds two --param values, one for when the port is using the casesi insn, and the other when it uses the more primitive tablejump insn. I have bootstrapped the compiler with this patch and run the test suite with no regressions. Is it ok to apply as is? Should I modify the avr and mn10300 ports to use the parameters and do away with the target hook? Or should I do this just as a powerpc target hook? [gcc] 2011-04-21 Michael Meissner <meiss...@linux.vnet.ibm.com> PR rtl-optimization/48715 * params.def (PARAM_CASE_VALUES_THRESHOD_CASESI): New parameter. (PARAM_CASE_VALUES_THRESHOLD_TABLEJUMP): Ditto. * params.h (CASE_VALUES_THRESHOLD_CASESI): Define. (CASE_VALUES_THRESHOLD_TABLEJUMP): Ditto. * targhooks.c (toplevel): Include params.h. (default_case_values_threshold): Use CASE_VALUES_THRESHOLD_CASESI and CASE_VALUES_THRESHOLD_TABLEJUMP. * Makefile.in (targhooks.o): Add $(PARAMS_H) dependency. * doc/invoke.texi (case-values-threshold-casesi): Document. (case-values-threshold-tablejump): Ditto. [gcc/testsuite] 2011-04-21 Michael Meissner <meiss...@linux.vnet.ibm.com> PR rtl-optimization/48715 * gcc.target/powerpc/case-threshold1.c: New file to test --param case-values-threshold-tablejump. * gcc.target/powerpc/case-threshold2.c: Ditto. -- Michael Meissner, IBM 5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA meiss...@linux.vnet.ibm.com fax +1 (978) 399-6899
Index: gcc/params.def =================================================================== --- gcc/params.def (revision 172832) +++ gcc/params.def (working copy) @@ -885,6 +885,22 @@ DEFPARAM (PARAM_MAX_STORES_TO_SINK, 2, 0, 0) +/* Threshold for using jump table vs. if statements if the machine supports a + CASESI instruction. */ +DEFPARAM (PARAM_CASE_VALUES_THRESHOLD_CASESI, + "case-values-threshold-casesi", + "Minimum number of case elements to use a jump table instead of" + "if statements if the machine supports a CASESI instruction", + 4, 2, 0) + +/* Threshold for using jump table vs. if statements if the machine does not + support a CASESI instruction. */ +DEFPARAM (PARAM_CASE_VALUES_THRESHOLD_TABLEJUMP, + "case-values-threshold-tablejump", + "Minimum number of case elements to use a jump table instead of" + "if statements if the machine does not support a CASESI instruction", + 5, 2, 0) + /* Local variables: mode:c Index: gcc/params.h =================================================================== --- gcc/params.h (revision 172832) +++ gcc/params.h (working copy) @@ -206,4 +206,8 @@ extern void init_param_values (int *para PARAM_VALUE (PARAM_MIN_NONDEBUG_INSN_UID) #define MAX_STORES_TO_SINK \ PARAM_VALUE (PARAM_MAX_STORES_TO_SINK) +#define CASE_VALUES_THRESHOLD_CASESI \ + PARAM_VALUE (PARAM_CASE_VALUES_THRESHOLD_CASESI) +#define CASE_VALUES_THRESHOLD_TABLEJUMP \ + PARAM_VALUE (PARAM_CASE_VALUES_THRESHOLD_TABLEJUMP) #endif /* ! GCC_PARAMS_H */ Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c (revision 172832) +++ gcc/targhooks.c (working copy) @@ -71,7 +71,7 @@ along with GCC; see the file COPYING3. #include "opts.h" #include "tree-flow.h" #include "tree-ssa-alias.h" - +#include "params.h" bool default_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, @@ -1209,7 +1209,9 @@ default_target_can_inline_p (tree caller unsigned int default_case_values_threshold (void) { - return (HAVE_casesi ? 4 : 5); + return (HAVE_casesi + ? CASE_VALUES_THRESHOLD_CASESI + : CASE_VALUES_THRESHOLD_TABLEJUMP); } bool Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 172832) +++ gcc/Makefile.in (working copy) @@ -2807,7 +2807,7 @@ opts-common.o : opts-common.c $(OPTS_H) targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(DIAGNOSTIC_CORE_H) \ $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ - $(OPTABS_H) $(RECOG_H) reload.h hard-reg-set.h intl.h $(OPTS_H) \ + $(OPTABS_H) $(RECOG_H) reload.h hard-reg-set.h intl.h $(OPTS_H) $(PARAMS_H) \ tree-ssa-alias.h $(TREE_FLOW_H) bversion.h: s-bversion; @true Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 172832) +++ gcc/doc/invoke.texi (working copy) @@ -8889,6 +8889,16 @@ The maximum number of conditional stores if either vectorization (@option{-ftree-vectorize}) or if-conversion (@option{-ftree-loop-if-convert}) is disabled. The default is 2. +@item case-values-threshold-casesi +The minimum number of case elements to use a jump table instead of if +statements if the machine supports a @code{casesi} instruction. The +default is 4. + +@item case-values-threshold-tablejump +The minimum number of case elements to use a jump table instead of if +statements if the machine does not support a @code{casesi} +instruction. The default is 5. + @end table @end table Index: gcc/testsuite/gcc.target/powerpc/case-threshold1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/case-threshold1.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/case-threshold1.c (revision 0) @@ -0,0 +1,26 @@ +/* Insure case-values-threshold is obeyed. This test should generate if + statements and not a table jump. */ +/* { dg-do compile } */ +/* { dg-options "-O2 --param case-values-threshold-tablejump=11" } */ + +/* { dg-final { scan-assembler-not "mtctr" } } */ +/* { dg-final { scan-assembler-not "bctr" } } */ + +int +switch_10 (int a, int b) +{ + switch (a) + { + case 0: return b + 1; + case 1: return b - 2; + case 2: return b * 3; + case 3: return b / 4; + case 4: return b % 5; + case 5: return b << 6; + case 6: return b >> 7; + case 7: return b & 0x8; + case 8: return b | 0x9; + case 9: return b ^ 0xa; + default: return b; + } +} Index: gcc/testsuite/gcc.target/powerpc/case-threshold2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/case-threshold2.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/case-threshold2.c (revision 0) @@ -0,0 +1,26 @@ +/* Insure case-values-threshold is obeyed. This test should generate a table + jump and not if statements. */ +/* { dg-do compile } */ +/* { dg-options "-O2 --param case-values-threshold-tablejump=10" } */ + +/* { dg-final { scan-assembler "mtctr" } } */ +/* { dg-final { scan-assembler "bctr" } } */ + +int +switch_10 (int a, int b) +{ + switch (a) + { + case 0: return b + 1; + case 1: return b - 2; + case 2: return b * 3; + case 3: return b / 4; + case 4: return b % 5; + case 5: return b << 6; + case 6: return b >> 7; + case 7: return b & 0x8; + case 8: return b | 0x9; + case 9: return b ^ 0xa; + default: return b; + } +}