mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-05 14:59:45 +08:00
integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg.
* integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg. (simplify_subreg): Handle complex types represented as CONCAT. * recog.c (validate_replace_rtx_1): Properly canonicalize expression * rtl.h (swap_commutative_operands_p): Declare. * rtlanal.c (swap_commutative_operands_p): New. (operand_preference): New static function. * combine.c (combine_simplify_rtx): Use swap_commutative_operands_p. (gen_binary): Likewise. * optabs.c (emit_cmp_and_jump_insns, emit_conditional_move): Likewise. * simplify-rtx.c (simplify_gen_binary, simplify_gen_relational): Likewise. From-SVN: r42224
This commit is contained in:
parent
949c5d6257
commit
e5c56fd9bf
@ -1,3 +1,19 @@
|
||||
Thu May 17 23:19:46 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* integrate.c (copy_rtx_and_substitute): Use simplify_gen_subreg.
|
||||
(simplify_subreg): Handle complex types represented as CONCAT.
|
||||
|
||||
* recog.c (validate_replace_rtx_1): Properly canonicalize expression
|
||||
* rtl.h (swap_commutative_operands_p): Declare.
|
||||
* rtlanal.c (swap_commutative_operands_p): New.
|
||||
(operand_preference): New static function.
|
||||
|
||||
* combine.c (combine_simplify_rtx): Use swap_commutative_operands_p.
|
||||
(gen_binary): Likewise.
|
||||
* optabs.c (emit_cmp_and_jump_insns, emit_conditional_move): Likewise.
|
||||
* simplify-rtx.c (simplify_gen_binary,
|
||||
simplify_gen_relational): Likewise.
|
||||
|
||||
Thu May 17 20:43:36 CEST 2001 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cse.c (fold_rtx): Use simplify_subreg.
|
||||
|
@ -3514,12 +3514,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
|
||||
/* If this is a commutative operation, put a constant last and a complex
|
||||
expression first. We don't need to do this for comparisons here. */
|
||||
if (GET_RTX_CLASS (code) == 'c'
|
||||
&& ((CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
|
||||
|| (GET_RTX_CLASS (GET_CODE (XEXP (x, 0))) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o')
|
||||
|| (GET_CODE (XEXP (x, 0)) == SUBREG
|
||||
&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (XEXP (x, 0)))) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) != 'o')))
|
||||
&& swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
|
||||
{
|
||||
temp = XEXP (x, 0);
|
||||
SUBST (XEXP (x, 0), XEXP (x, 1));
|
||||
@ -9818,12 +9813,7 @@ gen_binary (code, mode, op0, op1)
|
||||
|
||||
/* Put complex operands first and constants second. */
|
||||
if (GET_RTX_CLASS (code) == 'c'
|
||||
&& ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
|
||||
|| (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (op1)) != 'o')
|
||||
|| (GET_CODE (op0) == SUBREG
|
||||
&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
|
||||
&& swap_commutative_operands_p (op0, op1))
|
||||
return gen_rtx_fmt_ee (code, mode, op1, op0);
|
||||
|
||||
/* If we are turning off bits already known off in OP0, we need not do
|
||||
|
@ -1308,10 +1308,6 @@ int
|
||||
subreg_lowpart_p (x)
|
||||
rtx x;
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
int difference = (GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))
|
||||
- GET_MODE_SIZE (GET_MODE (x)));
|
||||
|
||||
if (GET_CODE (x) != SUBREG)
|
||||
return 1;
|
||||
else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
|
||||
|
@ -1902,35 +1902,9 @@ copy_rtx_and_substitute (orig, map, for_lhs)
|
||||
|
||||
case SUBREG:
|
||||
copy = copy_rtx_and_substitute (SUBREG_REG (orig), map, for_lhs);
|
||||
/* SUBREG is ordinary, but don't make nested SUBREGs. */
|
||||
if (GET_CODE (copy) == SUBREG)
|
||||
{
|
||||
int final_offset = SUBREG_BYTE (orig) + SUBREG_BYTE (copy);
|
||||
|
||||
/* When working with SUBREGs the rule is that the byte
|
||||
offset must be a multiple of the SUBREG's mode. */
|
||||
final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig)));
|
||||
final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig)));
|
||||
return gen_rtx_SUBREG (GET_MODE (orig), SUBREG_REG (copy),
|
||||
final_offset);
|
||||
}
|
||||
else if (GET_CODE (copy) == CONCAT)
|
||||
{
|
||||
rtx retval = subreg_realpart_p (orig) ? XEXP (copy, 0) : XEXP (copy, 1);
|
||||
int final_offset;
|
||||
|
||||
if (GET_MODE (retval) == GET_MODE (orig))
|
||||
return retval;
|
||||
|
||||
final_offset = SUBREG_BYTE (orig) %
|
||||
GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (orig)));
|
||||
final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (orig)));
|
||||
final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (orig)));
|
||||
return gen_rtx_SUBREG (GET_MODE (orig), retval, final_offset);
|
||||
}
|
||||
else
|
||||
return gen_rtx_SUBREG (GET_MODE (orig), copy,
|
||||
SUBREG_BYTE (orig));
|
||||
return simplify_gen_subreg (GET_MODE (orig), copy,
|
||||
GET_MODE (SUBREG_REG (orig)),
|
||||
SUBREG_BYTE (orig));
|
||||
|
||||
case ADDRESSOF:
|
||||
copy = gen_rtx_ADDRESSOF (mode,
|
||||
|
17
gcc/optabs.c
17
gcc/optabs.c
@ -3290,8 +3290,7 @@ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
|
||||
rtx op0;
|
||||
rtx op1;
|
||||
|
||||
if ((CONSTANT_P (x) && ! CONSTANT_P (y))
|
||||
|| (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
|
||||
if (swap_commutative_operands_p (x, y))
|
||||
{
|
||||
/* Swap operands and condition to ensure canonical RTL. */
|
||||
op0 = y;
|
||||
@ -3609,12 +3608,12 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
|
||||
{
|
||||
rtx tem, subtarget, comparison, insn;
|
||||
enum insn_code icode;
|
||||
enum rtx_code reversed;
|
||||
|
||||
/* If one operand is constant, make it the second one. Only do this
|
||||
if the other operand is not constant as well. */
|
||||
|
||||
if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
|
||||
|| (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
|
||||
if (swap_commutative_operands_p (op0, op1))
|
||||
{
|
||||
tem = op0;
|
||||
op0 = op1;
|
||||
@ -3633,16 +3632,14 @@ emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
|
||||
if (cmode == VOIDmode)
|
||||
cmode = GET_MODE (op0);
|
||||
|
||||
if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
|
||||
|| (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
|
||||
&& (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
|
||||
|| TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
|
||||
|| flag_unsafe_math_optimizations))
|
||||
if (swap_commutative_operands_p (op2, op3)
|
||||
&& ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
|
||||
!= UNKNOWN))
|
||||
{
|
||||
tem = op2;
|
||||
op2 = op3;
|
||||
op3 = tem;
|
||||
code = reverse_condition (code);
|
||||
code = reversed;
|
||||
}
|
||||
|
||||
if (mode == VOIDmode)
|
||||
|
@ -1370,6 +1370,7 @@ extern int reg_used_between_p PARAMS ((rtx, rtx, rtx));
|
||||
extern int reg_referenced_between_p PARAMS ((rtx, rtx, rtx));
|
||||
extern int reg_set_between_p PARAMS ((rtx, rtx, rtx));
|
||||
extern int regs_set_between_p PARAMS ((rtx, rtx, rtx));
|
||||
extern int swap_commutative_operands_p PARAMS ((rtx, rtx));
|
||||
extern int modified_between_p PARAMS ((rtx, rtx, rtx));
|
||||
extern int no_labels_between_p PARAMS ((rtx, rtx));
|
||||
extern int no_jumps_between_p PARAMS ((rtx, rtx));
|
||||
|
@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
|
||||
static void set_of_1 PARAMS ((rtx, rtx, void *));
|
||||
static void insn_dependent_p_1 PARAMS ((rtx, rtx, void *));
|
||||
static int computed_jump_p_1 PARAMS ((rtx));
|
||||
static int operand_preference PARAMS ((rtx));
|
||||
|
||||
/* Bit flags that specify the machine subtype we are compiling for.
|
||||
Bits are tested using macros TARGET_... defined in the tm.h file
|
||||
@ -2533,6 +2534,52 @@ regno_use_in (regno, x)
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Return a value indicating whether OP, an operand of a commutative
|
||||
operation, is preferred as the first or second operand. The higher
|
||||
the value, the stronger the preference for being the first operand.
|
||||
We use negative values to indicate a preference for the first operand
|
||||
and positive values for the second operand. */
|
||||
|
||||
static int
|
||||
operand_preference (op)
|
||||
rtx op;
|
||||
{
|
||||
/* Constants always come the second operand. Prefer "nice" constants. */
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
return -4;
|
||||
if (GET_CODE (op) == CONST_DOUBLE)
|
||||
return -3;
|
||||
if (CONSTANT_P (op))
|
||||
return -2;
|
||||
|
||||
/* SUBREGs of objects should come second. */
|
||||
if (GET_CODE (op) == SUBREG
|
||||
&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (op))) == 'o')
|
||||
return -1;
|
||||
|
||||
/* If only one operand is a `neg', `not',
|
||||
`mult', `plus', or `minus' expression, it will be the first
|
||||
operand. */
|
||||
if (GET_CODE (op) == NEG || GET_CODE (op) == NOT
|
||||
|| GET_CODE (op) == MULT || GET_CODE (op) == PLUS
|
||||
|| GET_CODE (op) == MINUS)
|
||||
return 2;
|
||||
|
||||
/* Complex expressions should be the first. */
|
||||
if (GET_RTX_CLASS (GET_CODE (op)) == 'o')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return 1 iff it is neccesary to swap operands of commutative operation
|
||||
in order to canonicalize expression. */
|
||||
|
||||
int
|
||||
swap_commutative_operands_p (x, y)
|
||||
rtx x, y;
|
||||
{
|
||||
return operand_preference (x) < operand_preference (y);
|
||||
}
|
||||
|
||||
/* Return 1 if X is an autoincrement side effect and the register is
|
||||
not the stack pointer. */
|
||||
|
@ -113,12 +113,7 @@ simplify_gen_binary (code, mode, op0, op1)
|
||||
|
||||
/* Put complex operands first and constants second if commutative. */
|
||||
if (GET_RTX_CLASS (code) == 'c'
|
||||
&& ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
|
||||
|| (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (op1)) != 'o')
|
||||
|| (GET_CODE (op0) == SUBREG
|
||||
&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
|
||||
&& swap_commutative_operands_p (op0, op1))
|
||||
tem = op0, op0 = op1, op1 = tem;
|
||||
|
||||
/* If this simplifies, do it. */
|
||||
@ -194,12 +189,7 @@ simplify_gen_relational (code, mode, cmp_mode, op0, op1)
|
||||
return tem;
|
||||
|
||||
/* Put complex operands first and constants second. */
|
||||
if ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
|
||||
|| (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (op1)) != 'o')
|
||||
|| (GET_CODE (op0) == SUBREG
|
||||
&& GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
|
||||
&& GET_RTX_CLASS (GET_CODE (op1)) != 'o'))
|
||||
if (swap_commutative_operands_p (op0, op1))
|
||||
tem = op0, op0 = op1, op1 = tem, code = swap_condition (code);
|
||||
|
||||
return gen_rtx_fmt_ee (code, mode, op0, op1);
|
||||
@ -2212,6 +2202,9 @@ simplify_subreg (outermode, op, innermode, byte)
|
||||
|| byte >= GET_MODE_SIZE (innermode))
|
||||
abort ();
|
||||
|
||||
if (outermode == innermode && !byte)
|
||||
return op;
|
||||
|
||||
/* Attempt to simplify constant to non-SUBREG expression. */
|
||||
if (CONSTANT_P (op))
|
||||
{
|
||||
@ -2388,6 +2381,19 @@ simplify_subreg (outermode, op, innermode, byte)
|
||||
MEM_COPY_ATTRIBUTES (new, op);
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Handle complex values represented as CONCAT
|
||||
of real and imaginary part. */
|
||||
if (GET_CODE (op) == CONCAT)
|
||||
{
|
||||
int is_realpart = byte < GET_MODE_UNIT_SIZE (innermode) / 2;
|
||||
rtx part = is_realpart ? XEXP (op, 0) : XEXP (op, 1);
|
||||
unsigned int final_offset;
|
||||
|
||||
final_offset = SUBREG_BYTE (op) % (GET_MODE_UNIT_SIZE (innermode) / 2);
|
||||
return simplify_subreg (outermode, part, GET_MODE (part), final_offset);
|
||||
}
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
/* Make a SUBREG operation or equivalent if it folds. */
|
||||
|
Loading…
Reference in New Issue
Block a user