i386-protos.h (ix86_split_lea_for_addr): Add additional argument.

2012-08-16  Yuri Rumyantsev  <ysrumyan@gmail.com>

	* config/i386/i386-protos.h (ix86_split_lea_for_addr) : Add
	additional argument.
	* config/i386/i386.md (ix86_split_lea_for_addr) : Add
	additional argument curr_insn.
	* config/i386/i386.c (ix86_split_lea_for_addr): Load base or index
	register first, depending on their defintion distances.
	(ix86_lea_outperforms): Prefer LEA only if split cost exceeds
	AGU stall.
	(find_nearest_reg-def): New function. Find register with
	nearest definition.

From-SVN: r190452
This commit is contained in:
Yuri Rumyantsev 2012-08-16 21:58:11 +02:00 committed by Uros Bizjak
parent fd19949184
commit af7c3fe7aa
4 changed files with 63 additions and 8 deletions

View File

@ -1,3 +1,16 @@
2012-08-16 Yuri Rumyantsev <ysrumyan@gmail.com>
* config/i386/i386-protos.h (ix86_split_lea_for_addr) : Add
additional argument.
* config/i386/i386.md (ix86_split_lea_for_addr) : Add
additional argument curr_insn.
* config/i386/i386.c (ix86_split_lea_for_addr): Load base or index
register first, depending on their defintion distances.
(ix86_lea_outperforms): Prefer LEA only if split cost exceeds
AGU stall.
(find_nearest_reg-def): New function. Find register with
nearest definition.
2012-08-16 Walter Lee <walt@tilera.com>
* config.gcc (tilegx-*-linux*): Add feedback.h.
@ -74,7 +87,7 @@
* config/avr/t-avr: Replace occurrences of $(CC) with $(COMPILER).
* config/avr/avr.c (avr_legitimize_reload_address): Add casts
for reload_type enums.
(DEF_BUILTIN): Cast the icode to enum insn_code.
(DEF_BUILTIN): Cast the icode to enum insn_code.
2012-08-15 Segher Boessenkool <segher@kernel.crashing.org>

View File

@ -95,7 +95,7 @@ extern bool ix86_binary_operator_ok (enum rtx_code, enum machine_mode, rtx[]);
extern bool ix86_avoid_lea_for_add (rtx, rtx[]);
extern bool ix86_use_lea_for_mov (rtx, rtx[]);
extern bool ix86_avoid_lea_for_addr (rtx, rtx[]);
extern void ix86_split_lea_for_addr (rtx[], enum machine_mode);
extern void ix86_split_lea_for_addr (rtx, rtx[], enum machine_mode);
extern bool ix86_lea_for_add_ok (rtx, rtx[]);
extern bool ix86_vec_interleave_v2df_operator_ok (rtx operands[3], bool high);
extern bool ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn);

View File

@ -16942,9 +16942,9 @@ ix86_lea_outperforms (rtx insn, unsigned int regno0, unsigned int regno1,
dist_define += split_cost + IX86_LEA_PRIORITY;
/* If there is no use in memory addess then we just check
that split cost does not exceed AGU stall. */
that split cost exceeds AGU stall. */
if (dist_use < 0)
return dist_define >= LEA_MAX_STALL;
return dist_define > LEA_MAX_STALL;
/* If this insn has both backward non-agu dependence and forward
agu dependence, the one with short distance takes effect. */
@ -17127,13 +17127,41 @@ ix86_emit_binop (enum rtx_code code, enum machine_mode mode,
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
}
/* Return true if regno1 def is nearest to the insn. */
static bool
find_nearest_reg_def (rtx insn, int regno1, int regno2)
{
rtx prev = insn;
rtx start = BB_HEAD (BLOCK_FOR_INSN (insn));
if (insn == start)
return false;
while (prev && prev != start)
{
if (!INSN_P (prev) || !NONDEBUG_INSN_P (prev))
{
prev = PREV_INSN (prev);
continue;
}
if (insn_defines_reg (regno1, INVALID_REGNUM, prev))
return true;
else if (insn_defines_reg (regno2, INVALID_REGNUM, prev))
return false;
prev = PREV_INSN (prev);
}
/* None of the regs is defined in the bb. */
return false;
}
/* Split lea instructions into a sequence of instructions
which are executed on ALU to avoid AGU stalls.
It is assumed that it is allowed to clobber flags register
at lea position. */
void
ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode)
ix86_split_lea_for_addr (rtx insn, rtx operands[], enum machine_mode mode)
{
unsigned int regno0, regno1, regno2;
struct ix86_address parts;
@ -17220,8 +17248,22 @@ ix86_split_lea_for_addr (rtx operands[], enum machine_mode mode)
tmp = parts.base;
else
{
emit_insn (gen_rtx_SET (VOIDmode, target, parts.base));
tmp = parts.index;
rtx tmp1;
/* Find better operand for SET instruction, depending
on which definition is farther from the insn. */
if (find_nearest_reg_def (insn, regno1, regno2))
tmp = parts.index, tmp1 = parts.base;
else
tmp = parts.base, tmp1 = parts.index;
emit_insn (gen_rtx_SET (VOIDmode, target, tmp));
if (parts.disp && parts.disp != const0_rtx)
ix86_emit_binop (PLUS, mode, target, parts.disp);
ix86_emit_binop (PLUS, mode, target, tmp1);
return;
}
ix86_emit_binop (PLUS, mode, target, tmp);

View File

@ -5520,7 +5520,7 @@
|| GET_CODE (operands[1]) == AND)
mode = SImode;
ix86_split_lea_for_addr (operands, mode);
ix86_split_lea_for_addr (curr_insn, operands, mode);
DONE;
}
[(set_attr "type" "lea")