Cleanup and improve multipass_dfa_lookahead_guard

* config/i386/i386.c (core2i7_first_cycle_multipass_filter_ready_try,)
	(core2i7_first_cycle_multipass_begin,)
	(core2i7_first_cycle_multipass_issue,)
	(core2i7_first_cycle_multipass_backtrack): Update signature.
	* config/ia64/ia64.c
	(ia64_first_cycle_multipass_dfa_lookahead_guard_spec): Remove.
	(ia64_first_cycle_multipass_dfa_lookahead_guard): Update signature.
	(TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC): Remove
	hook definition.
	(ia64_first_cycle_multipass_dfa_lookahead_guard): Merge logic from
	ia64_first_cycle_multipass_dfa_lookahead_guard_spec.  Update return
	values.
	* config/rs6000/rs6000.c (rs6000_use_sched_lookahead_guard): Update
	return values.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in
	(TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC): Remove.
	* haifa-sched.c (ready_try): Make signed to allow negative values.
	(rebug_ready_list_1): Update.
	(choose_ready): Simplify.
	(sched_extend_ready_list): Update.

From-SVN: r210747
This commit is contained in:
Maxim Kuvyrkov 2014-05-22 07:26:00 +00:00 committed by Maxim Kuvyrkov
parent 16d83dd6f8
commit 4960a0cb38
10 changed files with 136 additions and 124 deletions

View File

@ -1,3 +1,28 @@
2014-05-22 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
Cleanup and improve multipass_dfa_lookahead_guard
* config/i386/i386.c (core2i7_first_cycle_multipass_filter_ready_try,)
(core2i7_first_cycle_multipass_begin,)
(core2i7_first_cycle_multipass_issue,)
(core2i7_first_cycle_multipass_backtrack): Update signature.
* config/ia64/ia64.c
(ia64_first_cycle_multipass_dfa_lookahead_guard_spec): Remove.
(ia64_first_cycle_multipass_dfa_lookahead_guard): Update signature.
(TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC): Remove
hook definition.
(ia64_first_cycle_multipass_dfa_lookahead_guard): Merge logic from
ia64_first_cycle_multipass_dfa_lookahead_guard_spec. Update return
values.
* config/rs6000/rs6000.c (rs6000_use_sched_lookahead_guard): Update
return values.
* doc/tm.texi: Regenerate.
* doc/tm.texi.in
(TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC): Remove.
* haifa-sched.c (ready_try): Make signed to allow negative values.
(rebug_ready_list_1): Update.
(choose_ready): Simplify.
(sched_extend_ready_list): Update.
2014-05-22 Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org>
Remove IA64 speculation tweaking flags

View File

