Commit 64766e8d by Jan Hubicka Committed by Jan Hubicka

config.gcc (i386, x86_64): Add extra objects.



	* config.gcc (i386, x86_64): Add extra objects.
	* i386/i386-protos.h (ix86_rip_relative_addr_p): Declare.
	(ix86_min_insn_size): Declare.
	(ix86_issue_rate): Declare.
	(ix86_adjust_cost): Declare.
	(ia32_multipass_dfa_lookahead): Declare.
	(ix86_macro_fusion_p): Declare.
	(ix86_macro_fusion_pair_p): Declare.
	(ix86_bd_has_dispatch): Declare.
	(ix86_bd_do_dispatch): Declare.
	(ix86_core2i7_init_hooks): Declare.
	(ix86_atom_sched_reorder): Declare.
	* i386/i386.c Move all CPU cost tables to x86-tune-costs.h.
	(COSTS_N_BYTES): Move to x86-tune-costs.h.
	(DUMMY_STRINGOP_ALGS):x86-tune-costs.h.
	(rip_relative_addr_p): Rename to ...
	(ix86_rip_relative_addr_p): ... this one; export.
	(memory_address_length): Update.
	(ix86_issue_rate): Move to x86-tune-sched.c.
	(ix86_flags_dependent): Move to x86-tune-sched.c.
	(ix86_agi_dependent): Move to x86-tune-sched.c.
	(exact_dependency_1): Move to x86-tune-sched.c.
	(exact_store_load_dependency): Move to x86-tune-sched.c.
	(ix86_adjust_cost): Move to x86-tune-sched.c.
	(ia32_multipass_dfa_lookahead): Move to x86-tune-sched.c.
	(ix86_macro_fusion_p): Move to x86-tune-sched.c.
	(ix86_macro_fusion_pair_p): Move to x86-tune-sched.c.
	(do_reorder_for_imul): Move to x86-tune-sched-atom.c.
	(swap_top_of_ready_list): Move to x86-tune-sched-atom.c.
	(ix86_sched_reorder): Move to x86-tune-sched-atom.c.
	(core2i7_first_cycle_multipass_init): Move to x86-tune-sched-core.c.
	(core2i7_dfa_post_advance_cycle): Move to x86-tune-sched-core.c.
	(min_insn_size): Rename to ...
	(ix86_min_insn_size): ... this one; export.
	(core2i7_first_cycle_multipass_begin): Move to x86-tune-sched-core.c.
	(core2i7_first_cycle_multipass_issue): Move to x86-tune-sched-core.c.
	(core2i7_first_cycle_multipass_backtrack): Move to x86-tune-sched-core.c.
	(core2i7_first_cycle_multipass_end): Move to x86-tune-sched-core.c.
	(core2i7_first_cycle_multipass_fini): Move to x86-tune-sched-core.c.
	(ix86_sched_init_global): Break up logic to ix86_core2i7_init_hooks.
	(ix86_avoid_jump_mispredicts): Update.
	(TARGET_SCHED_DISPATCH): Move to ix86-tune-sched-bd.c.
	(TARGET_SCHED_DISPATCH_DO): Move to ix86-tune-sched-bd.c.
	(TARGET_SCHED_REORDER): Move to ix86-tune-sched-bd.c.
	(DISPATCH_WINDOW_SIZE): Move to ix86-tune-sched-bd.c.
	(MAX_DISPATCH_WINDOWS): Move to ix86-tune-sched-bd.c.
	(MAX_INSN): Move to ix86-tune-sched-bd.c.
	(MAX_IMM): Move to ix86-tune-sched-bd.c.
	(MAX_IMM_SIZE): Move to ix86-tune-sched-bd.c.
	(MAX_IMM_32): Move to ix86-tune-sched-bd.c.
	(MAX_IMM_64): Move to ix86-tune-sched-bd.c.
	(MAX_LOAD): Move to ix86-tune-sched-bd.c.
	(MAX_STORE): Move to ix86-tune-sched-bd.c.
	(BIG): Move to ix86-tune-sched-bd.c.
	(enum dispatch_group): Move to ix86-tune-sched-bd.c.
	(enum insn_path): Move to ix86-tune-sched-bd.c.
	(get_mem_group): Move to ix86-tune-sched-bd.c.
	(is_cmp): Move to ix86-tune-sched-bd.c.
	(dispatch_violation): Move to ix86-tune-sched-bd.c.
	(is_branch): Move to ix86-tune-sched-bd.c.
	(is_prefetch): Move to ix86-tune-sched-bd.c.
	(init_window): Move to ix86-tune-sched-bd.c.
	(allocate_window): Move to ix86-tune-sched-bd.c.
	(init_dispatch_sched): Move to ix86-tune-sched-bd.c.
	(is_end_basic_block): Move to ix86-tune-sched-bd.c.
	(process_end_window): Move to ix86-tune-sched-bd.c.
	(allocate_next_window): Move to ix86-tune-sched-bd.c.
	(find_constant): Move to ix86-tune-sched-bd.c.
	(get_num_immediates): Move to ix86-tune-sched-bd.c.
	(has_immediate): Move to ix86-tune-sched-bd.c.
	(get_insn_path): Move to ix86-tune-sched-bd.c.
	(get_insn_group): Move to ix86-tune-sched-bd.c.
	(count_num_restricted): Move to ix86-tune-sched-bd.c.
	(fits_dispatch_window): Move to ix86-tune-sched-bd.c.
	(add_insn_window): Move to ix86-tune-sched-bd.c.
	(add_to_dispatch_window): Move to ix86-tune-sched-bd.c.
	(debug_dispatch_window_file): Move to ix86-tune-sched-bd.c.
	(debug_dispatch_window): Move to ix86-tune-sched-bd.c.
	(debug_insn_dispatch_info_file): Move to ix86-tune-sched-bd.c.
	(debug_ready_dispatch): Move to ix86-tune-sched-bd.c.
	(do_dispatch): Move to ix86-tune-sched-bd.c.
	(has_dispatch): Move to ix86-tune-sched-bd.c.
	* i386/t-i386: Add new object files.
	* i386/x86-tune-costs.h: New file.
	* i386/x86-tune-sched-atom.c: New file.
	* i386/x86-tune-sched-bd.c: New file.
	* i386/x86-tune-sched-core.c: New file.
	* i386/x86-tune-sched.c: New file.

From-SVN: r253646
parent db0d1bae
2017-10-11 Jan Hubicka <hubicka@ucw.cz>
* config.gcc (i386, x86_64): Add extra objects.
* i386/i386-protos.h (ix86_rip_relative_addr_p): Declare.
(ix86_min_insn_size): Declare.
(ix86_issue_rate): Declare.
(ix86_adjust_cost): Declare.
(ia32_multipass_dfa_lookahead): Declare.
(ix86_macro_fusion_p): Declare.
(ix86_macro_fusion_pair_p): Declare.
(ix86_bd_has_dispatch): Declare.
(ix86_bd_do_dispatch): Declare.
(ix86_core2i7_init_hooks): Declare.
(ix86_atom_sched_reorder): Declare.
* i386/i386.c Move all CPU cost tables to x86-tune-costs.h.
(COSTS_N_BYTES): Move to x86-tune-costs.h.
(DUMMY_STRINGOP_ALGS):x86-tune-costs.h.
(rip_relative_addr_p): Rename to ...
(ix86_rip_relative_addr_p): ... this one; export.
(memory_address_length): Update.
(ix86_issue_rate): Move to x86-tune-sched.c.
(ix86_flags_dependent): Move to x86-tune-sched.c.
(ix86_agi_dependent): Move to x86-tune-sched.c.
(exact_dependency_1): Move to x86-tune-sched.c.
(exact_store_load_dependency): Move to x86-tune-sched.c.
(ix86_adjust_cost): Move to x86-tune-sched.c.
(ia32_multipass_dfa_lookahead): Move to x86-tune-sched.c.
(ix86_macro_fusion_p): Move to x86-tune-sched.c.
(ix86_macro_fusion_pair_p): Move to x86-tune-sched.c.
(do_reorder_for_imul): Move to x86-tune-sched-atom.c.
(swap_top_of_ready_list): Move to x86-tune-sched-atom.c.
(ix86_sched_reorder): Move to x86-tune-sched-atom.c.
(core2i7_first_cycle_multipass_init): Move to x86-tune-sched-core.c.
(core2i7_dfa_post_advance_cycle): Move to x86-tune-sched-core.c.
(min_insn_size): Rename to ...
(ix86_min_insn_size): ... this one; export.
(core2i7_first_cycle_multipass_begin): Move to x86-tune-sched-core.c.
(core2i7_first_cycle_multipass_issue): Move to x86-tune-sched-core.c.
(core2i7_first_cycle_multipass_backtrack): Move to x86-tune-sched-core.c.
(core2i7_first_cycle_multipass_end): Move to x86-tune-sched-core.c.
(core2i7_first_cycle_multipass_fini): Move to x86-tune-sched-core.c.
(ix86_sched_init_global): Break up logic to ix86_core2i7_init_hooks.
(ix86_avoid_jump_mispredicts): Update.
(TARGET_SCHED_DISPATCH): Move to ix86-tune-sched-bd.c.
(TARGET_SCHED_DISPATCH_DO): Move to ix86-tune-sched-bd.c.
(TARGET_SCHED_REORDER): Move to ix86-tune-sched-bd.c.
(DISPATCH_WINDOW_SIZE): Move to ix86-tune-sched-bd.c.
(MAX_DISPATCH_WINDOWS): Move to ix86-tune-sched-bd.c.
(MAX_INSN): Move to ix86-tune-sched-bd.c.
(MAX_IMM): Move to ix86-tune-sched-bd.c.
(MAX_IMM_SIZE): Move to ix86-tune-sched-bd.c.
(MAX_IMM_32): Move to ix86-tune-sched-bd.c.
(MAX_IMM_64): Move to ix86-tune-sched-bd.c.
(MAX_LOAD): Move to ix86-tune-sched-bd.c.
(MAX_STORE): Move to ix86-tune-sched-bd.c.
(BIG): Move to ix86-tune-sched-bd.c.
(enum dispatch_group): Move to ix86-tune-sched-bd.c.
(enum insn_path): Move to ix86-tune-sched-bd.c.
(get_mem_group): Move to ix86-tune-sched-bd.c.
(is_cmp): Move to ix86-tune-sched-bd.c.
(dispatch_violation): Move to ix86-tune-sched-bd.c.
(is_branch): Move to ix86-tune-sched-bd.c.
(is_prefetch): Move to ix86-tune-sched-bd.c.
(init_window): Move to ix86-tune-sched-bd.c.
(allocate_window): Move to ix86-tune-sched-bd.c.
(init_dispatch_sched): Move to ix86-tune-sched-bd.c.
(is_end_basic_block): Move to ix86-tune-sched-bd.c.
(process_end_window): Move to ix86-tune-sched-bd.c.
(allocate_next_window): Move to ix86-tune-sched-bd.c.
(find_constant): Move to ix86-tune-sched-bd.c.
(get_num_immediates): Move to ix86-tune-sched-bd.c.
(has_immediate): Move to ix86-tune-sched-bd.c.
(get_insn_path): Move to ix86-tune-sched-bd.c.
(get_insn_group): Move to ix86-tune-sched-bd.c.
(count_num_restricted): Move to ix86-tune-sched-bd.c.
(fits_dispatch_window): Move to ix86-tune-sched-bd.c.
(add_insn_window): Move to ix86-tune-sched-bd.c.
(add_to_dispatch_window): Move to ix86-tune-sched-bd.c.
(debug_dispatch_window_file): Move to ix86-tune-sched-bd.c.
(debug_dispatch_window): Move to ix86-tune-sched-bd.c.
(debug_insn_dispatch_info_file): Move to ix86-tune-sched-bd.c.
(debug_ready_dispatch): Move to ix86-tune-sched-bd.c.
(do_dispatch): Move to ix86-tune-sched-bd.c.
(has_dispatch): Move to ix86-tune-sched-bd.c.
* i386/t-i386: Add new object files.
* i386/x86-tune-costs.h: New file.
* i386/x86-tune-sched-atom.c: New file.
* i386/x86-tune-sched-bd.c: New file.
* i386/x86-tune-sched-core.c: New file.
* i386/x86-tune-sched.c: New file.
2017-10-11 Liu Hao <lh_mouse@126.com> 2017-10-11 Liu Hao <lh_mouse@126.com>
* pretty-print.c [_WIN32] (colorize_init): Remove. Use * pretty-print.c [_WIN32] (colorize_init): Remove. Use
...@@ -360,6 +360,7 @@ i[34567]86-*-*) ...@@ -360,6 +360,7 @@ i[34567]86-*-*)
cpu_type=i386 cpu_type=i386
c_target_objs="i386-c.o" c_target_objs="i386-c.o"
cxx_target_objs="i386-c.o" cxx_target_objs="i386-c.o"
extra_objs="x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o"
extra_options="${extra_options} fused-madd.opt" extra_options="${extra_options} fused-madd.opt"
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
...@@ -384,6 +385,7 @@ x86_64-*-*) ...@@ -384,6 +385,7 @@ x86_64-*-*)
c_target_objs="i386-c.o" c_target_objs="i386-c.o"
cxx_target_objs="i386-c.o" cxx_target_objs="i386-c.o"
extra_options="${extra_options} fused-madd.opt" extra_options="${extra_options} fused-madd.opt"
extra_objs="x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o"
extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h extra_headers="cpuid.h mmintrin.h mm3dnow.h xmmintrin.h emmintrin.h
pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h pmmintrin.h tmmintrin.h ammintrin.h smmintrin.h
nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h nmmintrin.h bmmintrin.h fma4intrin.h wmmintrin.h
......
...@@ -27,6 +27,7 @@ extern bool ix86_handle_option (struct gcc_options *opts, ...@@ -27,6 +27,7 @@ extern bool ix86_handle_option (struct gcc_options *opts,
extern bool ix86_target_stack_probe (void); extern bool ix86_target_stack_probe (void);
extern bool ix86_can_use_return_insn_p (void); extern bool ix86_can_use_return_insn_p (void);
extern void ix86_setup_frame_addresses (void); extern void ix86_setup_frame_addresses (void);
extern bool ix86_rip_relative_addr_p (struct ix86_address *parts);
extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int); extern HOST_WIDE_INT ix86_initial_elimination_offset (int, int);
extern void ix86_expand_prologue (void); extern void ix86_expand_prologue (void);
...@@ -314,6 +315,21 @@ extern enum attr_cpu ix86_schedule; ...@@ -314,6 +315,21 @@ extern enum attr_cpu ix86_schedule;
extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op); extern const char * ix86_output_call_insn (rtx_insn *insn, rtx call_op);
extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load, extern bool ix86_operands_ok_for_move_multiple (rtx *operands, bool load,
machine_mode mode); machine_mode mode);
extern int ix86_min_insn_size (rtx_insn *);
extern int ix86_issue_rate (void);
extern int ix86_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn,
int cost, unsigned int);
extern int ia32_multipass_dfa_lookahead (void);
extern bool ix86_macro_fusion_p (void);
extern bool ix86_macro_fusion_pair_p (rtx_insn *condgen, rtx_insn *condjmp);
extern bool ix86_bd_has_dispatch (rtx_insn *insn, int action);
extern void ix86_bd_do_dispatch (rtx_insn *insn, int mode);
extern void ix86_core2i7_init_hooks (void);
extern int ix86_atom_sched_reorder (FILE *, int, rtx_insn **, int *, int);
#ifdef RTX_CODE #ifdef RTX_CODE
/* Target data for multipass lookahead scheduling. /* Target data for multipass lookahead scheduling.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -24,6 +24,22 @@ i386-c.o: $(srcdir)/config/i386/i386-c.c ...@@ -24,6 +24,22 @@ i386-c.o: $(srcdir)/config/i386/i386-c.c
$(COMPILE) $< $(COMPILE) $<
$(POSTCOMPILE) $(POSTCOMPILE)
x86-tune-sched.o: $(srcdir)/config/i386/x86-tune-sched.c
$(COMPILE) $<
$(POSTCOMPILE)
x86-tune-sched-bd.o: $(srcdir)/config/i386/x86-tune-sched-bd.c
$(COMPILE) $<
$(POSTCOMPILE)
x86-tune-sched-atom.o: $(srcdir)/config/i386/x86-tune-sched-atom.c
$(COMPILE) $<
$(POSTCOMPILE)
x86-tune-sched-core.o: $(srcdir)/config/i386/x86-tune-sched-core.c
$(COMPILE) $<
$(POSTCOMPILE)
i386.o: i386-builtin-types.inc i386.o: i386-builtin-types.inc
i386-builtin-types.inc: s-i386-bt ; @true i386-builtin-types.inc: s-i386-bt ; @true
......
/* Scheduler hooks for IA-32 which implement atom+ specific logic.
Copyright (C) 1988-2017 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "tm_p.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "recog.h"
#include "target.h"
#include "rtl-iter.h"
#include "regset.h"
#include "sched-int.h"
/* Try to reorder ready list to take advantage of Atom pipelined IMUL
execution. It is applied if
(1) IMUL instruction is on the top of list;
(2) There exists the only producer of independent IMUL instruction in
ready list.
Return index of IMUL producer if it was found and -1 otherwise. */
static int
do_reorder_for_imul (rtx_insn **ready, int n_ready)
{
rtx_insn *insn;
rtx set, insn1, insn2;
sd_iterator_def sd_it;
dep_t dep;
int index = -1;
int i;
if (!TARGET_BONNELL)
return index;
/* Check that IMUL instruction is on the top of ready list. */
insn = ready[n_ready - 1];
set = single_set (insn);
if (!set)
return index;
if (!(GET_CODE (SET_SRC (set)) == MULT
&& GET_MODE (SET_SRC (set)) == SImode))
return index;
/* Search for producer of independent IMUL instruction. */
for (i = n_ready - 2; i >= 0; i--)
{
insn = ready[i];
if (!NONDEBUG_INSN_P (insn))
continue;
/* Skip IMUL instruction. */
insn2 = PATTERN (insn);
if (GET_CODE (insn2) == PARALLEL)
insn2 = XVECEXP (insn2, 0, 0);
if (GET_CODE (insn2) == SET
&& GET_CODE (SET_SRC (insn2)) == MULT
&& GET_MODE (SET_SRC (insn2)) == SImode)
continue;
FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
{
rtx con;
con = DEP_CON (dep);
if (!NONDEBUG_INSN_P (con))
continue;
insn1 = PATTERN (con);
if (GET_CODE (insn1) == PARALLEL)
insn1 = XVECEXP (insn1, 0, 0);
if (GET_CODE (insn1) == SET
&& GET_CODE (SET_SRC (insn1)) == MULT
&& GET_MODE (SET_SRC (insn1)) == SImode)
{
sd_iterator_def sd_it1;
dep_t dep1;
/* Check if there is no other dependee for IMUL. */
index = i;
FOR_EACH_DEP (con, SD_LIST_BACK, sd_it1, dep1)
{
rtx pro;
pro = DEP_PRO (dep1);
if (!NONDEBUG_INSN_P (pro))
continue;
if (pro != insn)
index = -1;
}
if (index >= 0)
break;
}
}
if (index >= 0)
break;
}
return index;
}
/* Try to find the best candidate on the top of ready list if two insns
have the same priority - candidate is best if its dependees were
scheduled earlier. Applied for Silvermont only.
Return true if top 2 insns must be interchanged. */
static bool
swap_top_of_ready_list (rtx_insn **ready, int n_ready)
{
rtx_insn *top = ready[n_ready - 1];
rtx_insn *next = ready[n_ready - 2];
rtx set;
sd_iterator_def sd_it;
dep_t dep;
int clock1 = -1;
int clock2 = -1;
#define INSN_TICK(INSN) (HID (INSN)->tick)
if (!TARGET_SILVERMONT && !TARGET_INTEL)
return false;
if (!NONDEBUG_INSN_P (top))
return false;
if (!NONJUMP_INSN_P (top))
return false;
if (!NONDEBUG_INSN_P (next))
return false;
if (!NONJUMP_INSN_P (next))
return false;
set = single_set (top);
if (!set)
return false;
set = single_set (next);
if (!set)
return false;
if (INSN_PRIORITY_KNOWN (top) && INSN_PRIORITY_KNOWN (next))
{
if (INSN_PRIORITY (top) != INSN_PRIORITY (next))
return false;
/* Determine winner more precise. */
FOR_EACH_DEP (top, SD_LIST_RES_BACK, sd_it, dep)
{
rtx pro;
pro = DEP_PRO (dep);
if (!NONDEBUG_INSN_P (pro))
continue;
if (INSN_TICK (pro) > clock1)
clock1 = INSN_TICK (pro);
}
FOR_EACH_DEP (next, SD_LIST_RES_BACK, sd_it, dep)
{
rtx pro;
pro = DEP_PRO (dep);
if (!NONDEBUG_INSN_P (pro))
continue;
if (INSN_TICK (pro) > clock2)
clock2 = INSN_TICK (pro);
}
if (clock1 == clock2)
{
/* Determine winner - load must win. */
enum attr_memory memory1, memory2;
memory1 = get_attr_memory (top);
memory2 = get_attr_memory (next);
if (memory2 == MEMORY_LOAD && memory1 != MEMORY_LOAD)
return true;
}
return (bool) (clock2 < clock1);
}
return false;
#undef INSN_TICK
}
/* Perform possible reodering of ready list for Atom/Silvermont only.
Return issue rate. */
int
ix86_atom_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready,
int *pn_ready, int clock_var)
{
int issue_rate = -1;
int n_ready = *pn_ready;
int i;
rtx_insn *insn;
int index = -1;
/* Set up issue rate. */
issue_rate = ix86_issue_rate ();
/* Do reodering for BONNELL/SILVERMONT only. */
if (!TARGET_BONNELL && !TARGET_SILVERMONT && !TARGET_INTEL)
return issue_rate;
/* Nothing to do if ready list contains only 1 instruction. */
if (n_ready <= 1)
return issue_rate;
/* Do reodering for post-reload scheduler only. */
if (!reload_completed)
return issue_rate;
if ((index = do_reorder_for_imul (ready, n_ready)) >= 0)
{
if (sched_verbose > 1)
fprintf (dump, ";;\tatom sched_reorder: put %d insn on top\n",
INSN_UID (ready[index]));
/* Put IMUL producer (ready[index]) at the top of ready list. */
insn = ready[index];
for (i = index; i < n_ready - 1; i++)
ready[i] = ready[i + 1];
ready[n_ready - 1] = insn;
return issue_rate;
}
/* Skip selective scheduling since HID is not populated in it. */
if (clock_var != 0
&& !sel_sched_p ()
&& swap_top_of_ready_list (ready, n_ready))
{
if (sched_verbose > 1)
fprintf (dump, ";;\tslm sched_reorder: swap %d and %d insns\n",
INSN_UID (ready[n_ready - 1]), INSN_UID (ready[n_ready - 2]));
/* Swap 2 top elements of ready list. */
insn = ready[n_ready - 1];
ready[n_ready - 1] = ready[n_ready - 2];
ready[n_ready - 2] = insn;
}
return issue_rate;
}
/* Scheduler hooks for IA-32 which implement bdver1-4 specific logic.
Copyright (C) 1988-2017 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "tm_p.h"
#include "insn-config.h"
#include "insn-attr.h"
#include "recog.h"
#include "target.h"
#include "rtl-iter.h"
#include "regset.h"
#include "sched-int.h"
/* Model decoder of Core 2/i7.
Below hooks for multipass scheduling (see haifa-sched.c:max_issue)
track the instruction fetch block boundaries and make sure that long
(9+ bytes) instructions are assigned to D0. */
/* Maximum length of an insn that can be handled by
a secondary decoder unit. '8' for Core 2/i7. */
static int core2i7_secondary_decoder_max_insn_size;
/* Ifetch block size, i.e., number of bytes decoder reads per cycle.
'16' for Core 2/i7. */
static int core2i7_ifetch_block_size;
/* Maximum number of instructions decoder can handle per cycle.
'6' for Core 2/i7. */
static int core2i7_ifetch_block_max_insns;
typedef struct ix86_first_cycle_multipass_data_ *
ix86_first_cycle_multipass_data_t;
typedef const struct ix86_first_cycle_multipass_data_ *
const_ix86_first_cycle_multipass_data_t;
/* A variable to store target state across calls to max_issue within
one cycle. */
static struct ix86_first_cycle_multipass_data_ _ix86_first_cycle_multipass_data,
*ix86_first_cycle_multipass_data = &_ix86_first_cycle_multipass_data;
/* Initialize DATA. */
static void
core2i7_first_cycle_multipass_init (void *_data)
{
ix86_first_cycle_multipass_data_t data
= (ix86_first_cycle_multipass_data_t) _data;
data->ifetch_block_len = 0;
data->ifetch_block_n_insns = 0;
data->ready_try_change = NULL;
data->ready_try_change_size = 0;
}
/* Advancing the cycle; reset ifetch block counts. */
static void
core2i7_dfa_post_advance_cycle (void)
{
ix86_first_cycle_multipass_data_t data = ix86_first_cycle_multipass_data;
gcc_assert (data->ifetch_block_n_insns <= core2i7_ifetch_block_max_insns);
data->ifetch_block_len = 0;
data->ifetch_block_n_insns = 0;
}
/* Filter out insns from ready_try that the core will not be able to issue
on current cycle due to decoder. */
static void
core2i7_first_cycle_multipass_filter_ready_try
(const_ix86_first_cycle_multipass_data_t data,
signed char *ready_try, int n_ready, bool first_cycle_insn_p)
{
while (n_ready--)
{
rtx_insn *insn;
int insn_size;
if (ready_try[n_ready])
continue;
insn = get_ready_element (n_ready);
insn_size = ix86_min_insn_size (insn);
if (/* If this is a too long an insn for a secondary decoder ... */
(!first_cycle_insn_p
&& insn_size > core2i7_secondary_decoder_max_insn_size)
/* ... or it would not fit into the ifetch block ... */
|| data->ifetch_block_len + insn_size > core2i7_ifetch_block_size
/* ... or the decoder is full already ... */
|| data->ifetch_block_n_insns + 1 > core2i7_ifetch_block_max_insns)
/* ... mask the insn out. */
{
ready_try[n_ready] = 1;
if (data->ready_try_change)
bitmap_set_bit (data->ready_try_change, n_ready);
}
}
}
/* Prepare for a new round of multipass lookahead scheduling. */
static void
core2i7_first_cycle_multipass_begin (void *_data,
signed char *ready_try, int n_ready,
bool first_cycle_insn_p)
{
ix86_first_cycle_multipass_data_t data
= (ix86_first_cycle_multipass_data_t) _data;
const_ix86_first_cycle_multipass_data_t prev_data
= ix86_first_cycle_multipass_data;
/* Restore the state from the end of the previous round. */
data->ifetch_block_len = prev_data->ifetch_block_len;
data->ifetch_block_n_insns = prev_data->ifetch_block_n_insns;
/* Filter instructions that cannot be issued on current cycle due to
decoder restrictions. */
core2i7_first_cycle_multipass_filter_ready_try (data, ready_try, n_ready,
first_cycle_insn_p);
}
/* INSN is being issued in current solution. Account for its impact on
the decoder model. */
static void
core2i7_first_cycle_multipass_issue (void *_data,
signed char *ready_try, int n_ready,
rtx_insn *insn, const void *_prev_data)
{
ix86_first_cycle_multipass_data_t data
= (ix86_first_cycle_multipass_data_t) _data;
const_ix86_first_cycle_multipass_data_t prev_data
= (const_ix86_first_cycle_multipass_data_t) _prev_data;
int insn_size = ix86_min_insn_size (insn);
data->ifetch_block_len = prev_data->ifetch_block_len + insn_size;
data->ifetch_block_n_insns = prev_data->ifetch_block_n_insns + 1;
gcc_assert (data->ifetch_block_len <= core2i7_ifetch_block_size
&& data->ifetch_block_n_insns <= core2i7_ifetch_block_max_insns);
/* Allocate or resize the bitmap for storing INSN's effect on ready_try. */
if (!data->ready_try_change)
{
data->ready_try_change = sbitmap_alloc (n_ready);
data->ready_try_change_size = n_ready;
}
else if (data->ready_try_change_size < n_ready)
{
data->ready_try_change = sbitmap_resize (data->ready_try_change,
n_ready, 0);
data->ready_try_change_size = n_ready;
}
bitmap_clear (data->ready_try_change);
/* Filter out insns from ready_try that the core will not be able to issue
on current cycle due to decoder. */
core2i7_first_cycle_multipass_filter_ready_try (data, ready_try, n_ready,
false);
}
/* Revert the effect on ready_try. */
static void
core2i7_first_cycle_multipass_backtrack (const void *_data,
signed char *ready_try,
int n_ready ATTRIBUTE_UNUSED)
{
const_ix86_first_cycle_multipass_data_t data
= (const_ix86_first_cycle_multipass_data_t) _data;
unsigned int i = 0;
sbitmap_iterator sbi;
gcc_assert (bitmap_last_set_bit (data->ready_try_change) < n_ready);
EXECUTE_IF_SET_IN_BITMAP (data->ready_try_change, 0, i, sbi)
{
ready_try[i] = 0;
}
}
/* Save the result of multipass lookahead scheduling for the next round. */
static void
core2i7_first_cycle_multipass_end (const void *_data)
{
const_ix86_first_cycle_multipass_data_t data
= (const_ix86_first_cycle_multipass_data_t) _data;
ix86_first_cycle_multipass_data_t next_data
= ix86_first_cycle_multipass_data;
if (data != NULL)
{
next_data->ifetch_block_len = data->ifetch_block_len;
next_data->ifetch_block_n_insns = data->ifetch_block_n_insns;
}
}
/* Deallocate target data. */
static void
core2i7_first_cycle_multipass_fini (void *_data)
{
ix86_first_cycle_multipass_data_t data
= (ix86_first_cycle_multipass_data_t) _data;
if (data->ready_try_change)
{
sbitmap_free (data->ready_try_change);
data->ready_try_change = NULL;
data->ready_try_change_size = 0;
}
}
void
ix86_core2i7_init_hooks (void)
{
targetm.sched.dfa_post_advance_cycle
= core2i7_dfa_post_advance_cycle;
targetm.sched.first_cycle_multipass_init
= core2i7_first_cycle_multipass_init;
targetm.sched.first_cycle_multipass_begin
= core2i7_first_cycle_multipass_begin;
targetm.sched.first_cycle_multipass_issue
= core2i7_first_cycle_multipass_issue;
targetm.sched.first_cycle_multipass_backtrack
= core2i7_first_cycle_multipass_backtrack;
targetm.sched.first_cycle_multipass_end
= core2i7_first_cycle_multipass_end;
targetm.sched.first_cycle_multipass_fini
= core2i7_first_cycle_multipass_fini;
/* Set decoder parameters. */
core2i7_secondary_decoder_max_insn_size = 8;
core2i7_ifetch_block_size = 16;
core2i7_ifetch_block_max_insns = 6;
}
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