From ec963611039e095aa654d81ffdd6b94ffd9aaee6 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Wed, 30 Nov 2005 13:51:32 +0000 Subject: [PATCH] predicates.md (symbolic_operand): Add comment. * pa/predicates.md (symbolic_operand): Add comment. * pa/pa.md (reload_insi_r1, reload_indi_r1): New reload expanders. * pa/pa-protos.h (pa_secondary_reload_class): Delete. * pa/pa.c (TARGET_SECONDARY_RELOAD): Define. (pa_secondary_reload_class): Delete. (pa_secondary_reload): New function derived from SECONDARY_RELOAD_CLASS and pa_secondary_reload_class. Reorder some checks. Update inline copy of symbolic operand. * pa/pa.h (SECONDARY_RELOAD_CLASS): Delete. Co-Authored-By: Bernd Schmidt From-SVN: r107719 --- gcc/ChangeLog | 13 +++++ gcc/config/pa/pa-protos.h | 2 - gcc/config/pa/pa.c | 121 ++++++++++++++++++++++++-------------------- gcc/config/pa/pa.h | 10 ---- gcc/config/pa/pa.md | 55 +++++++++++++++++--- gcc/config/pa/predicates.md | 3 +- 6 files changed, 129 insertions(+), 75 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ddb830f..813e209 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2005-11-30 John David Anglin + Bernd Schmidt + + * pa/predicates.md (symbolic_operand): Add comment. + * pa/pa.md (reload_insi_r1, reload_indi_r1): New reload expanders. + * pa/pa-protos.h (pa_secondary_reload_class): Delete. + * pa/pa.c (TARGET_SECONDARY_RELOAD): Define. + (pa_secondary_reload_class): Delete. + (pa_secondary_reload): New function derived from SECONDARY_RELOAD_CLASS + and pa_secondary_reload_class. Reorder some checks. Update inline + copy of symbolic operand. + * pa/pa.h (SECONDARY_RELOAD_CLASS): Delete. + 2005-11-30 Nathan Sidwell * loop-doloop.c (add_test): Only add jump notes if we did emit a diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h index d0daf72..0963844 100644 --- a/gcc/config/pa/pa-protos.h +++ b/gcc/config/pa/pa-protos.h @@ -106,8 +106,6 @@ extern int emit_move_sequence (rtx *, enum machine_mode, rtx); extern int emit_hpdiv_const (rtx *, int); extern int is_function_label_plus_const (rtx); extern int jump_in_call_delay (rtx); -extern enum reg_class pa_secondary_reload_class (enum reg_class, - enum machine_mode, rtx); extern int hppa_fpstore_bypass_p (rtx, rtx); extern int attr_length_millicode_call (rtx); extern int attr_length_call (rtx, int); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 0eeb163..4dcd828 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -150,6 +150,9 @@ static bool pa_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, static int pa_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode, tree, bool); static struct machine_function * pa_init_machine_status (void); +static enum reg_class pa_secondary_reload (bool, rtx, enum reg_class, + enum machine_mode, + secondary_reload_info *); /* Save the operands last given to a compare for use when we @@ -299,6 +302,9 @@ static size_t n_deferred_plabels = 0; #undef TARGET_CANNOT_FORCE_CONST_MEM #define TARGET_CANNOT_FORCE_CONST_MEM pa_tls_referenced_p +#undef TARGET_SECONDARY_RELOAD +#define TARGET_SECONDARY_RELOAD pa_secondary_reload + struct gcc_target targetm = TARGET_INITIALIZER; /* Parse the -mfixed-range= option string. */ @@ -5565,49 +5571,47 @@ output_arg_descriptor (rtx call_insn) fputc ('\n', asm_out_file); } -/* Return the class of any secondary reload register that is needed to - move IN into a register in class CLASS using mode MODE. +static enum reg_class +pa_secondary_reload (bool in_p, rtx x, enum reg_class class, + enum machine_mode mode, secondary_reload_info *sri) +{ + int is_symbolic; + int regno = -1; - Profiling has showed this routine and its descendants account for - a significant amount of compile time (~7%). So it has been - optimized to reduce redundant computations and eliminate useless - function calls. + /* Handle the easy stuff first. */ + if (class == R1_REGS) + return NO_REGS; - It might be worthwhile to try and make this a leaf function too. */ + if (REG_P (x)) + { + regno = REGNO (x); + if (class == BASE_REG_CLASS && regno < FIRST_PSEUDO_REGISTER) + return NO_REGS; + } -enum reg_class -pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in) -{ - int regno, is_symbolic; + /* If we have something like (mem (mem (...)), we can safely assume the + inner MEM will end up in a general register after reloading, so there's + no need for a secondary reload. */ + if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == MEM) + return NO_REGS; /* Trying to load a constant into a FP register during PIC code - generation will require %r1 as a scratch register. */ + generation requires %r1 as a scratch register. */ if (flag_pic && GET_MODE_CLASS (mode) == MODE_INT && FP_REG_CLASS_P (class) - && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE)) - return R1_REGS; - - /* Profiling showed the PA port spends about 1.3% of its compilation - time in true_regnum from calls inside pa_secondary_reload_class. */ - - if (GET_CODE (in) == REG) + && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)) { - regno = REGNO (in); - if (regno >= FIRST_PSEUDO_REGISTER) - regno = true_regnum (in); + gcc_assert (mode == SImode || mode == DImode); + sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1 + : CODE_FOR_reload_indi_r1); + return NO_REGS; } - else if (GET_CODE (in) == SUBREG) - regno = true_regnum (in); - else - regno = -1; - /* If we have something like (mem (mem (...)), we can safely assume the - inner MEM will end up in a general register after reloading, so there's - no need for a secondary reload. */ - if (GET_CODE (in) == MEM - && GET_CODE (XEXP (in, 0)) == MEM) - return NO_REGS; + /* Profiling showed the PA port spends about 1.3% of its compilation + time in true_regnum from calls inside pa_secondary_reload_class. */ + if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG) + regno = true_regnum (x); /* Handle out of range displacement for integer mode loads/stores of FP registers. */ @@ -5615,50 +5619,59 @@ pa_secondary_reload_class (enum reg_class class, enum machine_mode mode, rtx in) && GET_MODE_CLASS (mode) == MODE_INT && FP_REG_CLASS_P (class)) || (class == SHIFT_REGS && (regno <= 0 || regno >= 32))) - return GENERAL_REGS; + { + sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode]; + return NO_REGS; + } /* A SAR<->FP register copy requires a secondary register (GPR) as well as secondary memory. */ if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER && ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class)) - || (class == SHIFT_REGS && FP_REG_CLASS_P (REGNO_REG_CLASS (regno))))) - return GENERAL_REGS; + || (class == SHIFT_REGS + && FP_REG_CLASS_P (REGNO_REG_CLASS (regno))))) + { + sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode]; + return NO_REGS; + } - if (GET_CODE (in) == HIGH) - in = XEXP (in, 0); + /* Secondary reloads of symbolic operands require %r1 as a scratch + register when we're generating PIC code and the operand isn't + readonly. */ + if (GET_CODE (x) == HIGH) + x = XEXP (x, 0); /* Profiling has showed GCC spends about 2.6% of its compilation time in symbolic_operand from calls inside pa_secondary_reload_class. - - We use an inline copy and only compute its return value once to avoid - useless work. */ - switch (GET_CODE (in)) + So, we use an inline copy to avoid useless work. */ + switch (GET_CODE (x)) { - rtx tmp; + rtx op; case SYMBOL_REF: + is_symbolic = !SYMBOL_REF_TLS_MODEL (x); + break; case LABEL_REF: is_symbolic = 1; break; case CONST: - tmp = XEXP (in, 0); - is_symbolic = ((GET_CODE (XEXP (tmp, 0)) == SYMBOL_REF - || GET_CODE (XEXP (tmp, 0)) == LABEL_REF) - && GET_CODE (XEXP (tmp, 1)) == CONST_INT); + op = XEXP (x, 0); + is_symbolic = (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF + && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) + || GET_CODE (XEXP (op, 0)) == LABEL_REF) + && GET_CODE (XEXP (op, 1)) == CONST_INT); break; - default: is_symbolic = 0; break; } - if (!flag_pic - && is_symbolic - && read_only_operand (in, VOIDmode)) - return NO_REGS; - - if (class != R1_REGS && is_symbolic) - return R1_REGS; + if (is_symbolic && (flag_pic || !read_only_operand (x, VOIDmode))) + { + gcc_assert (mode == SImode || mode == DImode); + sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1 + : CODE_FOR_reload_indi_r1); + } return NO_REGS; } diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h index 1787038..6fc265e 100644 --- a/gcc/config/pa/pa.h +++ b/gcc/config/pa/pa.h @@ -527,16 +527,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void); in some cases it is preferable to use a more restrictive class. */ #define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS) -/* Return the register class of a scratch register needed to copy - IN into a register in CLASS in MODE, or a register in CLASS in MODE - to IN. If it can be done directly NO_REGS is returned. - - Avoid doing any work for the common case calls. */ -#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \ - ((CLASS == BASE_REG_CLASS && GET_CODE (IN) == REG \ - && REGNO (IN) < FIRST_PSEUDO_REGISTER) \ - ? NO_REGS : pa_secondary_reload_class (CLASS, MODE, IN)) - #define MAYBE_FP_REG_CLASS_P(CLASS) \ reg_classes_intersect_p ((CLASS), FP_REGS) diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 83fdec6..8e28e8f 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -2255,9 +2255,24 @@ DONE; }") -;; Reloading an SImode or DImode value requires a scratch register if -;; going in to or out of float point registers. +;; Handle SImode input reloads requiring %r1 as a scratch register. +(define_expand "reload_insi_r1" + [(set (match_operand:SI 0 "register_operand" "=Z") + (match_operand:SI 1 "non_hard_reg_operand" "")) + (clobber (match_operand:SI 2 "register_operand" "=&a"))] + "" + " +{ + if (emit_move_sequence (operands, SImode, operands[2])) + DONE; + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + DONE; +}") + +;; Handle SImode input reloads requiring a general register as a +;; scratch register. (define_expand "reload_insi" [(set (match_operand:SI 0 "register_operand" "=Z") (match_operand:SI 1 "non_hard_reg_operand" "")) @@ -2273,6 +2288,8 @@ DONE; }") +;; Handle SImode output reloads requiring a general register as a +;; scratch register. (define_expand "reload_outsi" [(set (match_operand:SI 0 "non_hard_reg_operand" "") (match_operand:SI 1 "register_operand" "Z")) @@ -3787,9 +3804,8 @@ DONE; }") -;; Reloading an SImode or DImode value requires a scratch register if -;; going in to or out of float point registers. - +;; Handle DFmode input reloads requiring a general register as a +;; scratch register. (define_expand "reload_indf" [(set (match_operand:DF 0 "register_operand" "=Z") (match_operand:DF 1 "non_hard_reg_operand" "")) @@ -3805,6 +3821,8 @@ DONE; }") +;; Handle DFmode output reloads requiring a general register as a +;; scratch register. (define_expand "reload_outdf" [(set (match_operand:DF 0 "non_hard_reg_operand" "") (match_operand:DF 1 "register_operand" "Z")) @@ -4044,6 +4062,24 @@ DONE; }") +;; Handle DImode input reloads requiring %r1 as a scratch register. +(define_expand "reload_indi_r1" + [(set (match_operand:DI 0 "register_operand" "=Z") + (match_operand:DI 1 "non_hard_reg_operand" "")) + (clobber (match_operand:SI 2 "register_operand" "=&a"))] + "" + " +{ + if (emit_move_sequence (operands, DImode, operands[2])) + DONE; + + /* We don't want the clobber emitted, so handle this ourselves. */ + emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1])); + DONE; +}") + +;; Handle DImode input reloads requiring a general register as a +;; scratch register. (define_expand "reload_indi" [(set (match_operand:DI 0 "register_operand" "=Z") (match_operand:DI 1 "non_hard_reg_operand" "")) @@ -4059,6 +4095,8 @@ DONE; }") +;; Handle DImode output reloads requiring a general register as a +;; scratch register. (define_expand "reload_outdi" [(set (match_operand:DI 0 "non_hard_reg_operand" "") (match_operand:DI 1 "register_operand" "Z")) @@ -4306,9 +4344,8 @@ DONE; }") -;; Reloading an SImode or DImode value requires a scratch register if -;; going in to or out of float point registers. - +;; Handle SFmode input reloads requiring a general register as a +;; scratch register. (define_expand "reload_insf" [(set (match_operand:SF 0 "register_operand" "=Z") (match_operand:SF 1 "non_hard_reg_operand" "")) @@ -4324,6 +4361,8 @@ DONE; }") +;; Handle SFmode output reloads requiring a general register as a +;; scratch register. (define_expand "reload_outsf" [(set (match_operand:SF 0 "non_hard_reg_operand" "") (match_operand:SF 1 "register_operand" "Z")) diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md index b383569..685a494 100644 --- a/gcc/config/pa/predicates.md +++ b/gcc/config/pa/predicates.md @@ -60,7 +60,8 @@ return (memory_address_p (mode, op) && IS_INDEX_ADDR_P (op)); }) -;; TODO: Add a comment. +;; Return 1 iff OP is a symbolic operand. +;; Note: an inline copy of this code is present in pa_secondary_reload. (define_predicate "symbolic_operand" (match_code "symbol_ref,label_ref,const") -- 2.7.4