2019-08-27 Richard Biener <rguenther@suse.de>
* config/i386/i386-features.h (general_scalar_chain::~general_scalar_chain): Add. (general_scalar_chain::insns_conv): New bitmap. (general_scalar_chain::n_sse_to_integer): New. (general_scalar_chain::n_integer_to_sse): Likewise. (general_scalar_chain::make_vector_copies): Adjust signature. * config/i386/i386-features.c (general_scalar_chain::general_scalar_chain): Outline, initialize new members. (general_scalar_chain::~general_scalar_chain): New. (general_scalar_chain::mark_dual_mode_def): Record insns we need to insert conversions at and count them. (general_scalar_chain::compute_convert_gain): Account for conversion instructions at chain boundary. (general_scalar_chain::make_vector_copies): Generate a single copy for a def by a specific insn. (general_scalar_chain::convert_registers): First populate defs_map, then make copies at out-of chain insns. From-SVN: r274953
This commit is contained in:
parent
6a07489267
commit
b5a6addb5b
3 changed files with 121 additions and 85 deletions
|
@ -1,3 +1,24 @@
|
|||
2019-08-27 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* config/i386/i386-features.h
|
||||
(general_scalar_chain::~general_scalar_chain): Add.
|
||||
(general_scalar_chain::insns_conv): New bitmap.
|
||||
(general_scalar_chain::n_sse_to_integer): New.
|
||||
(general_scalar_chain::n_integer_to_sse): Likewise.
|
||||
(general_scalar_chain::make_vector_copies): Adjust signature.
|
||||
* config/i386/i386-features.c
|
||||
(general_scalar_chain::general_scalar_chain): Outline,
|
||||
initialize new members.
|
||||
(general_scalar_chain::~general_scalar_chain): New.
|
||||
(general_scalar_chain::mark_dual_mode_def): Record insns
|
||||
we need to insert conversions at and count them.
|
||||
(general_scalar_chain::compute_convert_gain): Account
|
||||
for conversion instructions at chain boundary.
|
||||
(general_scalar_chain::make_vector_copies): Generate a single
|
||||
copy for a def by a specific insn.
|
||||
(general_scalar_chain::convert_registers): First populate
|
||||
defs_map, then make copies at out-of chain insns.
|
||||
|
||||
2019-08-27 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* config/arm/arm.md (stack_protect_set_insn): Add security-related
|
||||
|
|
|
@ -320,6 +320,20 @@ scalar_chain::add_to_queue (unsigned insn_uid)
|
|||
bitmap_set_bit (queue, insn_uid);
|
||||
}
|
||||
|
||||
general_scalar_chain::general_scalar_chain (enum machine_mode smode_,
|
||||
enum machine_mode vmode_)
|
||||
: scalar_chain (smode_, vmode_)
|
||||
{
|
||||
insns_conv = BITMAP_ALLOC (NULL);
|
||||
n_sse_to_integer = 0;
|
||||
n_integer_to_sse = 0;
|
||||
}
|
||||
|
||||
general_scalar_chain::~general_scalar_chain ()
|
||||
{
|
||||
BITMAP_FREE (insns_conv);
|
||||
}
|
||||
|
||||
/* For DImode conversion, mark register defined by DEF as requiring
|
||||
conversion. */
|
||||
|
||||
|
@ -328,15 +342,27 @@ general_scalar_chain::mark_dual_mode_def (df_ref def)
|
|||
{
|
||||
gcc_assert (DF_REF_REG_DEF_P (def));
|
||||
|
||||
if (bitmap_bit_p (defs_conv, DF_REF_REGNO (def)))
|
||||
return;
|
||||
|
||||
/* Record the def/insn pair so we can later efficiently iterate over
|
||||
the defs to convert on insns not in the chain. */
|
||||
bool reg_new = bitmap_set_bit (defs_conv, DF_REF_REGNO (def));
|
||||
if (!bitmap_bit_p (insns, DF_REF_INSN_UID (def)))
|
||||
{
|
||||
if (!bitmap_set_bit (insns_conv, DF_REF_INSN_UID (def))
|
||||
&& !reg_new)
|
||||
return;
|
||||
n_integer_to_sse++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reg_new)
|
||||
return;
|
||||
n_sse_to_integer++;
|
||||
}
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
" Mark r%d def in insn %d as requiring both modes in chain #%d\n",
|
||||
DF_REF_REGNO (def), DF_REF_INSN_UID (def), chain_id);
|
||||
|
||||
bitmap_set_bit (defs_conv, DF_REF_REGNO (def));
|
||||
}
|
||||
|
||||
/* For TImode conversion, it is unused. */
|
||||
|
@ -523,7 +549,7 @@ general_scalar_chain::compute_convert_gain ()
|
|||
|| GET_CODE (src) == ASHIFTRT
|
||||
|| GET_CODE (src) == LSHIFTRT)
|
||||
{
|
||||
if (CONST_INT_P (XEXP (src, 0)))
|
||||
if (CONST_INT_P (XEXP (src, 0)))
|
||||
igain -= vector_const_cost (XEXP (src, 0));
|
||||
igain += m * ix86_cost->shift_const - ix86_cost->sse_op;
|
||||
if (INTVAL (XEXP (src, 1)) >= 32)
|
||||
|
@ -588,9 +614,12 @@ general_scalar_chain::compute_convert_gain ()
|
|||
if (dump_file)
|
||||
fprintf (dump_file, " Instruction conversion gain: %d\n", gain);
|
||||
|
||||
/* ??? What about integer to SSE? */
|
||||
EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, insn_uid, bi)
|
||||
cost += DF_REG_DEF_COUNT (insn_uid) * ix86_cost->sse_to_integer;
|
||||
/* Cost the integer to sse and sse to integer moves. */
|
||||
cost += n_sse_to_integer * ix86_cost->sse_to_integer;
|
||||
/* ??? integer_to_sse but we only have that in the RA cost table.
|
||||
Assume sse_to_integer/integer_to_sse are the same which they
|
||||
are at the moment. */
|
||||
cost += n_integer_to_sse * ix86_cost->sse_to_integer;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, " Registers conversion cost: %d\n", cost);
|
||||
|
@ -649,85 +678,64 @@ gen_gpr_to_xmm_move_src (enum machine_mode vmode, rtx gpr)
|
|||
and replace its uses in a chain. */
|
||||
|
||||
void
|
||||
general_scalar_chain::make_vector_copies (unsigned regno)
|
||||
general_scalar_chain::make_vector_copies (rtx_insn *insn, rtx reg)
|
||||
{
|
||||
rtx reg = regno_reg_rtx[regno];
|
||||
rtx vreg = gen_reg_rtx (smode);
|
||||
df_ref ref;
|
||||
rtx vreg = *defs_map.get (reg);
|
||||
|
||||
defs_map.put (reg, vreg);
|
||||
|
||||
/* For each insn defining REGNO, see if it is defined by an insn
|
||||
not part of the chain but with uses in insns part of the chain
|
||||
and insert a copy in that case. */
|
||||
for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref))
|
||||
start_sequence ();
|
||||
if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
|
||||
{
|
||||
if (bitmap_bit_p (insns, DF_REF_INSN_UID (ref)))
|
||||
continue;
|
||||
df_link *use;
|
||||
for (use = DF_REF_CHAIN (ref); use; use = use->next)
|
||||
if (!DF_REF_REG_MEM_P (use->ref)
|
||||
&& bitmap_bit_p (insns, DF_REF_INSN_UID (use->ref)))
|
||||
break;
|
||||
if (!use)
|
||||
continue;
|
||||
|
||||
start_sequence ();
|
||||
if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
|
||||
rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP);
|
||||
if (smode == DImode && !TARGET_64BIT)
|
||||
{
|
||||
rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP);
|
||||
if (smode == DImode && !TARGET_64BIT)
|
||||
{
|
||||
emit_move_insn (adjust_address (tmp, SImode, 0),
|
||||
gen_rtx_SUBREG (SImode, reg, 0));
|
||||
emit_move_insn (adjust_address (tmp, SImode, 4),
|
||||
gen_rtx_SUBREG (SImode, reg, 4));
|
||||
}
|
||||
else
|
||||
emit_move_insn (copy_rtx (tmp), reg);
|
||||
emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
|
||||
gen_gpr_to_xmm_move_src (vmode, tmp)));
|
||||
}
|
||||
else if (!TARGET_64BIT && smode == DImode)
|
||||
{
|
||||
if (TARGET_SSE4_1)
|
||||
{
|
||||
emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_rtx_SUBREG (SImode, reg, 0)));
|
||||
emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (SImode, reg, 4),
|
||||
GEN_INT (2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_rtx_SUBREG (SImode, reg, 0)));
|
||||
emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_rtx_SUBREG (SImode, reg, 4)));
|
||||
emit_insn (gen_vec_interleave_lowv4si
|
||||
(gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (V4SImode, tmp, 0)));
|
||||
}
|
||||
emit_move_insn (adjust_address (tmp, SImode, 0),
|
||||
gen_rtx_SUBREG (SImode, reg, 0));
|
||||
emit_move_insn (adjust_address (tmp, SImode, 4),
|
||||
gen_rtx_SUBREG (SImode, reg, 4));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
|
||||
gen_gpr_to_xmm_move_src (vmode, reg)));
|
||||
rtx_insn *seq = get_insns ();
|
||||
end_sequence ();
|
||||
rtx_insn *insn = DF_REF_INSN (ref);
|
||||
emit_conversion_insns (seq, insn);
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
" Copied r%d to a vector register r%d for insn %d\n",
|
||||
regno, REGNO (vreg), INSN_UID (insn));
|
||||
emit_move_insn (copy_rtx (tmp), reg);
|
||||
emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
|
||||
gen_gpr_to_xmm_move_src (vmode, tmp)));
|
||||
}
|
||||
else if (!TARGET_64BIT && smode == DImode)
|
||||
{
|
||||
if (TARGET_SSE4_1)
|
||||
{
|
||||
emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_rtx_SUBREG (SImode, reg, 0)));
|
||||
emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (SImode, reg, 4),
|
||||
GEN_INT (2)));
|
||||
}
|
||||
else
|
||||
{
|
||||
rtx tmp = gen_reg_rtx (DImode);
|
||||
emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_rtx_SUBREG (SImode, reg, 0)));
|
||||
emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_rtx_SUBREG (SImode, reg, 4)));
|
||||
emit_insn (gen_vec_interleave_lowv4si
|
||||
(gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (V4SImode, vreg, 0),
|
||||
gen_rtx_SUBREG (V4SImode, tmp, 0)));
|
||||
}
|
||||
}
|
||||
else
|
||||
emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
|
||||
gen_gpr_to_xmm_move_src (vmode, reg)));
|
||||
rtx_insn *seq = get_insns ();
|
||||
end_sequence ();
|
||||
emit_conversion_insns (seq, insn);
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
" Copied r%d to a vector register r%d for insn %d\n",
|
||||
REGNO (reg), REGNO (vreg), INSN_UID (insn));
|
||||
}
|
||||
|
||||
/* Copy the definition SRC of INSN inside the chain to DST for
|
||||
|
@ -1158,7 +1166,11 @@ general_scalar_chain::convert_registers ()
|
|||
bitmap_iterator bi;
|
||||
unsigned id;
|
||||
EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, id, bi)
|
||||
make_vector_copies (id);
|
||||
defs_map.put (regno_reg_rtx[id], gen_reg_rtx (smode));
|
||||
EXECUTE_IF_SET_IN_BITMAP (insns_conv, 0, id, bi)
|
||||
for (df_ref ref = DF_INSN_UID_DEFS (id); ref; ref = DF_REF_NEXT_LOC (ref))
|
||||
if (bitmap_bit_p (defs_conv, DF_REF_REGNO (ref)))
|
||||
make_vector_copies (DF_REF_INSN (ref), DF_REF_REAL_REG (ref));
|
||||
}
|
||||
|
||||
/* Convert whole chain creating required register
|
||||
|
|
|
@ -167,16 +167,19 @@ class scalar_chain
|
|||
class general_scalar_chain : public scalar_chain
|
||||
{
|
||||
public:
|
||||
general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_)
|
||||
: scalar_chain (smode_, vmode_) {}
|
||||
general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_);
|
||||
~general_scalar_chain ();
|
||||
int compute_convert_gain ();
|
||||
private:
|
||||
hash_map<rtx, rtx> defs_map;
|
||||
bitmap insns_conv;
|
||||
unsigned n_sse_to_integer;
|
||||
unsigned n_integer_to_sse;
|
||||
void mark_dual_mode_def (df_ref def);
|
||||
void convert_insn (rtx_insn *insn);
|
||||
void convert_op (rtx *op, rtx_insn *insn);
|
||||
void convert_reg (rtx_insn *insn, rtx dst, rtx src);
|
||||
void make_vector_copies (unsigned regno);
|
||||
void make_vector_copies (rtx_insn *, rtx);
|
||||
void convert_registers ();
|
||||
int vector_const_cost (rtx exp);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue