From 3aa439ed17d7339192493926fd7e2562dd2bdf32 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Tue, 5 Jul 2011 17:45:38 +0000 Subject: [PATCH] Add --param case-values-threshold From-SVN: r175878 --- gcc/ChangeLog | 14 ++++++++ gcc/Makefile.in | 2 +- gcc/doc/invoke.texi | 5 +++ gcc/params.def | 10 ++++++ gcc/stmt.c | 17 +++++++++- gcc/testsuite/ChangeLog | 6 ++++ .../gcc.target/powerpc/ppc-switch-1.c | 26 +++++++++++++++ .../gcc.target/powerpc/ppc-switch-2.c | 32 +++++++++++++++++++ 8 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70de80a5f5a..184ea83bf11 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2011-07-05 Michael Meissner + + * params.def (PARAM_CASE_VALUES_THRESHOLD): New parameter to + override CASE_VALUES_THRESHOLD. + + * stmt.c (toplevel): Include params.h. + (case_values_threshold): Use the --param case-values-threshold + value if non-zero, otherwise use machine dependent value. + (expand_case): Use case_values_threshold. + + * Makefile.in (stmt.o): Add $(PARAMS_H) dependency. + + * doc/invoke.texi (--param case-values-threshold): Document. + 2011-07-05 Richard Henderson * dwarf2out.c (dwarf2out_cfi_label): Make static. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 091729d6e61..82119117e67 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2946,7 +2946,7 @@ stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(LIBFUNCS_H) $(EXCEPT_H) $(RECOG_H) $(DIAGNOSTIC_CORE_H) \ output.h $(GGC_H) $(TM_P_H) langhooks.h $(PREDICT_H) $(OPTABS_H) \ $(TARGET_H) $(GIMPLE_H) $(MACHMODE_H) $(REGS_H) alloc-pool.h \ - $(PRETTY_PRINT_H) $(BITMAP_H) + $(PRETTY_PRINT_H) $(BITMAP_H) $(PARAMS_H) except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) $(EXCEPT_H) $(FUNCTION_H) $(EXPR_H) $(LIBFUNCS_H) \ langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1fc40389f0a..c5e369ac6f8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -9026,6 +9026,11 @@ The maximum number of conditional stores paires that can be sunk. Set to 0 if either vectorization (@option{-ftree-vectorize}) or if-conversion (@option{-ftree-loop-if-convert}) is disabled. The default is 2. +@item case-values-threshold +The smallest number of different values for which it is best to use a +jump-table instead of a tree of conditional branches. If the value is +0, use the default for the machine. The default is 0. + @end table @end table diff --git a/gcc/params.def b/gcc/params.def index d827121f86c..78601f6de88 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -892,6 +892,16 @@ DEFPARAM (PARAM_MAX_STORES_TO_SINK, "Maximum number of conditional store pairs that can be sunk", 2, 0, 0) +/* Override CASE_VALUES_THRESHOLD of when to switch from doing switch + statements via if statements to using a table jump operation. If the value + is 0, the default CASE_VALUES_THRESHOLD will be used. */ +DEFPARAM (PARAM_CASE_VALUES_THRESHOLD, + "case-values-threshold", + "The smallest number of different values for which it is best to " + "use a jump-table instead of a tree of conditional branches, " + "if 0, use the default for the machine", + 0, 0, 0) + /* Local variables: diff --git a/gcc/stmt.c b/gcc/stmt.c index 1a9f9e505da..38e1e285234 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "alloc-pool.h" #include "pretty-print.h" #include "bitmap.h" +#include "params.h" /* Functions and data structures for expanding case statements. */ @@ -2270,6 +2271,20 @@ expand_switch_using_bit_tests_p (tree index_expr, tree range, || (uniq == 3 && count >= 6))); } +/* Return the smallest number of different values for which it is best to use a + jump-table instead of a tree of conditional branches. */ + +static unsigned int +case_values_threshold (void) +{ + unsigned int threshold = PARAM_VALUE (PARAM_CASE_VALUES_THRESHOLD); + + if (threshold == 0) + threshold = targetm.case_values_threshold (); + + return threshold; +} + /* Terminate a case (Pascal/Ada) or switch (C) statement in which ORIG_INDEX is the expression to be tested. If ORIG_TYPE is not NULL, it is the original ORIG_INDEX @@ -2424,7 +2439,7 @@ expand_case (gimple stmt) If the switch-index is a constant, do it this way because we can optimize it. */ - else if (count < targetm.case_values_threshold () + else if (count < 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 31297628029..7ce7bf88c7c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-07-05 Michael Meissner + + * gcc.target/powerpc/ppc-switch-1.c: New test for + --param case-values-threshold. + * gcc.target/powerpc/ppc-switch-2.c: Ditto. + 2011-07-05 Janis Johnson * gcc.target/arm/pr42093.c: Use "-fno-reorder-blocks". diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c b/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c new file mode 100644 index 00000000000..ac1dac9faa9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c @@ -0,0 +1,26 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 --param case-values-threshold=2" } */ +/* { dg-final { scan-assembler "mtctr" } } */ +/* { dg-final { scan-assembler "bctr" } } */ + +/* Force using a dispatch table even though by default we would generate + ifs. */ + +extern long call (long); + +long +test_switch (long a, long b) +{ + long c; + + switch (a) + { + case 0: c = -b; break; + case 1: c = ~b; break; + case 2: c = b+1; break; + default: c = b & 9; break; + } + + return call (c) + 1; +} diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c b/gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c new file mode 100644 index 00000000000..4f2efccfbd7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c @@ -0,0 +1,32 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 --param case-values-threshold=20" } */ +/* { dg-final { scan-assembler-not "mtctr" } } */ +/* { dg-final { scan-assembler-not "bctr" } } */ + +/* Force using if tests, instead of a dispatch table. */ + +extern long call (long); + +long +test_switch (long a, long b) +{ + long c; + + switch (a) + { + case 0: c = -b; break; + case 1: c = ~b; break; + case 2: c = b+1; break; + case 3: c = b-2; break; + case 4: c = b*3; break; + case 5: c = b/4; break; + case 6: c = b<<5; break; + case 7: c = b>>6; break; + case 8: c = b|7; break; + case 9: c = b^8; break; + default: c = b&9; break; + } + + return call (c) + 1; +} -- 2.30.2