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
This commit is contained in:
Richard Kenner 2002-02-22 16:18:25 -05:00
parent 3256b817fc
commit b76b08ef94
4 changed files with 41 additions and 61 deletions

View File

@ -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;

View File

@ -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")

View File

@ -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

View File

@ -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