From patchwork Wed Jun 29 22:34:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 102687 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 38B3FB6F6C for ; Thu, 30 Jun 2011 08:34:48 +1000 (EST) Received: (qmail 32064 invoked by alias); 29 Jun 2011 22:34:46 -0000 Received: (qmail 31800 invoked by uid 22791); 29 Jun 2011 22:34:44 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL, BAYES_00, NO_DNS_FOR_FROM, TW_MV, TW_MX, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from e1.ny.us.ibm.com (HELO e1.ny.us.ibm.com) (32.97.182.141) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 29 Jun 2011 22:34:27 +0000 Received: from d01relay06.pok.ibm.com (d01relay06.pok.ibm.com [9.56.227.116]) by e1.ny.us.ibm.com (8.14.4/8.13.1) with ESMTP id p5TMMMpC005581 for ; Wed, 29 Jun 2011 18:22:22 -0400 Received: from d01av03.pok.ibm.com (d01av03.pok.ibm.com [9.56.224.217]) by d01relay06.pok.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id p5TMYNgi1331286 for ; Wed, 29 Jun 2011 18:34:23 -0400 Received: from d01av03.pok.ibm.com (loopback [127.0.0.1]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id p5TIYB3K009776 for ; Wed, 29 Jun 2011 15:34:11 -0300 Received: from hungry-tiger.westford.ibm.com (hungry-tiger.westford.ibm.com [9.33.37.78]) by d01av03.pok.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id p5TIYBPD009765; Wed, 29 Jun 2011 15:34:11 -0300 Received: by hungry-tiger.westford.ibm.com (Postfix, from userid 500) id 59BAAF81FD; Wed, 29 Jun 2011 18:34:22 -0400 (EDT) Date: Wed, 29 Jun 2011 18:34:21 -0400 From: Michael Meissner To: gcc-patches@gcc.gnu.org, dje.gcc@gmail.com Subject: [PATCH] Add support on powerpc to change CASE_VALUES_THRESHOLD Message-ID: <20110629223421.GA24872@hungry-tiger.westford.ibm.com> Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, dje.gcc@gmail.com MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org On the powerpc, switch statements can be expensive, and we would like to be able to tune the threshold of when the compiler generates if statements vs. using a table jump operation (and different processors within the powerpc have different limits). This patch adds a powerpc tuning option to control this. I've done bootstraps and make checks with no regressions. Is this ok to apply to the trunk? At this time, I am not changing the default value (4). With the option, I've seen a few spec 2006 benchmarks run faster, and a few run slower. [gcc] 2011-06-29 Michael Meissner * config/rs6000/rs6000.opt (-mcase-values-threshold): New switch. * config/rs6000/rs6000.c (TARGET_CASE_VALUES_THRESHOLD): New target hook for override choice of when to do jump table vs. if statements based on -mcase-values-threshold=. * doc/invoke.texi (RS/6000 and PowerPC Options): Document -mcase-values-threshold. [gcc/testsuite] 2011-06-29 Michael Meissner * gcc.target/powerpc/ppc-switch-1.c: New test for -mcase-values-threshold. * gcc.target/powerpc/ppc-switch-2.c: Ditto. Index: gcc/config/rs6000/rs6000.opt =================================================================== --- gcc/config/rs6000/rs6000.opt (revision 175662) +++ gcc/config/rs6000/rs6000.opt (working copy) @@ -521,4 +521,7 @@ mxilinx-fpu Target Var(rs6000_xilinx_fpu) Save Specify Xilinx FPU. - +mcase-values-threshold= +Target Report Var(rs6000_case_values_threshold_num) Init(4) RejectNegative Joined UInteger Save +Specify the smallest number of different values for which it is best to use a +jump-table instead of a tree of conditional branches (default, 4). Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 175662) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -1210,6 +1210,7 @@ static void rs6000_function_specific_pri struct cl_target_option *); static bool rs6000_can_inline_p (tree, tree); static void rs6000_set_current_function (tree); +static unsigned int rs6000_case_values_threshold (void); /* Default register names. */ @@ -1617,6 +1618,9 @@ static const struct attribute_spec rs600 #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P rs6000_legitimate_constant_p +#undef TARGET_CASE_VALUES_THRESHOLD +#define TARGET_CASE_VALUES_THRESHOLD rs6000_case_values_threshold + struct gcc_target targetm = TARGET_INITIALIZER; @@ -26834,6 +26838,18 @@ rs6000_libcall_value (enum machine_mode return gen_rtx_REG (mode, regno); } +/* 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. */ + +static unsigned int +rs6000_case_values_threshold (void) +{ + if (rs6000_case_values_threshold_num) + return rs6000_case_values_threshold_num; + + return default_case_values_threshold (); +} /* Given FROM and TO register numbers, say whether this elimination is allowed. Frame pointer elimination is automatically handled. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 175662) +++ gcc/doc/invoke.texi (working copy) @@ -807,7 +807,7 @@ See RS/6000 and PowerPC Options. -msdata=@var{opt} -mvxworks -G @var{num} -pthread @gol -mrecip -mrecip=@var{opt} -mno-recip -mrecip-precision @gol -mno-recip-precision @gol --mveclibabi=@var{type} -mfriz -mno-friz} +-mveclibabi=@var{type} -mfriz -mno-friz -mcase-values-threshold=@var{n}} @emph{RX Options} @gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol @@ -16320,6 +16320,11 @@ Generate (do not generate) the @code{fri rounding a floating point value to 64-bit integer and back to floating point. The @code{friz} instruction does not return the same value if the floating point number is too large to fit in an integer. + +@item -mcase-values-threshold=@var{n} +Specify 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 for @option{-mcase-values-threshold} is 4. @end table @node RX Options Index: gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/ppc-switch-1.c (revision 0) @@ -0,0 +1,26 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 -mcase-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; +} Index: gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/ppc-switch-2.c (revision 0) @@ -0,0 +1,32 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ +/* { dg-options "-O2 -mcase-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; +}