aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>2002-02-22 16:18:25 -0500
committerRichard Kenner <kenner@gcc.gnu.org>2002-02-22 16:18:25 -0500
commitb76b08ef94598e7fe6ef2ec3550f03c7bb1e1e7f (patch)
tree4650717d3b5700502979ec67e579bd50629ce350
parent3256b817fc4df76420ab88b8f83dabeb66939360 (diff)
downloadgcc-b76b08ef94598e7fe6ef2ec3550f03c7bb1e1e7f.zip
gcc-b76b08ef94598e7fe6ef2ec3550f03c7bb1e1e7f.tar.gz
gcc-b76b08ef94598e7fe6ef2ec3550f03c7bb1e1e7f.tar.bz2
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
-rw-r--r--gcc/config/alpha/alpha.c35
-rw-r--r--gcc/config/alpha/alpha.md45
-rw-r--r--gcc/expr.c6
-rw-r--r--gcc/loop.c14
4 files changed, 40 insertions, 60 deletions
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 69f7870..7710be5 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;
+ /* 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;
+ }
+
/* 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;
+ for (i = 1; i <= n && result == 0; i++)
+ result = alpha_emit_set_const_1 (target, mode, c, i);
- return 0;
+ /* 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 48ac0f7..06c272b 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 b730435..bcc76bc 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 f675a87..68ef439 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