From patchwork Fri Oct 15 17:31:24 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anatoly Sokolov X-Patchwork-Id: 67986 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 59078B70DA for ; Sat, 16 Oct 2010 04:31:34 +1100 (EST) Received: (qmail 24952 invoked by alias); 15 Oct 2010 17:31:29 -0000 Received: (qmail 24922 invoked by uid 22791); 15 Oct 2010 17:31:25 -0000 X-SWARE-Spam-Status: No, hits=1.0 required=5.0 tests=AWL, BAYES_00, KAM_THEBAT, RCVD_IN_DNSWL_NONE, TW_EG, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from contrabass.post.ru (HELO contrabass.post.ru) (85.21.78.5) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 15 Oct 2010 17:31:18 +0000 Received: from corbina.ru (mail.post.ru [195.14.50.16]) by contrabass.post.ru (Postfix) with ESMTP id 2C4D5C22C for ; Fri, 15 Oct 2010 21:31:12 +0400 (MSD) Received: from [95.26.103.123] (account aesok@post.ru HELO Vista.corbina.ru) by corbina.ru (CommuniGate Pro SMTP 5.1.14) with ESMTPA id 266918673 for gcc-patches@gcc.gnu.org; Fri, 15 Oct 2010 21:31:12 +0400 Date: Fri, 15 Oct 2010 21:31:24 +0400 From: Anatoly Sokolov Message-ID: <769948200.20101015213124@post.ru> To: gcc-patches Subject: [PATCH] Hookize PREFERRED_OUTPUT_RELOAD_CLASS MIME-Version: 1.0 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 Hello. This patch turns PREFERRED_OUTPUT_RELOAD_CLASS macro into a hook. The patch has been bootstrapped on and regression tested on x86_64-unknown-linux-gnu for c. This patch is pre-approved and should be committed within a week if no objections. * target.def (preferred_output_reload_class): New hook. * doc/tm.texi.in (TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Document. * doc/tm.texi: Regenerate. * targhooks.c (default_preferred_output_reload_class): New function. * targhooks.h (default_preferred_output_reload_class): Declare. * reload.c (find_dummy_reload): Change rclass argument type from enum reg_class to reg_class_t. Change this_alternative array type from enum reg_class to reg_class_t. Use TARGET_PREFERRED_OUTPUT_RELOAD_CLASS target hook. (push_reload): Change preferred_class variable type to reg_class_t. Use TARGET_PREFERRED_OUTPUT_RELOAD_CLASS target hook. * recog.c (reg_fits_class_p): Change result type to bool. Change cl argument type from enum reg_class to reg_class_t. Use HARD_REGISTER_NUM_P predicate. * recog.h (reg_fits_class_p): Update prototype. * config/i386/i386.h (PREFERRED_OUTPUT_RELOAD_CLASS): Remove. * config/i386/i386.c (ix86_preferred_output_reload_class): Remove. * config/i386/i386.c (ix86_preferred_output_reload_class): Make static. Change regclass argument and result types from enum reg_class to reg_class_t. (TARGET_PREFERRED_OUTPUT_RELOAD_CLASS): Define. Anatoly. Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 165513) +++ gcc/doc/tm.texi (working copy) @@ -2665,6 +2665,17 @@ reload from using some alternatives, like @code{PREFERRED_RELOAD_CLASS}. @end defmac +@deftypefn {Target Hook} reg_class_t TARGET_PREFERRED_OUTPUT_RELOAD_CLASS (rtx @var{x}, reg_class_t @var{rclass}) +Like @code{TARGET_PREFERRED_RELOAD_CLASS}, but for output reloads instead of +input reloads. + +The default version of this hook always returns value of @code{rclass} +argument. + +You can also use @code{TARGET_PREFERRED_OUTPUT_RELOAD_CLASS} to discourage +reload from using some alternatives, like @code{TARGET_PREFERRED_RELOAD_CLASS}. +@end deftypefn + @defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class}) A C expression that places additional restrictions on the register class to use when it is necessary to be able to hold a value of mode Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in (revision 165513) +++ gcc/doc/tm.texi.in (working copy) @@ -2663,6 +2663,17 @@ reload from using some alternatives, like @code{PREFERRED_RELOAD_CLASS}. @end defmac +@hook TARGET_PREFERRED_OUTPUT_RELOAD_CLASS +Like @code{TARGET_PREFERRED_RELOAD_CLASS}, but for output reloads instead of +input reloads. + +The default version of this hook always returns value of @code{rclass} +argument. + +You can also use @code{TARGET_PREFERRED_OUTPUT_RELOAD_CLASS} to discourage +reload from using some alternatives, like @code{TARGET_PREFERRED_RELOAD_CLASS}. +@end deftypefn + @defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class}) A C expression that places additional restrictions on the register class to use when it is necessary to be able to hold a value of mode Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c (revision 165513) +++ gcc/targhooks.c (working copy) @@ -1243,6 +1243,19 @@ #endif } +/* The default implementation of TARGET_OUTPUT_PREFERRED_RELOAD_CLASS. */ + +reg_class_t +default_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED, + reg_class_t rclass) +{ +#ifdef PREFERRED_OUTPUT_RELOAD_CLASS + return PREFERRED_OUTPUT_RELOAD_CLASS (x, (enum reg_class) rclass); +#else + return rclass; +#endif +} + /* The default implementation of TARGET_CLASS_LIKELY_SPILLED_P. */ bool Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h (revision 165513) +++ gcc/targhooks.h (working copy) @@ -155,6 +155,7 @@ extern bool default_profile_before_prologue (void); extern reg_class_t default_preferred_reload_class (rtx, reg_class_t); +extern reg_class_t default_preferred_output_reload_class (rtx, reg_class_t); extern bool default_class_likely_spilled_p (reg_class_t); extern enum unwind_info_type default_debug_unwind_info (void); Index: gcc/target.def =================================================================== --- gcc/target.def (revision 165513) +++ gcc/target.def (working copy) @@ -2042,7 +2042,16 @@ (rtx x, reg_class_t rclass), default_preferred_reload_class) +/* Like TARGET_PREFERRED_RELOAD_CLASS, but for output reloads instead of + input reloads. */ DEFHOOK +(preferred_output_reload_class, + "", + reg_class_t, + (rtx x, reg_class_t rclass), + default_preferred_output_reload_class) + +DEFHOOK (class_likely_spilled_p, "", bool, (reg_class_t rclass), Index: gcc/reload.c =================================================================== --- gcc/reload.c (revision 165513) +++ gcc/reload.c (working copy) @@ -264,7 +264,7 @@ static int find_reusable_reload (rtx *, rtx, enum reg_class, enum reload_type, int, int); static rtx find_dummy_reload (rtx, rtx, rtx *, rtx *, enum machine_mode, - enum machine_mode, enum reg_class, int, int); + enum machine_mode, reg_class_t, int, int); static int hard_reg_set_here_p (unsigned int, unsigned int, rtx); static struct decomposition decompose (rtx); static int immune_p (rtx, rtx, struct decomposition); @@ -1224,21 +1224,20 @@ /* Narrow down the class of register wanted if that is desirable on this machine for efficiency. */ { - enum reg_class preferred_class = rclass; + reg_class_t preferred_class = rclass; if (in != 0) - preferred_class = (enum reg_class) targetm.preferred_reload_class (in, rclass); + preferred_class = targetm.preferred_reload_class (in, rclass); - /* Output reloads may need analogous treatment, different in detail. */ -#ifdef PREFERRED_OUTPUT_RELOAD_CLASS + /* Output reloads may need analogous treatment, different in detail. */ if (out != 0) - preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class); -#endif + preferred_class = targetm.preferred_reload_class (out, + preferred_class); /* Discard what the target said if we cannot do it. */ if (preferred_class != NO_REGS || (optional && type == RELOAD_FOR_OUTPUT)) - rclass = preferred_class; + rclass = (enum reg_class) preferred_class; } /* Make sure we use a class that can handle the actual pseudo @@ -1920,7 +1919,7 @@ static rtx find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc, enum machine_mode inmode, enum machine_mode outmode, - enum reg_class rclass, int for_real, int earlyclobber) + reg_class_t rclass, int for_real, int earlyclobber) { rtx in = real_in; rtx out = real_out; @@ -2588,7 +2587,7 @@ enum reload_usage { RELOAD_READ, RELOAD_READ_WRITE, RELOAD_WRITE } modified[MAX_RECOG_OPERANDS]; int no_input_reloads = 0, no_output_reloads = 0; int n_alternatives; - enum reg_class this_alternative[MAX_RECOG_OPERANDS]; + reg_class_t this_alternative[MAX_RECOG_OPERANDS]; char this_alternative_match_win[MAX_RECOG_OPERANDS]; char this_alternative_win[MAX_RECOG_OPERANDS]; char this_alternative_offmemok[MAX_RECOG_OPERANDS]; @@ -3535,17 +3534,15 @@ if (! CONSTANT_P (operand) && this_alternative[i] != NO_REGS) { - if (targetm.preferred_reload_class (operand, this_alternative[i]) - == NO_REGS) - reject = 600; - -#ifdef PREFERRED_OUTPUT_RELOAD_CLASS if (operand_type[i] == RELOAD_FOR_OUTPUT - && (PREFERRED_OUTPUT_RELOAD_CLASS (operand, - this_alternative[i]) + && (targetm.preferred_output_reload_class (operand, + this_alternative[i]) == NO_REGS)) reject = 600; -#endif + else if (targetm.preferred_reload_class (operand, + this_alternative[i]) + == NO_REGS) + reject = 600; } /* We prefer to reload pseudos over reloading other things, @@ -3696,7 +3693,7 @@ { goal_alternative_win[i] = this_alternative_win[i]; goal_alternative_match_win[i] = this_alternative_match_win[i]; - goal_alternative[i] = (reg_class_t) this_alternative[i]; + goal_alternative[i] = this_alternative[i]; goal_alternative_offmemok[i] = this_alternative_offmemok[i]; goal_alternative_matches[i] = this_alternative_matches[i]; goal_alternative_earlyclobber[i] @@ -3723,7 +3720,7 @@ { for (i = 0; i < noperands; i++) { - goal_alternative[i] = (reg_class_t) this_alternative[i]; + goal_alternative[i] = this_alternative[i]; goal_alternative_win[i] = this_alternative_win[i]; goal_alternative_match_win[i] = this_alternative_match_win[i]; Index: gcc/recog.c =================================================================== --- gcc/recog.c (revision 165513) +++ gcc/recog.c (working copy) @@ -2751,21 +2751,21 @@ return 0; } -/* Return 1 iff OPERAND (assumed to be a REG rtx) +/* Return true iff OPERAND (assumed to be a REG rtx) is a hard reg in class CLASS when its regno is offset by OFFSET and changed to mode MODE. If REG occupies multiple hard regs, all of them must be in CLASS. */ -int -reg_fits_class_p (rtx operand, enum reg_class cl, int offset, +bool +reg_fits_class_p (const_rtx operand, reg_class_t cl, int offset, enum machine_mode mode) { int regno = REGNO (operand); if (cl == NO_REGS) - return 0; + return false; - return (regno < FIRST_PSEUDO_REGISTER + return (HARD_REGISTER_NUM_P (regno) && in_hard_reg_set_p (reg_class_contents[(int) cl], mode, regno + offset)); } Index: gcc/recog.h =================================================================== --- gcc/recog.h (revision 165513) +++ gcc/recog.h (working copy) @@ -102,7 +102,7 @@ #ifdef HAVE_cc0 extern int next_insn_tests_no_inequality (rtx); #endif -extern int reg_fits_class_p (rtx, enum reg_class, int, enum machine_mode); +extern bool reg_fits_class_p (const_rtx, reg_class_t, int, enum machine_mode); extern int offsettable_memref_p (rtx); extern int offsettable_nonstrict_memref_p (rtx); Index: gcc/config/i386/i386.h =================================================================== --- gcc/config/i386/i386.h (revision 165513) +++ gcc/config/i386/i386.h (working copy) @@ -1373,12 +1373,6 @@ || (CLASS) == LEGACY_REGS || (CLASS) == INDEX_REGS) \ ? Q_REGS : (CLASS)) -/* Discourage putting floating-point values in SSE registers unless - SSE math is being used, and likewise for the 387 registers. */ - -#define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \ - ix86_preferred_output_reload_class ((X), (CLASS)) - /* If we are copying between general and FP registers, we need a memory location. The same is true for SSE and MMX registers. */ #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ Index: gcc/config/i386/i386-protos.h =================================================================== --- gcc/config/i386/i386-protos.h (revision 165513) +++ gcc/config/i386/i386-protos.h (working copy) @@ -153,7 +153,6 @@ enum machine_mode, int); extern bool ix86_cannot_change_mode_class (enum machine_mode, enum machine_mode, enum reg_class); -extern enum reg_class ix86_preferred_output_reload_class (rtx, enum reg_class); extern int ix86_mode_needed (int, rtx); extern void emit_i387_cw_initialization (int); extern void x86_order_regs_for_local_alloc (void); Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (revision 165513) +++ gcc/config/i386/i386.c (working copy) @@ -26795,8 +26795,8 @@ /* Discourage putting floating-point values in SSE registers unless SSE math is being used, and likewise for the 387 registers. */ -enum reg_class -ix86_preferred_output_reload_class (rtx x, enum reg_class regclass) +static reg_class_t +ix86_preferred_output_reload_class (rtx x, reg_class_t regclass) { enum machine_mode mode = GET_MODE (x); @@ -33379,6 +33379,8 @@ #undef TARGET_PREFERRED_RELOAD_CLASS #define TARGET_PREFERRED_RELOAD_CLASS ix86_preferred_reload_class +#undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS +#define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS ix86_preferred_output_reload_class #undef TARGET_CLASS_LIKELY_SPILLED_P #define TARGET_CLASS_LIKELY_SPILLED_P ix86_class_likely_spilled_p