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:
parent
fd19949184
commit
af7c3fe7aa
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user