diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 29df5e2f5f4..63d305f5a7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-03-02 Richard Henderson + + * expr.h (promoted_input_arg): Remove decl. + * function.c (promoted_input_arg): Merge into ... + * combine.c (setup_incoming_promotions): ... only caller. + Rearrange to avoid double loop. + 2007-03-02 Ben Elliston Peter Bergner Janis Johnson diff --git a/gcc/combine.c b/gcc/combine.c index d1277d49639..99da26da349 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1014,27 +1014,36 @@ init_reg_last (void) static void setup_incoming_promotions (void) { - unsigned int regno; - rtx reg; - enum machine_mode mode; - int unsignedp; - rtx first = get_insns (); + rtx first; + tree arg; - if (targetm.calls.promote_function_args (TREE_TYPE (cfun->decl))) + if (!targetm.calls.promote_function_args (TREE_TYPE (cfun->decl))) + return; + + first = get_insns (); + + for (arg = DECL_ARGUMENTS (current_function_decl); arg; + arg = TREE_CHAIN (arg)) { - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - /* Check whether this register can hold an incoming pointer - argument. FUNCTION_ARG_REGNO_P tests outgoing register - numbers, so translate if necessary due to register windows. */ - if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (regno)) - && (reg = promoted_input_arg (regno, &mode, &unsignedp)) != 0) - { - record_value_for_reg - (reg, first, gen_rtx_fmt_e ((unsignedp ? ZERO_EXTEND - : SIGN_EXTEND), - GET_MODE (reg), - gen_rtx_CLOBBER (mode, const0_rtx))); - } + rtx reg = DECL_INCOMING_RTL (arg); + + if (!REG_P (reg)) + continue; + + if (TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg))) + { + enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg)); + int uns = TYPE_UNSIGNED (TREE_TYPE (arg)); + + mode = promote_mode (TREE_TYPE (arg), mode, &uns, 1); + if (mode == GET_MODE (reg) && mode != DECL_MODE (arg)) + { + rtx x; + x = gen_rtx_CLOBBER (DECL_MODE (arg), const0_rtx); + x = gen_rtx_fmt_e ((uns ? ZERO_EXTEND : SIGN_EXTEND), mode, x); + record_value_for_reg (reg, first, x); + } + } } } diff --git a/gcc/expr.h b/gcc/expr.h index bc3feeeab80..13c73215960 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -597,9 +597,6 @@ extern rtx label_rtx (tree); if how is not obvious). */ extern rtx force_label_rtx (tree); -/* Indicate how an input argument register was promoted. */ -extern rtx promoted_input_arg (unsigned int, enum machine_mode *, int *); - /* Return an rtx like arg but sans any constant terms. Returns the original rtx if it has no constant terms. The constant terms are added and stored via a second arg. */ diff --git a/gcc/function.c b/gcc/function.c index 3c6222700c9..1d48f5b33a2 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -3228,40 +3228,6 @@ gimplify_parameters (void) return stmts; } - -/* Indicate whether REGNO is an incoming argument to the current function - that was promoted to a wider mode. If so, return the RTX for the - register (to get its mode). PMODE and PUNSIGNEDP are set to the mode - that REGNO is promoted from and whether the promotion was signed or - unsigned. */ - -rtx -promoted_input_arg (unsigned int regno, enum machine_mode *pmode, int *punsignedp) -{ - tree arg; - - for (arg = DECL_ARGUMENTS (current_function_decl); arg; - arg = TREE_CHAIN (arg)) - if (REG_P (DECL_INCOMING_RTL (arg)) - && REGNO (DECL_INCOMING_RTL (arg)) == regno - && TYPE_MODE (DECL_ARG_TYPE (arg)) == TYPE_MODE (TREE_TYPE (arg))) - { - enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg)); - int unsignedp = TYPE_UNSIGNED (TREE_TYPE (arg)); - - mode = promote_mode (TREE_TYPE (arg), mode, &unsignedp, 1); - if (mode == GET_MODE (DECL_INCOMING_RTL (arg)) - && mode != DECL_MODE (arg)) - { - *pmode = DECL_MODE (arg); - *punsignedp = unsignedp; - return DECL_INCOMING_RTL (arg); - } - } - - return 0; -} - /* Compute the size and offset from the start of the stacked arguments for a parm passed in mode PASSED_MODE and with type TYPE.