mirror of git://gcc.gnu.org/git/gcc.git
re PR rtl-optimization/50339 (suboptimal register allocation for abs(__int128_t))
PR rtl-optimization/50339 * lower-subreg.h (struct lower_subreg_choices): Add splitting_ashiftrt field. * lower-subreg.c (compute_splitting_shift): Handle ASHIFTRT. (compute_costs): Call compute_splitting_shift also for ASHIFTRT into splitting_ashiftrt field. (find_decomposable_shift_zext, resolve_shift_zext): Handle also ASHIFTRT. (dump_choices): Fix up printing LSHIFTRT choices, print ASHIFTRT choices. From-SVN: r196214
This commit is contained in:
parent
6aad44556a
commit
d7fde18c2a
|
|
@ -1,3 +1,16 @@
|
|||
2013-02-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR rtl-optimization/50339
|
||||
* lower-subreg.h (struct lower_subreg_choices): Add splitting_ashiftrt
|
||||
field.
|
||||
* lower-subreg.c (compute_splitting_shift): Handle ASHIFTRT.
|
||||
(compute_costs): Call compute_splitting_shift also for ASHIFTRT
|
||||
into splitting_ashiftrt field.
|
||||
(find_decomposable_shift_zext, resolve_shift_zext): Handle also
|
||||
ASHIFTRT.
|
||||
(dump_choices): Fix up printing LSHIFTRT choices, print ASHIFTRT
|
||||
choices.
|
||||
|
||||
2013-02-20 Aldy Hernandez <aldyh@redhat.com>
|
||||
|
||||
PR middle-end/56108
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ along with GCC; see the file COPYING3. If not see
|
|||
to do this.
|
||||
|
||||
This pass only splits moves with modes that are wider than
|
||||
word_mode and ASHIFTs, LSHIFTRTs and ZERO_EXTENDs with integer
|
||||
modes that are twice the width of word_mode. The latter could be
|
||||
generalized if there was a need to do this, but the trend in
|
||||
word_mode and ASHIFTs, LSHIFTRTs, ASHIFTRTs and ZERO_EXTENDs with
|
||||
integer modes that are twice the width of word_mode. The latter
|
||||
could be generalized if there was a need to do this, but the trend in
|
||||
architectures is to not need this.
|
||||
|
||||
There are two useful preprocessor defines for use by maintainers:
|
||||
|
|
@ -152,7 +152,7 @@ compute_splitting_shift (bool speed_p, struct cost_rtxes *rtxes,
|
|||
bool *splitting, enum rtx_code code,
|
||||
int word_move_zero_cost, int word_move_cost)
|
||||
{
|
||||
int wide_cost, narrow_cost, i;
|
||||
int wide_cost, narrow_cost, upper_cost, i;
|
||||
|
||||
for (i = 0; i < BITS_PER_WORD; i++)
|
||||
{
|
||||
|
|
@ -163,13 +163,20 @@ compute_splitting_shift (bool speed_p, struct cost_rtxes *rtxes,
|
|||
else
|
||||
narrow_cost = shift_cost (speed_p, rtxes, code, word_mode, i);
|
||||
|
||||
if (code != ASHIFTRT)
|
||||
upper_cost = word_move_zero_cost;
|
||||
else if (i == BITS_PER_WORD - 1)
|
||||
upper_cost = word_move_cost;
|
||||
else
|
||||
upper_cost = shift_cost (speed_p, rtxes, code, word_mode,
|
||||
BITS_PER_WORD - 1);
|
||||
|
||||
if (LOG_COSTS)
|
||||
fprintf (stderr, "%s %s by %d: original cost %d, split cost %d + %d\n",
|
||||
GET_MODE_NAME (twice_word_mode), GET_RTX_NAME (code),
|
||||
i + BITS_PER_WORD, wide_cost, narrow_cost,
|
||||
word_move_zero_cost);
|
||||
i + BITS_PER_WORD, wide_cost, narrow_cost, upper_cost);
|
||||
|
||||
if (FORCE_LOWERING || wide_cost >= narrow_cost + word_move_zero_cost)
|
||||
if (FORCE_LOWERING || wide_cost >= narrow_cost + upper_cost)
|
||||
splitting[i] = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -248,6 +255,9 @@ compute_costs (bool speed_p, struct cost_rtxes *rtxes)
|
|||
compute_splitting_shift (speed_p, rtxes,
|
||||
choices[speed_p].splitting_lshiftrt, LSHIFTRT,
|
||||
word_move_zero_cost, word_move_cost);
|
||||
compute_splitting_shift (speed_p, rtxes,
|
||||
choices[speed_p].splitting_ashiftrt, ASHIFTRT,
|
||||
word_move_zero_cost, word_move_cost);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1153,6 +1163,7 @@ find_decomposable_shift_zext (rtx insn, bool speed_p)
|
|||
op = SET_SRC (set);
|
||||
if (GET_CODE (op) != ASHIFT
|
||||
&& GET_CODE (op) != LSHIFTRT
|
||||
&& GET_CODE (op) != ASHIFTRT
|
||||
&& GET_CODE (op) != ZERO_EXTEND)
|
||||
return false;
|
||||
|
||||
|
|
@ -1173,6 +1184,8 @@ find_decomposable_shift_zext (rtx insn, bool speed_p)
|
|||
{
|
||||
bool *splitting = (GET_CODE (op) == ASHIFT
|
||||
? choices[speed_p].splitting_ashift
|
||||
: GET_CODE (op) == ASHIFTRT
|
||||
? choices[speed_p].splitting_ashiftrt
|
||||
: choices[speed_p].splitting_lshiftrt);
|
||||
if (!CONST_INT_P (XEXP (op, 1))
|
||||
|| !IN_RANGE (INTVAL (XEXP (op, 1)), BITS_PER_WORD,
|
||||
|
|
@ -1200,7 +1213,7 @@ resolve_shift_zext (rtx insn)
|
|||
rtx op;
|
||||
rtx op_operand;
|
||||
rtx insns;
|
||||
rtx src_reg, dest_reg, dest_zero;
|
||||
rtx src_reg, dest_reg, dest_upper, upper_src = NULL_RTX;
|
||||
int src_reg_num, dest_reg_num, offset1, offset2, src_offset;
|
||||
|
||||
set = single_set (insn);
|
||||
|
|
@ -1210,6 +1223,7 @@ resolve_shift_zext (rtx insn)
|
|||
op = SET_SRC (set);
|
||||
if (GET_CODE (op) != ASHIFT
|
||||
&& GET_CODE (op) != LSHIFTRT
|
||||
&& GET_CODE (op) != ASHIFTRT
|
||||
&& GET_CODE (op) != ZERO_EXTEND)
|
||||
return NULL_RTX;
|
||||
|
||||
|
|
@ -1223,7 +1237,8 @@ resolve_shift_zext (rtx insn)
|
|||
/* src_reg_num is the number of the word mode register which we
|
||||
are operating on. For a left shift and a zero_extend on little
|
||||
endian machines this is register 0. */
|
||||
src_reg_num = GET_CODE (op) == LSHIFTRT ? 1 : 0;
|
||||
src_reg_num = (GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT)
|
||||
? 1 : 0;
|
||||
|
||||
if (WORDS_BIG_ENDIAN
|
||||
&& GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD)
|
||||
|
|
@ -1243,12 +1258,17 @@ resolve_shift_zext (rtx insn)
|
|||
dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
|
||||
GET_MODE (SET_DEST (set)),
|
||||
offset1);
|
||||
dest_zero = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
|
||||
GET_MODE (SET_DEST (set)),
|
||||
offset2);
|
||||
dest_upper = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
|
||||
GET_MODE (SET_DEST (set)),
|
||||
offset2);
|
||||
src_reg = simplify_gen_subreg_concatn (word_mode, op_operand,
|
||||
GET_MODE (op_operand),
|
||||
src_offset);
|
||||
if (GET_CODE (op) == ASHIFTRT
|
||||
&& INTVAL (XEXP (op, 1)) != 2 * BITS_PER_WORD - 1)
|
||||
upper_src = expand_shift (RSHIFT_EXPR, word_mode, copy_rtx (src_reg),
|
||||
BITS_PER_WORD - 1, NULL_RTX, 0);
|
||||
|
||||
if (GET_CODE (op) != ZERO_EXTEND)
|
||||
{
|
||||
int shift_count = INTVAL (XEXP (op, 1));
|
||||
|
|
@ -1257,12 +1277,17 @@ resolve_shift_zext (rtx insn)
|
|||
LSHIFT_EXPR : RSHIFT_EXPR,
|
||||
word_mode, src_reg,
|
||||
shift_count - BITS_PER_WORD,
|
||||
dest_reg, 1);
|
||||
dest_reg, GET_CODE (op) != ASHIFTRT);
|
||||
}
|
||||
|
||||
if (dest_reg != src_reg)
|
||||
emit_move_insn (dest_reg, src_reg);
|
||||
emit_move_insn (dest_zero, CONST0_RTX (word_mode));
|
||||
if (GET_CODE (op) != ASHIFTRT)
|
||||
emit_move_insn (dest_upper, CONST0_RTX (word_mode));
|
||||
else if (INTVAL (XEXP (op, 1)) == 2 * BITS_PER_WORD - 1)
|
||||
emit_move_insn (dest_upper, copy_rtx (src_reg));
|
||||
else
|
||||
emit_move_insn (dest_upper, upper_src);
|
||||
insns = get_insns ();
|
||||
|
||||
end_sequence ();
|
||||
|
|
@ -1328,7 +1353,8 @@ dump_choices (bool speed_p, const char *description)
|
|||
GET_MODE_NAME (twice_word_mode));
|
||||
|
||||
dump_shift_choices (ASHIFT, choices[speed_p].splitting_ashift);
|
||||
dump_shift_choices (LSHIFTRT, choices[speed_p].splitting_ashift);
|
||||
dump_shift_choices (LSHIFTRT, choices[speed_p].splitting_lshiftrt);
|
||||
dump_shift_choices (ASHIFTRT, choices[speed_p].splitting_ashiftrt);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ struct lower_subreg_choices {
|
|||
should be split. */
|
||||
bool splitting_ashift[MAX_BITS_PER_WORD];
|
||||
bool splitting_lshiftrt[MAX_BITS_PER_WORD];
|
||||
bool splitting_ashiftrt[MAX_BITS_PER_WORD];
|
||||
|
||||
/* True if there is at least one mode that is worth splitting. */
|
||||
bool something_to_do;
|
||||
|
|
|
|||
Loading…
Reference in New Issue