i386: Unify {general,timode}_scalar_chain::convert_op [PR111822]
Recent PR111822 fix implemented REG_EH_REGION note copying to a STV converted preload instruction in general_scalar_chain::convert_op. However, the same issue remains in timode_scalar_chain::convert_op. Instead of copying the newly introduced code to timode_scalar_chain::convert_op, the patch unifies both functions to a common function. PR target/111822 gcc/ChangeLog: * config/i386/i386-features.cc (smode_convert_cst): New function to handle SImode, DImode and TImode immediates, generalized from timode_convert_cst. (timode_convert_cst): Remove. (scalar_chain::convert_op): Unify from general_scalar_chain::convert_op and timode_scalar_chain::convert_op. (general_scalar_chain::convert_op): Remove. (timode_scalar_chain::convert_op): Remove. (timode_scalar_chain::convert_insn): Update the call to renamed timode_convert_cst. * config/i386/i386-features.h (class scalar_chain): Redeclare convert_op as protected class member. (class general_calar_chain): Remove convert_op. (class timode_scalar_chain): Ditto. gcc/testsuite/ChangeLog: * g++.target/i386/pr111822.C (dg-do): Compile only for ia32 targets. (dg-options): Add -march=x86-64.
This commit is contained in:
parent
3be2b8f475
commit
b96c543688
3 changed files with 40 additions and 95 deletions
|
@ -980,14 +980,35 @@ scalar_chain::convert_reg (rtx_insn *insn, rtx dst, rtx src)
|
|||
REGNO (src), REGNO (dst), INSN_UID (insn));
|
||||
}
|
||||
|
||||
/* Helper function to convert immediate constant X to vmode. */
|
||||
static rtx
|
||||
smode_convert_cst (rtx x, enum machine_mode vmode)
|
||||
{
|
||||
/* Prefer all ones vector in case of -1. */
|
||||
if (constm1_operand (x, GET_MODE (x)))
|
||||
return CONSTM1_RTX (vmode);
|
||||
|
||||
unsigned n = GET_MODE_NUNITS (vmode);
|
||||
rtx *v = XALLOCAVEC (rtx, n);
|
||||
v[0] = x;
|
||||
for (unsigned i = 1; i < n; ++i)
|
||||
v[i] = const0_rtx;
|
||||
return gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (n, v));
|
||||
}
|
||||
|
||||
/* Convert operand OP in INSN. We should handle
|
||||
memory operands and uninitialized registers.
|
||||
All other register uses are converted during
|
||||
registers conversion. */
|
||||
|
||||
void
|
||||
general_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
|
||||
scalar_chain::convert_op (rtx *op, rtx_insn *insn)
|
||||
{
|
||||
rtx tmp;
|
||||
|
||||
if (GET_MODE (*op) == V1TImode)
|
||||
return;
|
||||
|
||||
*op = copy_rtx_if_shared (*op);
|
||||
|
||||
if (GET_CODE (*op) == NOT
|
||||
|
@ -998,20 +1019,21 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
|
|||
}
|
||||
else if (MEM_P (*op))
|
||||
{
|
||||
rtx_insn* eh_insn, *movabs = NULL;
|
||||
rtx tmp = gen_reg_rtx (GET_MODE (*op));
|
||||
rtx_insn *movabs = NULL;
|
||||
|
||||
/* Emit MOVABS to load from a 64-bit absolute address to a GPR. */
|
||||
if (!memory_operand (*op, GET_MODE (*op)))
|
||||
{
|
||||
rtx tmp2 = gen_reg_rtx (GET_MODE (*op));
|
||||
movabs = emit_insn_before (gen_rtx_SET (tmp2, *op), insn);
|
||||
tmp = gen_reg_rtx (GET_MODE (*op));
|
||||
movabs = emit_insn_before (gen_rtx_SET (tmp, *op), insn);
|
||||
|
||||
*op = tmp2;
|
||||
*op = tmp;
|
||||
}
|
||||
|
||||
eh_insn
|
||||
= emit_insn_before (gen_rtx_SET (gen_rtx_SUBREG (vmode, tmp, 0),
|
||||
tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (GET_MODE (*op)), 0);
|
||||
|
||||
rtx_insn *eh_insn
|
||||
= emit_insn_before (gen_rtx_SET (copy_rtx (tmp),
|
||||
gen_gpr_to_xmm_move_src (vmode, *op)),
|
||||
insn);
|
||||
|
||||
|
@ -1028,33 +1050,17 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
|
|||
}
|
||||
}
|
||||
|
||||
*op = gen_rtx_SUBREG (vmode, tmp, 0);
|
||||
*op = tmp;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " Preloading operand for insn %d into r%d\n",
|
||||
INSN_UID (insn), REGNO (tmp));
|
||||
}
|
||||
else if (REG_P (*op))
|
||||
*op = gen_rtx_SUBREG (vmode, *op, 0);
|
||||
else if (CONST_SCALAR_INT_P (*op))
|
||||
{
|
||||
*op = gen_rtx_SUBREG (vmode, *op, 0);
|
||||
}
|
||||
else if (CONST_INT_P (*op))
|
||||
{
|
||||
rtx vec_cst;
|
||||
rtx tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (smode), 0);
|
||||
|
||||
/* Prefer all ones vector in case of -1. */
|
||||
if (constm1_operand (*op, GET_MODE (*op)))
|
||||
vec_cst = CONSTM1_RTX (vmode);
|
||||
else
|
||||
{
|
||||
unsigned n = GET_MODE_NUNITS (vmode);
|
||||
rtx *v = XALLOCAVEC (rtx, n);
|
||||
v[0] = *op;
|
||||
for (unsigned i = 1; i < n; ++i)
|
||||
v[i] = const0_rtx;
|
||||
vec_cst = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (n, v));
|
||||
}
|
||||
rtx vec_cst = smode_convert_cst (*op, vmode);
|
||||
|
||||
if (!standard_sse_constant_p (vec_cst, vmode))
|
||||
{
|
||||
|
@ -1065,6 +1071,8 @@ general_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
|
|||
emit_insn_before (seq, insn);
|
||||
}
|
||||
|
||||
tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (smode), 0);
|
||||
|
||||
emit_insn_before (gen_move_insn (copy_rtx (tmp), vec_cst), insn);
|
||||
*op = tmp;
|
||||
}
|
||||
|
@ -1767,67 +1775,6 @@ timode_scalar_chain::fix_debug_reg_uses (rtx reg)
|
|||
}
|
||||
}
|
||||
|
||||
/* Helper function to convert immediate constant X to V1TImode. */
|
||||
static rtx
|
||||
timode_convert_cst (rtx x)
|
||||
{
|
||||
/* Prefer all ones vector in case of -1. */
|
||||
if (constm1_operand (x, TImode))
|
||||
return CONSTM1_RTX (V1TImode);
|
||||
|
||||
rtx *v = XALLOCAVEC (rtx, 1);
|
||||
v[0] = x;
|
||||
return gen_rtx_CONST_VECTOR (V1TImode, gen_rtvec_v (1, v));
|
||||
}
|
||||
|
||||
/* Convert operand OP in INSN from TImode to V1TImode. */
|
||||
|
||||
void
|
||||
timode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
|
||||
{
|
||||
if (GET_MODE (*op) == V1TImode)
|
||||
return;
|
||||
|
||||
*op = copy_rtx_if_shared (*op);
|
||||
|
||||
if (REG_P (*op))
|
||||
*op = gen_rtx_SUBREG (V1TImode, *op, 0);
|
||||
else if (MEM_P (*op))
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (V1TImode);
|
||||
emit_insn_before (gen_rtx_SET (tmp,
|
||||
gen_gpr_to_xmm_move_src (V1TImode, *op)),
|
||||
insn);
|
||||
*op = tmp;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " Preloading operand for insn %d into r%d\n",
|
||||
INSN_UID (insn), REGNO (tmp));
|
||||
}
|
||||
else if (CONST_SCALAR_INT_P (*op))
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (V1TImode);
|
||||
rtx vec_cst = timode_convert_cst (*op);
|
||||
|
||||
if (!standard_sse_constant_p (vec_cst, V1TImode))
|
||||
{
|
||||
start_sequence ();
|
||||
vec_cst = validize_mem (force_const_mem (V1TImode, vec_cst));
|
||||
rtx_insn *seq = get_insns ();
|
||||
end_sequence ();
|
||||
emit_insn_before (seq, insn);
|
||||
}
|
||||
|
||||
emit_insn_before (gen_move_insn (tmp, vec_cst), insn);
|
||||
*op = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (SUBREG_P (*op));
|
||||
gcc_assert (GET_MODE (*op) == vmode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert INSN from TImode to V1T1mode. */
|
||||
|
||||
void
|
||||
|
@ -1892,7 +1839,7 @@ timode_scalar_chain::convert_insn (rtx_insn *insn)
|
|||
}
|
||||
else
|
||||
{
|
||||
src = timode_convert_cst (src);
|
||||
src = smode_convert_cst (src, V1TImode);
|
||||
src = validize_mem (force_const_mem (V1TImode, src));
|
||||
use_move = MEM_P (dst);
|
||||
}
|
||||
|
|
|
@ -170,13 +170,13 @@ class scalar_chain
|
|||
void convert_insn_common (rtx_insn *insn);
|
||||
void make_vector_copies (rtx_insn *, rtx);
|
||||
void convert_registers ();
|
||||
void convert_op (rtx *op, rtx_insn *insn);
|
||||
|
||||
private:
|
||||
bool add_insn (bitmap candidates, unsigned insn_uid, bitmap disallowed);
|
||||
bool analyze_register_chain (bitmap candidates, df_ref ref,
|
||||
bitmap disallowed);
|
||||
virtual void convert_insn (rtx_insn *insn) = 0;
|
||||
virtual void convert_op (rtx *op, rtx_insn *insn) = 0;
|
||||
};
|
||||
|
||||
class general_scalar_chain : public scalar_chain
|
||||
|
@ -188,7 +188,6 @@ class general_scalar_chain : public scalar_chain
|
|||
|
||||
private:
|
||||
void convert_insn (rtx_insn *insn) final override;
|
||||
void convert_op (rtx *op, rtx_insn *insn) final override;
|
||||
int vector_const_cost (rtx exp);
|
||||
rtx convert_rotate (enum rtx_code, rtx op0, rtx op1, rtx_insn *insn);
|
||||
};
|
||||
|
@ -202,7 +201,6 @@ class timode_scalar_chain : public scalar_chain
|
|||
private:
|
||||
void fix_debug_reg_uses (rtx reg);
|
||||
void convert_insn (rtx_insn *insn) final override;
|
||||
void convert_op (rtx *op, rtx_insn *insn) final override;
|
||||
};
|
||||
|
||||
} // anon namespace
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* PR target/111822 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -flive-range-shrinkage -fno-dce -fnon-call-exceptions" } */
|
||||
/* { dg-do compile { target ia32 } } */
|
||||
/* { dg-options "-O2 -flive-range-shrinkage -fno-dce -fnon-call-exceptions -march=x86-64" } */
|
||||
|
||||
typedef union {
|
||||
int *pNativeClosure;
|
||||
|
|
Loading…
Add table
Reference in a new issue