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 <[email protected]>
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 <[email protected]>
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
[email protected] 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;
+ }
+}