From abd26bfbf3434e296f7dd412557f925e7ac512c5 Mon Sep 17 00:00:00 2001 From: Anatoly Sokolov Date: Sun, 17 Oct 2010 19:27:53 +0400 Subject: [PATCH] target.def (preferred_output_reload_class): New hook. * 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-protos.h (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. From-SVN: r165588 --- gcc/ChangeLog | 25 +++++++++++++++++++++++++ gcc/config/i386/i386-protos.h | 1 - gcc/config/i386/i386.c | 6 ++++-- gcc/config/i386/i386.h | 6 ------ gcc/doc/tm.texi | 11 +++++++++++ gcc/doc/tm.texi.in | 11 +++++++++++ gcc/recog.c | 10 +++++----- gcc/recog.h | 2 +- gcc/reload.c | 29 +++++++++++++---------------- gcc/target.def | 9 +++++++++ gcc/targhooks.c | 13 +++++++++++++ gcc/targhooks.h | 1 + 12 files changed, 93 insertions(+), 31 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 512ae120dbc..9e3642408bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2010-10-17 Anatoly Sokolov + + * 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-protos.h (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. + 2010-10-17 Iain Sandoe * c-parser.c (c_parser_objc_class_instance_variables): Update to use diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index f23ea933ec0..9c10103114a 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -153,7 +153,6 @@ extern bool ix86_secondary_memory_needed (enum reg_class, enum reg_class, 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); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cf70018675c..60b4dff8cc5 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -26788,8 +26788,8 @@ ix86_preferred_reload_class (rtx x, reg_class_t regclass) /* 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); @@ -33374,6 +33374,8 @@ ix86_autovectorize_vector_sizes (void) #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 diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 719761d2438..25463a5ed4b 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1373,12 +1373,6 @@ enum reg_class || (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) \ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 7c15d95f6be..941e2e1a492 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2669,6 +2669,17 @@ You can also use @code{PREFERRED_OUTPUT_RELOAD_CLASS} to discourage 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 diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 938ff6aeba1..604802bea0e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2665,6 +2665,17 @@ You can also use @code{PREFERRED_OUTPUT_RELOAD_CLASS} to discourage 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 diff --git a/gcc/recog.c b/gcc/recog.c index e16a85cc4ea..3ab72f10dd3 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2751,21 +2751,21 @@ constrain_operands (int strict) 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)); } diff --git a/gcc/recog.h b/gcc/recog.h index 71dba91fc05..217c6e56c86 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -102,7 +102,7 @@ extern int num_changes_pending (void); #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); diff --git a/gcc/reload.c b/gcc/reload.c index 17d4f2838b0..b1f94b27a0b 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -264,7 +264,7 @@ static void combine_reloads (void); 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 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc, /* 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_output_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 @@ combine_reloads (void) 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 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, 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]; @@ -3539,13 +3538,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, == 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 } /* We prefer to reload pseudos over reloading other things, @@ -3696,7 +3693,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, { 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 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, { 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]; diff --git a/gcc/target.def b/gcc/target.def index 186950ec2ed..cdfa903cd6e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -2042,6 +2042,15 @@ DEFHOOK (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, "", diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 7a3dda3241b..5948e3fcba4 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -1243,6 +1243,19 @@ default_preferred_reload_class (rtx x ATTRIBUTE_UNUSED, #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 diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 925e1f51aef..f59467904ce 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -155,6 +155,7 @@ extern int default_register_move_cost (enum machine_mode, reg_class_t, 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); -- 2.11.4.GIT