@ -26383,7 +26383,7 @@ static int min_insn_size (rtx);
static void
core2i7_first_cycle_multipass_filter_ready_try
(const_ix86_first_cycle_multipass_data_t data,
char *ready_try, int n_ready, bool first_cycle_insn_p)
signed char *ready_try, int n_ready, bool first_cycle_insn_p)
{
while (n_ready--)
{
@ -26415,7 +26415,8 @@ core2i7_first_cycle_multipass_filter_ready_try
/* Prepare for a new round of multipass lookahead scheduling. */
static void
core2i7_first_cycle_multipass_begin (void *_data, char *ready_try, int n_ready,
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
@ -26436,7 +26437,8 @@ core2i7_first_cycle_multipass_begin (void *_data, char *ready_try, int n_ready,
/* INSN is being issued in current solution. Account for its impact on
the decoder model. */
static void
core2i7_first_cycle_multipass_issue (void *_data, char *ready_try, int n_ready,
core2i7_first_cycle_multipass_issue (void *_data,
signed char *ready_try, int n_ready,
rtx insn, const void *_prev_data)
{
ix86_first_cycle_multipass_data_t data
@ -26474,7 +26476,7 @@ core2i7_first_cycle_multipass_issue (void *_data, char *ready_try, int n_ready,
/* Revert the effect on ready_try. */
static void
core2i7_first_cycle_multipass_backtrack (const void *_data,
char *ready_try,
signed char *ready_try,
int n_ready ATTRIBUTE_UNUSED)
{
const_ix86_first_cycle_multipass_data_t data

View File

@ -169,8 +169,7 @@ static int ia64_first_cycle_multipass_dfa_lookahead (void);
static void ia64_dependencies_evaluation_hook (rtx, rtx);
static void ia64_init_dfa_pre_cycle_insn (void);
static rtx ia64_dfa_pre_cycle_insn (void);
static int ia64_first_cycle_multipass_dfa_lookahead_guard (rtx);
static bool ia64_first_cycle_multipass_dfa_lookahead_guard_spec (const_rtx);
static int ia64_first_cycle_multipass_dfa_lookahead_guard (rtx, int);
static int ia64_dfa_new_cycle (FILE *, int, rtx, int, int, int *);
static void ia64_h_i_d_extended (void);
static void * ia64_alloc_sched_context (void);
@ -496,10 +495,6 @@ static const struct attribute_spec ia64_attribute_table[] =
#undef TARGET_SCHED_GEN_SPEC_CHECK
#define TARGET_SCHED_GEN_SPEC_CHECK ia64_gen_spec_check
#undef TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC
#define TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC\
ia64_first_cycle_multipass_dfa_lookahead_guard_spec
#undef TARGET_SCHED_SKIP_RTX_P
#define TARGET_SCHED_SKIP_RTX_P ia64_skip_rtx_p
@ -7531,32 +7526,28 @@ ia64_variable_issue (FILE *dump ATTRIBUTE_UNUSED,
return 1;
}
/* We are choosing insn from the ready queue. Return nonzero if INSN
/* We are choosing insn from the ready queue. Return zero if INSN
can be chosen. */
static int
ia64_first_cycle_multipass_dfa_lookahead_guard (rtx insn)
ia64_first_cycle_multipass_dfa_lookahead_guard (rtx insn, int ready_index)
{
gcc_assert (insn && INSN_P (insn));
return ((!reload_completed
|| !safe_group_barrier_needed (insn))
&& ia64_first_cycle_multipass_dfa_lookahead_guard_spec (insn)
&& (!mflag_sched_mem_insns_hard_limit
|| !is_load_p (insn)
|| mem_ops_in_group[current_cycle % 4] < ia64_max_memory_insns));
}
/* We are choosing insn from the ready queue. Return nonzero if INSN
can be chosen. */
/* Size of ALAT is 32. As far as we perform conservative
data speculation, we keep ALAT half-empty. */
if ((TODO_SPEC (insn) & BEGIN_DATA) && pending_data_specs >= 16)
return ready_index == 0 ? -1 : 1;
static bool
ia64_first_cycle_multipass_dfa_lookahead_guard_spec (const_rtx insn)
{
gcc_assert (insn && INSN_P (insn));
/* Size of ALAT is 32. As far as we perform conservative data speculation,
we keep ALAT half-empty. */
return (pending_data_specs < 16
|| !(TODO_SPEC (insn) & BEGIN_DATA));
if (ready_index == 0)
return 0;
if ((!reload_completed
|| !safe_group_barrier_needed (insn))
&& (!mflag_sched_mem_insns_hard_limit
|| !is_load_p (insn)
|| mem_ops_in_group[current_cycle % 4] < ia64_max_memory_insns))
return 0;
}
/* The following variable value is pseudo-insn used by the DFA insn

View File

@ -26796,22 +26796,25 @@ rs6000_use_sched_lookahead (void)
}
}
/* We are choosing insn from the ready queue. Return nonzero if INSN can be chosen. */
/* We are choosing insn from the ready queue. Return zero if INSN can be
chosen. */
static int
rs6000_use_sched_lookahead_guard (rtx insn)
rs6000_use_sched_lookahead_guard (rtx insn, int ready_index)
{
if (rs6000_cpu_attr != CPU_CELL)
return 1;
if (ready_index == 0)
return 0;
if (insn == NULL_RTX || !INSN_P (insn))
abort ();
if (rs6000_cpu_attr != CPU_CELL)
return 0;
gcc_assert (insn != NULL_RTX && INSN_P (insn));
if (!reload_completed
|| is_nonpipeline_insn (insn)
|| is_microcoded_insn (insn))
return 0;
return 1;
return 1;
return 0;
}
/* Determine if PAT refers to memory. If so, set MEM_REF to the MEM rtx

View File

@ -6716,26 +6716,32 @@ schedules to choose the best one.
The default is no multipass scheduling.
@end deftypefn
@deftypefn {Target Hook} int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD (rtx @var{insn})
@deftypefn {Target Hook} int TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD (rtx @var{insn}, int @var{ready_index})
This hook controls what insns from the ready insn queue will be
considered for the multipass insn scheduling. If the hook returns
zero for @var{insn}, the insn will be not chosen to
be issued.
zero for @var{insn}, the insn will be considered in multipass scheduling.
Positive return values will remove @var{insn} from consideration on
the current round of multipass scheduling.
Negative return values will remove @var{insn} from consideration for given
number of cycles.
Backends should be careful about returning non-zero for highest priority
instruction at position 0 in the ready list. @var{ready_index} is passed
to allow backends make correct judgements.
The default is that any ready insns can be chosen to be issued.
@end deftypefn
@deftypefn {Target Hook} void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BEGIN (void *@var{data}, char *@var{ready_try}, int @var{n_ready}, bool @var{first_cycle_insn_p})
@deftypefn {Target Hook} void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BEGIN (void *@var{data}, signed char *@var{ready_try}, int @var{n_ready}, bool @var{first_cycle_insn_p})
This hook prepares the target backend for a new round of multipass
scheduling.
@end deftypefn
@deftypefn {Target Hook} void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_ISSUE (void *@var{data}, char *@var{ready_try}, int @var{n_ready}, rtx @var{insn}, const void *@var{prev_data})
@deftypefn {Target Hook} void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_ISSUE (void *@var{data}, signed char *@var{ready_try}, int @var{n_ready}, rtx @var{insn}, const void *@var{prev_data})
This hook is called when multipass scheduling evaluates instruction INSN.
@end deftypefn
@deftypefn {Target Hook} void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BACKTRACK (const void *@var{data}, char *@var{ready_try}, int @var{n_ready})
@deftypefn {Target Hook} void TARGET_SCHED_FIRST_CYCLE_MULTIPASS_BACKTRACK (const void *@var{data}, signed char *@var{ready_try}, int @var{n_ready})
This is called when multipass scheduling backtracks from evaluation of
an instruction.
@end deftypefn
@ -6843,19 +6849,6 @@ a pattern for a branchy check corresponding to a simple check denoted by
@var{insn} should be generated. In this case @var{label} can't be null.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC (const_rtx @var{insn})
This hook is used as a workaround for
@samp{TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD} not being
called on the first instruction of the ready list. The hook is used to
discard speculative instructions that stand first in the ready list from
being scheduled on the current cycle. If the hook returns @code{false},
@var{insn} will not be chosen to be issued.
For non-speculative instructions,
the hook should always return @code{true}. For example, in the ia64 backend
the hook is used to cancel data speculative insns when the ALAT table
is nearly full.
@end deftypefn
@deftypefn {Target Hook} void TARGET_SCHED_SET_SCHED_FLAGS (struct spec_info_def *@var{spec_info})
This hook is used by the insn scheduler to find out what features should be
enabled/used.

View File

@ -5019,8 +5019,6 @@ them: try the first ones in this list first.
@hook TARGET_SCHED_GEN_SPEC_CHECK
@hook TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD_SPEC
@hook TARGET_SCHED_SET_SCHED_FLAGS
@hook TARGET_SCHED_SMS_RES_MII

View File

@ -345,7 +345,7 @@ size_t dfa_state_size;
/* The following array is used to find the best insn from ready when
the automaton pipeline interface is used. */
char *ready_try = NULL;
signed char *ready_try = NULL;
/* The ready list. */
struct ready_list ready = {NULL, 0, 0, 0, 0};
@ -5126,7 +5126,7 @@ early_queue_to_ready (state_t state, struct ready_list *ready)
If READY_TRY is non-zero then only print insns that max_issue
will consider. */
static void
debug_ready_list_1 (struct ready_list *ready, char *ready_try)
debug_ready_list_1 (struct ready_list *ready, signed char *ready_try)
{
rtx *p;
int i;
@ -5566,10 +5566,9 @@ choose_ready (struct ready_list *ready, bool first_cycle_insn_p,
}
else
{
/* Try to choose the better insn. */
/* Try to choose the best insn. */
int index = 0, i;
rtx insn;
ds_t ts;
insn = ready_element (ready, 0);
if (INSN_CODE (insn) < 0)
@ -5578,42 +5577,56 @@ choose_ready (struct ready_list *ready, bool first_cycle_insn_p,
return 0;
}
ts = TODO_SPEC (insn);
if ((ts & SPECULATIVE)
&& (targetm.sched.first_cycle_multipass_dfa_lookahead_guard_spec
&& (!targetm.sched
.first_cycle_multipass_dfa_lookahead_guard_spec (insn))))
/* Discard speculative instruction that stands first in the ready
list. */
{
change_queue_index (insn, 1);
return 1;
}
/* Filter the search space. */
for (i = 0; i < ready->n_ready; i++)
ready_try [i] = 0;
{
ready_try[i] = 0;
/* Let the target filter the search space. */
for (i = 1; i < ready->n_ready; i++)
if (!ready_try[i])
{
insn = ready_element (ready, i);
insn = ready_element (ready, i);
/* If this insn is recognizable we should have already
recognized it earlier.
??? Not very clear where this is supposed to be done.
See dep_cost_1. */
gcc_checking_assert (INSN_CODE (insn) >= 0
|| recog_memoized (insn) < 0);
/* If this insn is recognizable we should have already
recognized it earlier.
??? Not very clear where this is supposed to be done.
See dep_cost_1. */
gcc_checking_assert (INSN_CODE (insn) >= 0
|| recog_memoized (insn) < 0);
if (INSN_CODE (insn) < 0)
{
/* Non-recognized insns at position 0 are handled above. */
gcc_assert (i > 0);
ready_try[i] = 1;
continue;
}
ready_try [i]
= (/* INSN_CODE check can be omitted here as it is also done later
in max_issue (). */
INSN_CODE (insn) < 0
|| (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
&& !targetm.sched.first_cycle_multipass_dfa_lookahead_guard
(insn)));
}
if (targetm.sched.first_cycle_multipass_dfa_lookahead_guard)
{
ready_try[i]
= (targetm.sched.first_cycle_multipass_dfa_lookahead_guard
(insn, i));
if (ready_try[i] < 0)
/* Queue instruction for several cycles.
We need to restart choose_ready as we have changed
the ready list. */
{
change_queue_index (insn, -ready_try[i]);
return 1;
}
/* Make sure that we didn't end up with 0'th insn filtered out.
Don't be tempted to make life easier for backends and just
requeue 0'th insn if (ready_try[0] == 0) and restart
choose_ready. Backends should be very considerate about
requeueing instructions -- especially the highest priority
one at position 0. */
gcc_assert (ready_try[i] == 0 || i > 0);
if (ready_try[i])
continue;
}
gcc_assert (ready_try[i] == 0);
/* INSN made it through the scrutiny of filters! */
}
if (max_issue (ready, 1, curr_state, first_cycle_insn_p, &index) == 0)
{
@ -7193,8 +7206,9 @@ sched_extend_ready_list (int new_sched_ready_n_insns)
gcc_assert (new_sched_ready_n_insns >= sched_ready_n_insns);
ready_try = (char *) xrecalloc (ready_try, new_sched_ready_n_insns,
sched_ready_n_insns, sizeof (*ready_try));
ready_try = (signed char *) xrecalloc (ready_try, new_sched_ready_n_insns,
sched_ready_n_insns,
sizeof (*ready_try));
/* We allocate +1 element to save initial state in the choice_stack[0]
entry. */

View File

@ -170,7 +170,7 @@ struct ready_list
int n_debug;
};
extern char *ready_try;
extern signed char *ready_try;
extern struct ready_list ready;
extern int max_issue (struct ready_list *, int, state_t, bool, int *);

View File

@ -4225,7 +4225,7 @@ invoke_dfa_lookahead_guard (void)
if (! have_hook || i == 0)
r = 0;
else
r = !targetm.sched.first_cycle_multipass_dfa_lookahead_guard (insn);
r = targetm.sched.first_cycle_multipass_dfa_lookahead_guard (insn, i);
gcc_assert (INSN_CODE (insn) >= 0);

View File

@ -1174,11 +1174,17 @@ DEFHOOK
"\n\
This hook controls what insns from the ready insn queue will be\n\
considered for the multipass insn scheduling. If the hook returns\n\
zero for @var{insn}, the insn will be not chosen to\n\
be issued.\n\
zero for @var{insn}, the insn will be considered in multipass scheduling.\n\
Positive return values will remove @var{insn} from consideration on\n\
the current round of multipass scheduling.\n\
Negative return values will remove @var{insn} from consideration for given\n\
number of cycles.\n\
Backends should be careful about returning non-zero for highest priority\n\
instruction at position 0 in the ready list. @var{ready_index} is passed\n\
to allow backends make correct judgements.\n\
\n\
The default is that any ready insns can be chosen to be issued.",
int, (rtx insn), NULL)
int, (rtx insn, int ready_index), NULL)
/* This hook prepares the target for a new round of multipass
scheduling.
@ -1193,7 +1199,7 @@ DEFHOOK
(first_cycle_multipass_begin,
"This hook prepares the target backend for a new round of multipass\n\
scheduling.",
void, (void *data, char *ready_try, int n_ready, bool first_cycle_insn_p),
void, (void *data, signed char *ready_try, int n_ready, bool first_cycle_insn_p),
NULL)
/* This hook is called when multipass scheduling evaluates instruction INSN.
@ -1209,7 +1215,7 @@ scheduling.",
DEFHOOK
(first_cycle_multipass_issue,
"This hook is called when multipass scheduling evaluates instruction INSN.",
void, (void *data, char *ready_try, int n_ready, rtx insn,
void, (void *data, signed char *ready_try, int n_ready, rtx insn,
const void *prev_data), NULL)
/* This hook is called when multipass scheduling backtracks from evaluation of
@ -1225,7 +1231,7 @@ DEFHOOK
(first_cycle_multipass_backtrack,
"This is called when multipass scheduling backtracks from evaluation of\n\
an instruction.",
void, (const void *data, char *ready_try, int n_ready), NULL)
void, (const void *data, signed char *ready_try, int n_ready), NULL)
/* This hook notifies the target about the result of the concluded current
round of multipass scheduling.
@ -1421,26 +1427,6 @@ a pattern for a branchy check corresponding to a simple check denoted by\n\
@var{insn} should be generated. In this case @var{label} can't be null.",
rtx, (rtx insn, rtx label, unsigned int ds), NULL)
/* The following member value is a pointer to a function controlling
what insns from the ready insn queue will be considered for the
multipass insn scheduling. If the hook returns zero for the insn
passed as the parameter, the insn will not be chosen to be
issued. This hook is used to discard speculative instructions,
that stand at the first position of the ready list. */
DEFHOOK
(first_cycle_multipass_dfa_lookahead_guard_spec,
"This hook is used as a workaround for\n\
@samp{TARGET_SCHED_FIRST_CYCLE_MULTIPASS_DFA_LOOKAHEAD_GUARD} not being\n\
called on the first instruction of the ready list. The hook is used to\n\
discard speculative instructions that stand first in the ready list from\n\
being scheduled on the current cycle. If the hook returns @code{false},\n\
@var{insn} will not be chosen to be issued.\n\
For non-speculative instructions,\n\
the hook should always return @code{true}. For example, in the ia64 backend\n\
the hook is used to cancel data speculative insns when the ALAT table\n\
is nearly full.",
bool, (const_rtx insn), NULL)
/* The following member value is a pointer to a function that provides
information about the speculation capabilities of the target.
The parameter is a pointer to spec_info variable. */