Commit 9a7f94d7 by H.J. Lu Committed by H.J. Lu

Add X86_TUNE_AVOID_LEA_FOR_ADDR

ix86_split_lea_for_addr transforms a single LEA instruction into a
series of MOV and ADD instructions.  For

lea 0x400(%edx, %ecx, 8), %edx

we get

mov %ecx, %edx
add %ecx, %edx
add %ecx, %edx
add %ecx, %edx
add %ecx, %edx
add %ecx, %edx
add %ecx, %edx
add %ecx, %edx
add $0x400, %edx

For -mtune=intel, we want to turn on X86_TUNE_OPT_AGU, but avoid
ix86_split_lea_for_addr to optimize for both Haswell and Silvermont.
This patch adds X86_TUNE_AVOID_LEA_FOR_ADDR and PROCESSOR_INTEL.
We keep PROCESSOR_INTEL the same as PROCESSOR_SILVERMONT, except that
X86_TUNE_AVOID_LEA_FOR_ADDR isn't turned on for PROCESSOR_INTEL.

	* config/i386/i386-c.c (ix86_target_macros_internal): Handle
	PROCESSOR_INTEL.  Treat like PROCESSOR_GENERIC.
	* config/i386/i386.c (intel_memcpy): New.  Duplicate slm_memcpy.
	(intel_memset): New.  Duplicate slm_memset.
	(intel_cost): New.  Duplicate slm_cost.
	(m_INTEL): New macro.
	(processor_target_table): Add "intel".
	(ix86_option_override_internal): Replace PROCESSOR_SILVERMONT
	with PROCESSOR_INTEL for "intel".
	(ix86_lea_outperforms): Support PROCESSOR_INTEL.  Duplicate
	PROCESSOR_SILVERMONT.
	(ix86_avoid_lea_for_addr): Check TARGET_AVOID_LEA_FOR_ADDR
	instead of TARGET_OPT_AGU.
	(ix86_issue_rate): Likewise.
	(ix86_adjust_cost): Likewise.
	(ia32_multipass_dfa_lookahead): Likewise.
	(swap_top_of_ready_list): Likewise.
	(ix86_sched_reorder): Likewise.
	* config/i386/i386.h (TARGET_INTEL): New.
	(TARGET_AVOID_LEA_FOR_ADDR): Likewise.
	(processor_type): Add PROCESSOR_INTEL.
	* config/i386/x86-tune.def: Support m_INTEL. Duplicate
	m_SILVERMONT.  Add X86_TUNE_AVOID_LEA_FOR_ADDR.

From-SVN: r206717
parent 0ffc4683
2014-01-17 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386-c.c (ix86_target_macros_internal): Handle
PROCESSOR_INTEL. Treat like PROCESSOR_GENERIC.
* config/i386/i386.c (intel_memcpy): New. Duplicate slm_memcpy.
(intel_memset): New. Duplicate slm_memset.
(intel_cost): New. Duplicate slm_cost.
(m_INTEL): New macro.
(processor_target_table): Add "intel".
(ix86_option_override_internal): Replace PROCESSOR_SILVERMONT
with PROCESSOR_INTEL for "intel".
(ix86_lea_outperforms): Support PROCESSOR_INTEL. Duplicate
PROCESSOR_SILVERMONT.
(ix86_avoid_lea_for_addr): Check TARGET_AVOID_LEA_FOR_ADDR
instead of TARGET_OPT_AGU.
(ix86_issue_rate): Likewise.
(ix86_adjust_cost): Likewise.
(ia32_multipass_dfa_lookahead): Likewise.
(swap_top_of_ready_list): Likewise.
(ix86_sched_reorder): Likewise.
* config/i386/i386.h (TARGET_INTEL): New.
(TARGET_AVOID_LEA_FOR_ADDR): Likewise.
(processor_type): Add PROCESSOR_INTEL.
* config/i386/x86-tune.def: Support m_INTEL. Duplicate
m_SILVERMONT. Add X86_TUNE_AVOID_LEA_FOR_ADDR.
2014-01-17 Marek Polacek <polacek@redhat.com>
PR c/58346
......
......@@ -174,6 +174,7 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
/* use PROCESSOR_max to not set/unset the arch macro. */
case PROCESSOR_max:
break;
case PROCESSOR_INTEL:
case PROCESSOR_GENERIC:
gcc_unreachable ();
}
......@@ -276,6 +277,7 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__tune_slm__");
def_or_undef (parse_in, "__tune_silvermont__");
break;
case PROCESSOR_INTEL:
case PROCESSOR_GENERIC:
break;
/* use PROCESSOR_max to not set/unset the tune macro. */
......
......@@ -1747,6 +1747,83 @@ struct processor_costs slm_cost = {
1, /* cond_not_taken_branch_cost. */
};
static stringop_algs intel_memcpy[2] = {
{libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}},
{libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
{8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static stringop_algs intel_memset[2] = {
{libcall, {{8, loop, false}, {15, unrolled_loop, false},
{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
{libcall, {{24, loop, false}, {32, unrolled_loop, false},
{8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs intel_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
COSTS_N_INSNS (1), /* constant shift costs */
{COSTS_N_INSNS (3), /* cost of starting multiply for QI */
COSTS_N_INSNS (3), /* HI */
COSTS_N_INSNS (3), /* SI */
COSTS_N_INSNS (4), /* DI */
COSTS_N_INSNS (2)}, /* other */
0, /* cost of multiply per each bit set */
{COSTS_N_INSNS (18), /* cost of a divide/mod for QI */
COSTS_N_INSNS (26), /* HI */
COSTS_N_INSNS (42), /* SI */
COSTS_N_INSNS (74), /* DI */
COSTS_N_INSNS (74)}, /* other */
COSTS_N_INSNS (1), /* cost of movsx */
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
4, /* cost for loading QImode using movzbl */
{4, 4, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{4, 4, 4}, /* cost of storing integer registers */
4, /* cost of reg,reg fld/fst */
{12, 12, 12}, /* cost of loading fp registers
in SFmode, DFmode and XFmode */
{6, 6, 8}, /* cost of storing fp registers
in SFmode, DFmode and XFmode */
2, /* cost of moving MMX register */
{8, 8}, /* cost of loading MMX registers
in SImode and DImode */
{8, 8}, /* cost of storing MMX registers
in SImode and DImode */
2, /* cost of moving SSE register */
{8, 8, 8}, /* cost of loading SSE registers
in SImode, DImode and TImode */
{8, 8, 8}, /* cost of storing SSE registers
in SImode, DImode and TImode */
5, /* MMX or SSE register to integer */
32, /* size of l1 cache. */
256, /* size of l2 cache. */
64, /* size of prefetch block */
6, /* number of parallel prefetches */
3, /* Branch cost */
COSTS_N_INSNS (8), /* cost of FADD and FSUB insns. */
COSTS_N_INSNS (8), /* cost of FMUL instruction. */
COSTS_N_INSNS (20), /* cost of FDIV instruction. */
COSTS_N_INSNS (8), /* cost of FABS instruction. */
COSTS_N_INSNS (8), /* cost of FCHS instruction. */
COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
intel_memcpy,
intel_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
1, /* vec_stmt_cost. */
1, /* vec_to_scalar_cost. */
1, /* scalar_to_vec_cost. */
1, /* vec_align_load_cost. */
2, /* vec_unalign_load_cost. */
1, /* vec_store_cost. */
3, /* cond_taken_branch_cost. */
1, /* cond_not_taken_branch_cost. */
};
/* Generic should produce code tuned for Core-i7 (and newer chips)
and btver1 (and newer chips). */
......@@ -1942,6 +2019,7 @@ const struct processor_costs *ix86_cost = &pentium_cost;
#define m_CORE_ALL (m_CORE2 | m_NEHALEM | m_SANDYBRIDGE | m_HASWELL)
#define m_BONNELL (1<<PROCESSOR_BONNELL)
#define m_SILVERMONT (1<<PROCESSOR_SILVERMONT)
#define m_INTEL (1<<PROCESSOR_INTEL)
#define m_GEODE (1<<PROCESSOR_GEODE)
#define m_K6 (1<<PROCESSOR_K6)
......@@ -2401,6 +2479,7 @@ static const struct ptt processor_target_table[PROCESSOR_max] =
{"haswell", &core_cost, 16, 10, 16, 10, 16},
{"bonnell", &atom_cost, 16, 15, 16, 7, 16},
{"silvermont", &slm_cost, 16, 15, 16, 7, 16},
{"intel", &intel_cost, 16, 15, 16, 7, 16},
{"geode", &geode_cost, 0, 0, 0, 0, 0},
{"k6", &k6_cost, 32, 7, 32, 7, 32},
{"athlon", &athlon_cost, 16, 7, 16, 7, 16},
......@@ -3112,7 +3191,7 @@ ix86_option_override_internal (bool main_args_p,
{"atom", PROCESSOR_BONNELL, CPU_ATOM, PTA_BONNELL},
{"silvermont", PROCESSOR_SILVERMONT, CPU_SLM, PTA_SILVERMONT},
{"slm", PROCESSOR_SILVERMONT, CPU_SLM, PTA_SILVERMONT},
{"intel", PROCESSOR_SILVERMONT, CPU_SLM, PTA_NEHALEM},
{"intel", PROCESSOR_INTEL, CPU_SLM, PTA_NEHALEM},
{"geode", PROCESSOR_GEODE, CPU_GEODE,
PTA_MMX | PTA_3DNOW | PTA_3DNOW_A | PTA_PREFETCH_SSE | PTA_PRFCHW},
{"k6", PROCESSOR_K6, CPU_K6, PTA_MMX},
......@@ -17941,7 +18020,7 @@ ix86_lea_outperforms (rtx insn, unsigned int regno0, unsigned int regno1,
/* For Silvermont if using a 2-source or 3-source LEA for
non-destructive destination purposes, or due to wanting
ability to use SCALE, the use of LEA is justified. */
if (ix86_tune == PROCESSOR_SILVERMONT)
if (ix86_tune == PROCESSOR_SILVERMONT || ix86_tune == PROCESSOR_INTEL)
{
if (has_scale)
return true;
......@@ -18077,7 +18156,7 @@ ix86_avoid_lea_for_addr (rtx insn, rtx operands[])
int ok;
/* Check we need to optimize. */
if (!TARGET_OPT_AGU || optimize_function_for_size_p (cfun))
if (!TARGET_AVOID_LEA_FOR_ADDR || optimize_function_for_size_p (cfun))
return false;
/* Check it is correct to split here. */
......@@ -25200,6 +25279,7 @@ ix86_issue_rate (void)
case PROCESSOR_PENTIUM:
case PROCESSOR_BONNELL:
case PROCESSOR_SILVERMONT:
case PROCESSOR_INTEL:
case PROCESSOR_K6:
case PROCESSOR_BTVER2:
case PROCESSOR_PENTIUM4:
......@@ -25541,6 +25621,7 @@ ix86_adjust_cost (rtx insn, rtx link, rtx dep_insn, int cost)
break;
case PROCESSOR_SILVERMONT:
case PROCESSOR_INTEL:
if (!reload_completed)
return cost;
......@@ -25609,6 +25690,7 @@ ia32_multipass_dfa_lookahead (void)
case PROCESSOR_HASWELL:
case PROCESSOR_BONNELL:
case PROCESSOR_SILVERMONT:
case PROCESSOR_INTEL:
/* Generally, we want haifa-sched:max_issue() to look ahead as far
as many instructions can be executed on a cycle, i.e.,
issue_rate. I wonder why tuning for many CPUs does not do this. */
......@@ -25830,7 +25912,7 @@ swap_top_of_ready_list (rtx *ready, int n_ready)
int clock2 = -1;
#define INSN_TICK(INSN) (HID (INSN)->tick)
if (ix86_tune != PROCESSOR_SILVERMONT)
if (ix86_tune != PROCESSOR_SILVERMONT && ix86_tune != PROCESSOR_INTEL)
return false;
if (!NONDEBUG_INSN_P (top))
......@@ -25904,7 +25986,8 @@ ix86_sched_reorder (FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
/* Do reodering for BONNELL/SILVERMONT only. */
if (ix86_tune != PROCESSOR_BONNELL
&& ix86_tune != PROCESSOR_SILVERMONT)
&& ix86_tune != PROCESSOR_SILVERMONT
&& ix86_tune != PROCESSOR_INTEL)
return issue_rate;
/* Nothing to do if ready list contains only 1 instruction. */
......@@ -308,6 +308,7 @@ extern const struct processor_costs ix86_size_cost;
#define TARGET_HASWELL (ix86_tune == PROCESSOR_HASWELL)
#define TARGET_BONNELL (ix86_tune == PROCESSOR_BONNELL)
#define TARGET_SILVERMONT (ix86_tune == PROCESSOR_SILVERMONT)
#define TARGET_INTEL (ix86_tune == PROCESSOR_INTEL)
#define TARGET_GENERIC (ix86_tune == PROCESSOR_GENERIC)
#define TARGET_AMDFAM10 (ix86_tune == PROCESSOR_AMDFAM10)
#define TARGET_BDVER1 (ix86_tune == PROCESSOR_BDVER1)
......@@ -429,6 +430,8 @@ extern unsigned char ix86_tune_features[X86_TUNE_LAST];
#define TARGET_FUSE_ALU_AND_BRANCH \
ix86_tune_features[X86_TUNE_FUSE_ALU_AND_BRANCH]
#define TARGET_OPT_AGU ix86_tune_features[X86_TUNE_OPT_AGU]
#define TARGET_AVOID_LEA_FOR_ADDR \
ix86_tune_features[X86_TUNE_AVOID_LEA_FOR_ADDR]
#define TARGET_VECTORIZE_DOUBLE \
ix86_tune_features[X86_TUNE_VECTORIZE_DOUBLE]
#define TARGET_SOFTWARE_PREFETCHING_BENEFICIAL \
......@@ -2184,6 +2187,7 @@ enum processor_type
PROCESSOR_HASWELL,
PROCESSOR_BONNELL,
PROCESSOR_SILVERMONT,
PROCESSOR_INTEL,
PROCESSOR_GEODE,
PROCESSOR_K6,
PROCESSOR_ATHLON,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment