Commit 38e60111 by Peter Bergner Committed by Peter Bergner

re PR rtl-optimization/87507 (IRA unnecessarily uses non-volatile registers…

re PR rtl-optimization/87507 (IRA unnecessarily uses non-volatile registers during register assignment)

gcc/
	PR rtl-optimization/87507
	* lower-subreg.c (operand_for_swap_move_operator): New function.
	(simple_move): Strip simple operators.
	(find_pseudo_copy): Likewise.
	(resolve_operand_for_swap_move_operator): New function.
	(resolve_simple_move): Strip simple operators and swap operands.

gcc/testsuite/
	PR rtl-optimization/87507
	* gcc.target/powerpc/pr87507.c: New test.
	* gcc.target/powerpc/pr68805.c: Update expected results.

From-SVN: r266097
parent 72931dea
2018-11-13 Peter Bergner <bergner@linux.ibm.com>
PR rtl-optimization/87507
* lower-subreg.c (operand_for_swap_move_operator): New function.
(simple_move): Strip simple operators.
(find_pseudo_copy): Likewise.
(resolve_operand_for_swap_move_operator): New function.
(resolve_simple_move): Strip simple operators and swap operands.
2018-11-13 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/87898
......@@ -320,6 +320,24 @@ simple_move_operand (rtx x)
return true;
}
/* If X is an operator that can be treated as a simple move that we
can split, then return the operand that is operated on. */
static rtx
operand_for_swap_move_operator (rtx x)
{
/* A word sized rotate of a register pair is equivalent to swapping
the registers in the register pair. */
if (GET_CODE (x) == ROTATE
&& GET_MODE (x) == twice_word_mode
&& simple_move_operand (XEXP (x, 0))
&& CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) == BITS_PER_WORD)
return XEXP (x, 0);
return NULL_RTX;
}
/* If INSN is a single set between two objects that we want to split,
return the single set. SPEED_P says whether we are optimizing
INSN for speed or size.
......@@ -330,7 +348,7 @@ simple_move_operand (rtx x)
static rtx
simple_move (rtx_insn *insn, bool speed_p)
{
rtx x;
rtx x, op;
rtx set;
machine_mode mode;
......@@ -348,6 +366,9 @@ simple_move (rtx_insn *insn, bool speed_p)
return NULL_RTX;
x = SET_SRC (set);
if ((op = operand_for_swap_move_operator (x)) != NULL_RTX)
x = op;
if (x != recog_data.operand[0] && x != recog_data.operand[1])
return NULL_RTX;
/* For the src we can handle ASM_OPERANDS, and it is beneficial for
......@@ -386,9 +407,13 @@ find_pseudo_copy (rtx set)
{
rtx dest = SET_DEST (set);
rtx src = SET_SRC (set);
rtx op;
unsigned int rd, rs;
bitmap b;
if ((op = operand_for_swap_move_operator (src)) != NULL_RTX)
src = op;
if (!REG_P (dest) || !REG_P (src))
return false;
......@@ -846,6 +871,21 @@ can_decompose_p (rtx x)
return true;
}
/* OPND is a concatn operand this is used with a simple move operator.
Return a new rtx with the concatn's operands swapped. */
static rtx
resolve_operand_for_swap_move_operator (rtx opnd)
{
gcc_assert (GET_CODE (opnd) == CONCATN);
rtx concatn = copy_rtx (opnd);
rtx op0 = XVECEXP (concatn, 0, 0);
rtx op1 = XVECEXP (concatn, 0, 1);
XVECEXP (concatn, 0, 0) = op1;
XVECEXP (concatn, 0, 1) = op0;
return concatn;
}
/* Decompose the registers used in a simple move SET within INSN. If
we don't change anything, return INSN, otherwise return the start
of the sequence of moves. */
......@@ -853,7 +893,7 @@ can_decompose_p (rtx x)
static rtx_insn *
resolve_simple_move (rtx set, rtx_insn *insn)
{
rtx src, dest, real_dest;
rtx src, dest, real_dest, src_op;
rtx_insn *insns;
machine_mode orig_mode, dest_mode;
unsigned int orig_size, words;
......@@ -876,6 +916,23 @@ resolve_simple_move (rtx set, rtx_insn *insn)
real_dest = NULL_RTX;
if ((src_op = operand_for_swap_move_operator (src)) != NULL_RTX)
{
if (resolve_reg_p (dest))
{
/* DEST is a CONCATN, so swap its operands and strip
SRC's operator. */
dest = resolve_operand_for_swap_move_operator (dest);
src = src_op;
}
else if (resolve_reg_p (src_op))
{
/* SRC is an operation on a CONCATN, so strip the operator and
swap the CONCATN's operands. */
src = resolve_operand_for_swap_move_operator (src_op);
}
}
if (GET_CODE (src) == SUBREG
&& resolve_reg_p (SUBREG_REG (src))
&& (maybe_ne (SUBREG_BYTE (src), 0)
......
2018-11-13 Peter Bergner <bergner@linux.ibm.com>
PR rtl-optimization/87507
* gcc.target/powerpc/pr87507.c: New test.
* gcc.target/powerpc/pr68805.c: Update expected results.
2018-11-13 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/87898
......
......@@ -9,7 +9,7 @@ typedef struct bar {
void foo (TYPE *p, TYPE *q) { *p = *q; }
/* { dg-final { scan-assembler "lxvd2x" } } */
/* { dg-final { scan-assembler "stxvd2x" } } */
/* { dg-final { scan-assembler-times {\mld\M} 2 } } */
/* { dg-final { scan-assembler-times {\mstd\M} 2 } } */
/* { dg-final { scan-assembler-not "xxpermdi" } } */
/* { dg-do compile { target powerpc64le-*-* } } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
/* { dg-options "-O2 -mcpu=power8" } */
typedef struct
{
__int128_t x;
__int128_t y;
} foo_t;
void
foo (long cond, foo_t *dst, __int128_t src)
{
if (cond)
{
dst->x = src;
dst->y = src;
}
}
/* { dg-final { scan-assembler-times {\mstd\M} 4 } } */
/* { dg-final { scan-assembler-not {\mld\M} } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment