re PR target/53250 ([SH] ICE: in change_address_1, at emit-rtl.c:2018)

PR target/53250
	* config/i386/i386.c (ix86_set_reg_reg_cost): New function.
	(ix86_rtx_costs): Handle SET.

From-SVN: r187289
This commit is contained in:
Uros Bizjak 2012-05-08 18:01:54 +02:00
parent bcc708fcdc
commit 3f3dcbb393
2 changed files with 62 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2012-05-08 Uros Bizjak <ubizjak@gmail.com>
PR target/53250
* config/i386/i386.c (ix86_set_reg_reg_cost): New function.
(ix86_rtx_costs): Handle SET.
2012-05-08 Michael Matz <matz@suse.de> 2012-05-08 Michael Matz <matz@suse.de>
* basic-block.h (struct rtl_bb_info): Remove visited member and * basic-block.h (struct rtl_bb_info): Remove visited member and
@ -15,8 +21,7 @@
(fixup_fallthru_exit_predecessor): Ditto. (fixup_fallthru_exit_predecessor): Ditto.
(cfg_layout_duplicate_bb): Ditto. (cfg_layout_duplicate_bb): Ditto.
* combine.c (update_cfg_for_uncondjump): Adjust. * combine.c (update_cfg_for_uncondjump): Adjust.
* bb-reorder.c (struct bbro_basic_block_data_def): Add visited * bb-reorder.c (struct bbro_basic_block_data_def): Add visited member.
member.
(bb_visited_trace): New accessor. (bb_visited_trace): New accessor.
(mark_bb_visited): Move in front. (mark_bb_visited): Move in front.
(rotate_loop): Use bb_visited_trace. (rotate_loop): Use bb_visited_trace.

View File

@ -31861,6 +31861,52 @@ ix86_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
return false; return false;
} }
/* Return the cost of moving between two registers of mode MODE. */
static int
ix86_set_reg_reg_cost (enum machine_mode mode)
{
unsigned int units = UNITS_PER_WORD;
switch (GET_MODE_CLASS (mode))
{
default:
break;
case MODE_CC:
units = GET_MODE_SIZE (CCmode);
break;
case MODE_FLOAT:
if ((TARGET_SSE2 && mode == TFmode)
|| (TARGET_80387 && mode == XFmode)
|| ((TARGET_80387 || TARGET_SSE2) && mode == DFmode)
|| ((TARGET_80387 || TARGET_SSE) && mode == SFmode))
units = GET_MODE_SIZE (mode);
break;
case MODE_COMPLEX_FLOAT:
if ((TARGET_SSE2 && mode == TCmode)
|| (TARGET_80387 && mode == XCmode)
|| ((TARGET_80387 || TARGET_SSE2) && mode == DCmode)
|| ((TARGET_80387 || TARGET_SSE) && mode == SCmode))
units = GET_MODE_SIZE (mode);
break;
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
if ((TARGET_AVX && VALID_AVX256_REG_MODE (mode))
|| (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
|| (TARGET_SSE && VALID_SSE_REG_MODE (mode))
|| (TARGET_MMX && VALID_MMX_REG_MODE (mode)))
units = GET_MODE_SIZE (mode);
}
/* Return the cost of moving between two registers of mode MODE,
assuming that the move will be in pieces of at most UNITS bytes. */
return COSTS_N_INSNS ((GET_MODE_SIZE (mode) + units - 1) / units);
}
/* Compute a (partial) cost for rtx X. Return true if the complete /* Compute a (partial) cost for rtx X. Return true if the complete
cost has been computed, and false if subexpressions should be cost has been computed, and false if subexpressions should be
scanned. In either case, *TOTAL contains the cost result. */ scanned. In either case, *TOTAL contains the cost result. */
@ -31875,6 +31921,15 @@ ix86_rtx_costs (rtx x, int code, int outer_code_i, int opno, int *total,
switch (code) switch (code)
{ {
case SET:
if (register_operand (SET_DEST (x), VOIDmode)
&& reg_or_0_operand (SET_SRC (x), VOIDmode))
{
*total = ix86_set_reg_reg_cost (GET_MODE (SET_DEST (x)));
return true;
}
return false;
case CONST_INT: case CONST_INT:
case CONST: case CONST:
case LABEL_REF: case LABEL_REF: