i386: Separate costs of pseudo registers from hard registers

processor_costs has costs of RTL expressions with pseudo registers and
and costs of hard register moves:

1. Costs of RTL expressions are used to generate the most efficient RTL
operations with pseudo registers.

2. Costs of hard register moves are used by register allocator to
decide how to allocate and move hard registers.

Since relative costs of pseudo register load and store versus pseudo
register moves in RTL expressions can be different from relative costs
of hard registers, we should separate costs of RTL expressions with
pseudo registers from costs of hard registers so that register allocator
and RTL expressions can be improved independently.

This patch moves costs of hard register moves to the new hard_register
field and duplicates costs of moves which are also used for costs of RTL
expressions.

	PR target/90878
	* config/i386/i386.c (inline_memory_move_cost): Use hard_register
	for costs of hard register moves.
	(ix86_register_move_cost): Likewise.
	* config/i386/i386.h (processor_costs): Move costs of hard
	register moves to hard_register.  Add int_load, int_store,
	xmm_move, ymm_move, zmm_move, sse_to_integer, integer_to_sse,
	sse_load, sse_store, sse_unaligned_load and sse_unaligned_store
	for costs of RTL expressions.
	* config/i386/x86-tune-costs.h: Move costs of hard register
	moves to hard_register.  Duplicate int_load, int_store,
	xmm_move, ymm_move, zmm_move, sse_to_integer, integer_to_sse,
	sse_load, sse_store for costs of RTL expressions.

From-SVN: r274543
This commit is contained in:
H.J. Lu 2019-08-15 18:15:33 +00:00 committed by H.J. Lu
parent d91f618d15
commit d321551cea
4 changed files with 841 additions and 543 deletions

View File

@ -1,3 +1,19 @@
2019-08-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/90878
* config/i386/i386.c (inline_memory_move_cost): Use hard_register
for costs of hard register moves.
(ix86_register_move_cost): Likewise.
* config/i386/i386.h (processor_costs): Move costs of hard
register moves to hard_register. Add int_load, int_store,
xmm_move, ymm_move, zmm_move, sse_to_integer, integer_to_sse,
sse_load, sse_store, sse_unaligned_load and sse_unaligned_store
for costs of RTL expressions.
* config/i386/x86-tune-costs.h: Move costs of hard register
moves to hard_register. Duplicate int_load, int_store,
xmm_move, ymm_move, zmm_move, sse_to_integer, integer_to_sse,
sse_load, sse_store for costs of RTL expressions.
2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
* target.def (setup_incoming_vararg_bounds): Remove.

View File

@ -18464,8 +18464,10 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
return 100;
}
if (in == 2)
return MAX (ix86_cost->fp_load [index], ix86_cost->fp_store [index]);
return in ? ix86_cost->fp_load [index] : ix86_cost->fp_store [index];
return MAX (ix86_cost->hard_register.fp_load [index],
ix86_cost->hard_register.fp_store [index]);
return in ? ix86_cost->hard_register.fp_load [index]
: ix86_cost->hard_register.fp_store [index];
}
if (SSE_CLASS_P (regclass))
{
@ -18473,8 +18475,10 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
if (index == -1)
return 100;
if (in == 2)
return MAX (ix86_cost->sse_load [index], ix86_cost->sse_store [index]);
return in ? ix86_cost->sse_load [index] : ix86_cost->sse_store [index];
return MAX (ix86_cost->hard_register.sse_load [index],
ix86_cost->hard_register.sse_store [index]);
return in ? ix86_cost->hard_register.sse_load [index]
: ix86_cost->hard_register.sse_store [index];
}
if (MMX_CLASS_P (regclass))
{
@ -18491,8 +18495,10 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
return 100;
}
if (in == 2)
return MAX (ix86_cost->mmx_load [index], ix86_cost->mmx_store [index]);
return in ? ix86_cost->mmx_load [index] : ix86_cost->mmx_store [index];
return MAX (ix86_cost->hard_register.mmx_load [index],
ix86_cost->hard_register.mmx_store [index]);
return in ? ix86_cost->hard_register.mmx_load [index]
: ix86_cost->hard_register.mmx_store [index];
}
switch (GET_MODE_SIZE (mode))
{
@ -18500,37 +18506,41 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
if (Q_CLASS_P (regclass) || TARGET_64BIT)
{
if (!in)
return ix86_cost->int_store[0];
return ix86_cost->hard_register.int_store[0];
if (TARGET_PARTIAL_REG_DEPENDENCY
&& optimize_function_for_speed_p (cfun))
cost = ix86_cost->movzbl_load;
cost = ix86_cost->hard_register.movzbl_load;
else
cost = ix86_cost->int_load[0];
cost = ix86_cost->hard_register.int_load[0];
if (in == 2)
return MAX (cost, ix86_cost->int_store[0]);
return MAX (cost, ix86_cost->hard_register.int_store[0]);
return cost;
}
else
{
if (in == 2)
return MAX (ix86_cost->movzbl_load, ix86_cost->int_store[0] + 4);
return MAX (ix86_cost->hard_register.movzbl_load,
ix86_cost->hard_register.int_store[0] + 4);
if (in)
return ix86_cost->movzbl_load;
return ix86_cost->hard_register.movzbl_load;
else
return ix86_cost->int_store[0] + 4;
return ix86_cost->hard_register.int_store[0] + 4;
}
break;
case 2:
if (in == 2)
return MAX (ix86_cost->int_load[1], ix86_cost->int_store[1]);
return in ? ix86_cost->int_load[1] : ix86_cost->int_store[1];
return MAX (ix86_cost->hard_register.int_load[1],
ix86_cost->hard_register.int_store[1]);
return in ? ix86_cost->hard_register.int_load[1]
: ix86_cost->hard_register.int_store[1];
default:
if (in == 2)
cost = MAX (ix86_cost->int_load[2], ix86_cost->int_store[2]);
cost = MAX (ix86_cost->hard_register.int_load[2],
ix86_cost->hard_register.int_store[2]);
else if (in)
cost = ix86_cost->int_load[2];
cost = ix86_cost->hard_register.int_load[2];
else
cost = ix86_cost->int_store[2];
cost = ix86_cost->hard_register.int_store[2];
/* Multiply with the number of GPR moves needed. */
return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
}
@ -18600,20 +18610,21 @@ ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
because of missing QImode and HImode moves to, from or between
MMX/SSE registers. */
return MAX (8, SSE_CLASS_P (class1)
? ix86_cost->sse_to_integer : ix86_cost->integer_to_sse);
? ix86_cost->hard_register.sse_to_integer
: ix86_cost->hard_register.integer_to_sse);
if (MAYBE_FLOAT_CLASS_P (class1))
return ix86_cost->fp_move;
return ix86_cost->hard_register.fp_move;
if (MAYBE_SSE_CLASS_P (class1))
{
if (GET_MODE_BITSIZE (mode) <= 128)
return ix86_cost->xmm_move;
return ix86_cost->hard_register.xmm_move;
if (GET_MODE_BITSIZE (mode) <= 256)
return ix86_cost->ymm_move;
return ix86_cost->zmm_move;
return ix86_cost->hard_register.ymm_move;
return ix86_cost->hard_register.zmm_move;
}
if (MAYBE_MMX_CLASS_P (class1))
return ix86_cost->mmx_move;
return ix86_cost->hard_register.mmx_move;
return 2;
}

View File

@ -237,9 +237,46 @@ struct stringop_algs
} size [MAX_STRINGOP_ALGS];
};
/* Define the specific costs for a given cpu */
/* Define the specific costs for a given cpu. NB: hard_register is used
by TARGET_REGISTER_MOVE_COST and TARGET_MEMORY_MOVE_COST to compute
hard register move costs by register allocator. Relative costs of
pseudo register load and store versus pseudo register moves in RTL
expressions for TARGET_RTX_COSTS can be different from relative
costs of hard registers to get the most efficient operations with
pseudo registers. */
struct processor_costs {
/* Costs used by register allocator. integer->integer register move
cost is 2. */
struct
{
const int movzbl_load; /* cost of loading using movzbl */
const int int_load[3]; /* cost of loading integer registers
in QImode, HImode and SImode relative
to reg-reg move (2). */
const int int_store[3]; /* cost of storing integer register
in QImode, HImode and SImode */
const int fp_move; /* cost of reg,reg fld/fst */
const int fp_load[3]; /* cost of loading FP register
in SFmode, DFmode and XFmode */
const int fp_store[3]; /* cost of storing FP register
in SFmode, DFmode and XFmode */
const int mmx_move; /* cost of moving MMX register. */
const int mmx_load[2]; /* cost of loading MMX register
in SImode and DImode */
const int mmx_store[2]; /* cost of storing MMX register
in SImode and DImode */
const int xmm_move; /* cost of moving XMM register. */
const int ymm_move; /* cost of moving XMM register. */
const int zmm_move; /* cost of moving XMM register. */
const int sse_load[5]; /* cost of loading SSE register
in 32bit, 64bit, 128bit, 256bit and 512bit */
const int sse_store[5]; /* cost of storing SSE register
in SImode, DImode and TImode. */
const int sse_to_integer; /* cost of moving SSE register to integer. */
const int integer_to_sse; /* cost of moving integer register to SSE. */
} hard_register;
const int add; /* cost of an add instruction */
const int lea; /* cost of a lea instruction */
const int shift_var; /* variable shift costs */
@ -254,32 +291,20 @@ struct processor_costs {
const int large_insn; /* insns larger than this cost more */
const int move_ratio; /* The threshold of number of scalar
memory-to-memory move insns. */
const int movzbl_load; /* cost of loading using movzbl */
const int int_load[3]; /* cost of loading integer registers
in QImode, HImode and SImode relative
to reg-reg move (2). */
const int int_store[3]; /* cost of storing integer register
in QImode, HImode and SImode */
const int fp_move; /* cost of reg,reg fld/fst */
const int fp_load[3]; /* cost of loading FP register
in SFmode, DFmode and XFmode */
const int fp_store[3]; /* cost of storing FP register
in SFmode, DFmode and XFmode */
const int mmx_move; /* cost of moving MMX register. */
const int mmx_load[2]; /* cost of loading MMX register
in SImode and DImode */
const int mmx_store[2]; /* cost of storing MMX register
in SImode and DImode */
const int xmm_move, ymm_move, /* cost of moving XMM and YMM register. */
zmm_move;
const int sse_load[5]; /* cost of loading SSE register
in 32bit, 64bit, 128bit, 256bit and 512bit */
const int sse_unaligned_load[5];/* cost of unaligned load. */
const int sse_store[5]; /* cost of storing SSE register
in SImode, DImode and TImode. */
in 32bit, 64bit, 128bit, 256bit and 512bit */
const int sse_unaligned_load[5];/* cost of unaligned load. */
const int sse_unaligned_store[5];/* cost of unaligned store. */
const int xmm_move, ymm_move, /* cost of moving XMM and YMM register. */
zmm_move;
const int sse_to_integer; /* cost of moving SSE register to integer. */
const int integer_to_sse; /* cost of moving integer register to SSE. */
const int gather_static, gather_per_elt; /* Cost of gather load is computed
as static + per_item * nelts. */
const int scatter_static, scatter_per_elt; /* Cost of gather store is

File diff suppressed because it is too large Load Diff