From b76b08ef94598e7fe6ef2ec3550f03c7bb1e1e7f Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Fri, 22 Feb 2002 16:18:25 -0500 Subject: [PATCH] expr.c (store_expr): When converting expression to promoted equivalent type... * expr.c (store_expr): When converting expression to promoted equivalent type, allow using SUBREG_REG of TARGET as the target of the expansion of EXP. * loop.c (basic_induction_var, case SUBREG): Always look inside. * config/alpha/alpha.c (rtx_equiv_function_matters): Delete decl. (alpha_emit_set_const): Handle SImode when can't make new pseudos. (alpha_emit_set_const_1, alpha_sa_mask): Use no_new_pseudos. * config/alpha/alpha.md (addsi3, subsi3): Don't use if optimizing. From-SVN: r49972 --- gcc/config/alpha/alpha.c | 37 ++++++++++++++++++++------------ gcc/config/alpha/alpha.md | 45 ++++++--------------------------------- gcc/expr.c | 6 +++++- gcc/loop.c | 14 ++++++------ 4 files changed, 41 insertions(+), 61 deletions(-) diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 69f7870eeb1..7710be58b60 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -48,9 +48,6 @@ Boston, MA 02111-1307, USA. */ #include "target-def.h" #include "debug.h" -/* External data. */ -extern int rtx_equal_function_value_matters; - /* Specify which cpu to schedule for. */ enum processor_type alpha_cpu; @@ -2231,15 +2228,29 @@ alpha_emit_set_const (target, mode, c, n) HOST_WIDE_INT c; int n; { - rtx pat; + rtx result = 0; + rtx orig_target = target; int i; - /* Try 1 insn, then 2, then up to N. */ - for (i = 1; i <= n; i++) - if ((pat = alpha_emit_set_const_1 (target, mode, c, i)) != 0) - return pat; + /* If we can't make any pseudos, TARGET is an SImode hard register, we + can't load this constant in one insn, do this in DImode. */ + if (no_new_pseudos && mode == SImode + && GET_CODE (target) == REG && REGNO (target) < FIRST_PSEUDO_REGISTER + && (result = alpha_emit_set_const_1 (target, mode, c, 1)) == 0) + { + target = gen_lowpart (DImode, target); + mode = DImode; + } - return 0; + /* Try 1 insn, then 2, then up to N. */ + for (i = 1; i <= n && result == 0; i++) + result = alpha_emit_set_const_1 (target, mode, c, i); + + /* Allow for the case where we changed the mode of TARGET. */ + if (result == target) + result = orig_target; + + return result; } /* Internal routine for the above to check for N or below insns. */ @@ -2255,8 +2266,7 @@ alpha_emit_set_const_1 (target, mode, c, n) int i, bits; /* Use a pseudo if highly optimizing and still generating RTL. */ rtx subtarget - = (flag_expensive_optimizations && rtx_equal_function_value_matters - ? 0 : target); + = (flag_expensive_optimizations && !no_new_pseudos ? 0 : target); rtx temp; #if HOST_BITS_PER_WIDE_INT == 64 @@ -2321,8 +2331,7 @@ alpha_emit_set_const_1 (target, mode, c, n) we can't make pseudos, we can't do anything since the expand_binop and expand_unop calls will widen and try to make pseudos. */ - if (n == 1 - || (mode == SImode && ! rtx_equal_function_value_matters)) + if (n == 1 || (mode == SImode && no_new_pseudos)) return 0; /* Next, see if we can load a related constant and then shift and possibly @@ -5857,7 +5866,7 @@ alpha_sa_mask (imaskP, fmaskP) the regular part of the compiler. In the ASM_OUTPUT_MI_THUNK case we don't have valid register life info, but assemble_start_function wants to output .frame and .mask directives. */ - if (current_function_is_thunk && rtx_equal_function_value_matters) + if (current_function_is_thunk && !no_new_pseudos) { *imaskP = 0; *fmaskP = 0; diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 48ac0f77577..06c272b6890 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -518,31 +518,14 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (sign_extend:DI (match_dup 1)))] "") -;; Do addsi3 the way expand_binop would do if we didn't have one. This -;; generates better code. We have the anonymous addsi3 pattern below in -;; case combine wants to make it. +;; Don't say we have addsi3 if optimizing. This generates better code. We +;; have the anonymous addsi3 pattern below in case combine wants to make it. (define_expand "addsi3" [(set (match_operand:SI 0 "register_operand" "") (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") (match_operand:SI 2 "add_operand" "")))] - "" -{ - if (optimize) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx op2 = gen_lowpart (DImode, operands[2]); - - if (! cse_not_expected) - { - rtx tmp = gen_reg_rtx (DImode); - emit_insn (gen_adddi3 (tmp, op1, op2)); - emit_move_insn (gen_lowpart (DImode, operands[0]), tmp); - } - else - emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2)); - DONE; - } -}) + "! optimize" + "") (define_insn "*addsi_internal" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") @@ -844,24 +827,8 @@ fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" [(set (match_operand:SI 0 "register_operand" "") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "") (match_operand:SI 2 "reg_or_8bit_operand" "")))] - "" -{ - if (optimize) - { - rtx op1 = gen_lowpart (DImode, operands[1]); - rtx op2 = gen_lowpart (DImode, operands[2]); - - if (! cse_not_expected) - { - rtx tmp = gen_reg_rtx (DImode); - emit_insn (gen_subdi3 (tmp, op1, op2)); - emit_move_insn (gen_lowpart (DImode, operands[0]), tmp); - } - else - emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2)); - DONE; - } -}) + "! optimize" + "") (define_insn "*subsi_internal" [(set (match_operand:SI 0 "register_operand" "=r") diff --git a/gcc/expr.c b/gcc/expr.c index b7304350b7f..bcc76bc2604 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -3989,6 +3989,8 @@ store_expr (exp, target, want_value) and then convert to the wider mode. Our value is the computed expression. */ { + rtx inner_target = 0; + /* If we don't want a value, we can do the conversion inside EXP, which will often result in some optimizations. Do the conversion in two steps: first change the signedness, if needed, then @@ -4009,9 +4011,11 @@ store_expr (exp, target, want_value) exp = convert (type_for_mode (GET_MODE (SUBREG_REG (target)), SUBREG_PROMOTED_UNSIGNED_P (target)), exp); + + inner_target = SUBREG_REG (target); } - temp = expand_expr (exp, NULL_RTX, VOIDmode, 0); + temp = expand_expr (exp, inner_target, VOIDmode, 0); /* If TEMP is a volatile MEM and we want a result value, make the access now so it gets done only once. Likewise if diff --git a/gcc/loop.c b/gcc/loop.c index f675a87f0de..68ef43906cb 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -6127,13 +6127,13 @@ basic_induction_var (loop, x, mode, dest_reg, p, inc_val, mult_val, location) return 1; case SUBREG: - /* If this is a SUBREG for a promoted variable, check the inner - value. */ - if (SUBREG_PROMOTED_VAR_P (x)) - return basic_induction_var (loop, SUBREG_REG (x), - GET_MODE (SUBREG_REG (x)), - dest_reg, p, inc_val, mult_val, location); - return 0; + /* If what's inside the SUBREG is a BIV, then the SUBREG. This will + handle addition of promoted variables. + ??? The comment at the start of this function is wrong: promoted + variable increments don't look like it says they do. */ + return basic_induction_var (loop, SUBREG_REG (x), + GET_MODE (SUBREG_REG (x)), + dest_reg, p, inc_val, mult_val, location); case REG: /* If this register is assigned in a previous insn, look at its