Commit e2724e63 by Bernd Schmidt Committed by Bernd Schmidt

reg-notes.def (DEP_CONTROL): New.

	* reg-notes.def (DEP_CONTROL): New.
	* sched-ebb.c (add_deps_for_risky_insns): Add a REG_DEP_CONTROL when
	not doing speculation.
	* rtlanal.c (record_hard_reg_sets, find_all_hard_reg_sets,
	record_hard_reg_uses_1, record_hard_reg_uses): New functions.
	* function.c (record_hard_reg_sets, record_hard_reg_uses,
	record_hard_reg_uses_1): Remove; move to rtlanal.c.
	* lists.c (copy_INSN_LIST, concat_INSN_LIST): New functions.
	* haifa-sched.c: Swap includes of "rtl.h" and "hard-reg-set.h".
	(MUST_RECOMPUTE_SPEC_P): New macro.
	(real_insn_for_shadow): New function.
	(cond_clobbered_p, recompute_todo_spec, check_clobbered_conditions,
	toggle_cancelled_flags): New static functions.
	(schedule_insn): Relax an assert to only check for empty hard back
	dependencies.  Skip cancelled dependencies.  Call
	check_clobbered_conditions.
	(copy_insn_list): Remove function, renamed moved to lists.c.
	(save_backtrack_point): Use new spelling copy_INSN_LIST.
	(unschedule_insns_until): Ensure TODO_SPEC is reset properly.
	(restore_last_backtrack_point): Likewise.  Call toggle_cancelled_flags.
	(estimate_insn_tick): Ignore cancelled dependencies.
	(haifa_speculate_insn): Move declaration.
	(try_ready): Move code into recompute_todo_spec and call it.  Tweak
	some asserts.  Ensure predicated patterns are restored if necessary.
	Dump DEP_CONTROL flag.
	(haifa_change_pattern): Merge with sched_change_pattern.
	(sched_change_pattern): Remove function.
	* sched-deps.c (NON_FLUSH_JUMP_KIND, NON_FLUSH_JUMP): Remove.  All
	uses changed to simply not test NON_FLUSH_JUMP_P.
	(ds_to_dk, dk_to_ds, dump_dep, ds_to_dt, dump_ds, check_dep): Handle
	REG_DEP_CONTROL.
	(dep_spec_p): If DO_PREDICATION, REG_DEP_CONTROL is speculative.
	(reg_pending_control_uses, control_dependency_cache): New static
	variables.
	(sched_get_reverse_condition_uncached): New function.
	(sd_find_dep_between): Remove pointless assert.  Look in
	control_dependency_cache.
	(ask_dependency_caches, set_dependency_caches, sd_delete_dep,
	extend_dependency_caches, sched_deps_finish): Handle REG_DEP_CONTROL
	and control_dependency_cache.
	(sd_unresolve_dep): Use dep_spec_p.
	(add_dependence): Now a wrapper around add_dependence_1, handling
	REG_DEP_CONTROL specially.
	(flush_pending_lists): Clear pending_jump_insns.
	(sched_analyze_1): Handle pending_jump_insns like a memory flush.
	(sched_analyze_2): Unconditionally add to pending memory flushes,
	keep previous behaviour but apply it to pending_jump_insns instead.
	(sched_analyze_insn): Defer adding jump reg dependencies using
	reg_pending_control_uses; add them to the control_uses list.  Handle
	pending_jump_insns and control_uses when adding dependence lists.
	(deps_analyze_insn): Update INSN_COND_DEPS.
	(deps_analyze_insn): Add jumps to pending_jump_insns rather than
	last_pending_memory_flush.
	(init_deps): Initialize pending_jump_insns.
	(free_deps): Free control_uses.
	(remove_from_deps): Remove from pending_jump_insns.
	(init_deps_global): Allocate reg_pending_control_uses).
	(finish_deps_global): Free it.
	(add_dependence_1): Renamed from add_dependence.  Handle
	REG_DEP_CONTROL.
	* rtl.h (record_hard_reg_uses, find_all_hard_reg_sets): Declare.
	(copy_INSN_LIST, concat_INSN_LIST): Declare.
	* sched-int.h (struct deps_reg): Add control_uses.
	(struct deps_desc): Add pending_jump_insns.
	(struct _haifa_deps_insn_data): Add cond_deps.
	(struct _haifa_insn_data): Add must_recompute_spec and predicated_pat.
	(INSN_COND_DEPS, PREDICATED_PAT): New macros.
	(BITS_PER_DEP_WEAK): Adjust for two extra bits in the word.
	(DEP_CONTROL): New macro.
	(DEP_TYPES): Include it.
	(HARD_DEP): Adjust definition.
	(DEP_CANCELLED): New macro.
	(enum SCHED_FLAGS): Add DO_PREDICATION.
	(sched_get_reverse_condition_uncached, real_insn_for_shadow): Declare.
	* sched-rgn.c (concat_INSN_LIST): Remove function.
	(deps_join): Handle pending_jump_insns.
	(free_pending_lists): Likewise.
	* config/c6x/c6x.c (c6x_set_sched_flags): Set DO_PREDICATION for final
	schedule.

From-SVN: r180302
parent b9af306b
2011-10-21 Bernd Schmidt <bernds@codesourcery.com>
* reg-notes.def (DEP_CONTROL): New.
* sched-ebb.c (add_deps_for_risky_insns): Add a REG_DEP_CONTROL when
not doing speculation.
* rtlanal.c (record_hard_reg_sets, find_all_hard_reg_sets,
record_hard_reg_uses_1, record_hard_reg_uses): New functions.
* function.c (record_hard_reg_sets, record_hard_reg_uses,
record_hard_reg_uses_1): Remove; move to rtlanal.c.
* lists.c (copy_INSN_LIST, concat_INSN_LIST): New functions.
* haifa-sched.c: Swap includes of "rtl.h" and "hard-reg-set.h".
(MUST_RECOMPUTE_SPEC_P): New macro.
(real_insn_for_shadow): New function.
(cond_clobbered_p, recompute_todo_spec, check_clobbered_conditions,
toggle_cancelled_flags): New static functions.
(schedule_insn): Relax an assert to only check for empty hard back
dependencies. Skip cancelled dependencies. Call
check_clobbered_conditions.
(copy_insn_list): Remove function, renamed moved to lists.c.
(save_backtrack_point): Use new spelling copy_INSN_LIST.
(unschedule_insns_until): Ensure TODO_SPEC is reset properly.
(restore_last_backtrack_point): Likewise. Call toggle_cancelled_flags.
(estimate_insn_tick): Ignore cancelled dependencies.
(haifa_speculate_insn): Move declaration.
(try_ready): Move code into recompute_todo_spec and call it. Tweak
some asserts. Ensure predicated patterns are restored if necessary.
Dump DEP_CONTROL flag.
(haifa_change_pattern): Merge with sched_change_pattern.
(sched_change_pattern): Remove function.
* sched-deps.c (NON_FLUSH_JUMP_KIND, NON_FLUSH_JUMP): Remove. All
uses changed to simply not test NON_FLUSH_JUMP_P.
(ds_to_dk, dk_to_ds, dump_dep, ds_to_dt, dump_ds, check_dep): Handle
REG_DEP_CONTROL.
(dep_spec_p): If DO_PREDICATION, REG_DEP_CONTROL is speculative.
(reg_pending_control_uses, control_dependency_cache): New static
variables.
(sched_get_reverse_condition_uncached): New function.
(sd_find_dep_between): Remove pointless assert. Look in
control_dependency_cache.
(ask_dependency_caches, set_dependency_caches, sd_delete_dep,
extend_dependency_caches, sched_deps_finish): Handle REG_DEP_CONTROL
and control_dependency_cache.
(sd_unresolve_dep): Use dep_spec_p.
(add_dependence): Now a wrapper around add_dependence_1, handling
REG_DEP_CONTROL specially.
(flush_pending_lists): Clear pending_jump_insns.
(sched_analyze_1): Handle pending_jump_insns like a memory flush.
(sched_analyze_2): Unconditionally add to pending memory flushes,
keep previous behaviour but apply it to pending_jump_insns instead.
(sched_analyze_insn): Defer adding jump reg dependencies using
reg_pending_control_uses; add them to the control_uses list. Handle
pending_jump_insns and control_uses when adding dependence lists.
(deps_analyze_insn): Update INSN_COND_DEPS.
(deps_analyze_insn): Add jumps to pending_jump_insns rather than
last_pending_memory_flush.
(init_deps): Initialize pending_jump_insns.
(free_deps): Free control_uses.
(remove_from_deps): Remove from pending_jump_insns.
(init_deps_global): Allocate reg_pending_control_uses).
(finish_deps_global): Free it.
(add_dependence_1): Renamed from add_dependence. Handle
REG_DEP_CONTROL.
* rtl.h (record_hard_reg_uses, find_all_hard_reg_sets): Declare.
(copy_INSN_LIST, concat_INSN_LIST): Declare.
* sched-int.h (struct deps_reg): Add control_uses.
(struct deps_desc): Add pending_jump_insns.
(struct _haifa_deps_insn_data): Add cond_deps.
(struct _haifa_insn_data): Add must_recompute_spec and predicated_pat.
(INSN_COND_DEPS, PREDICATED_PAT): New macros.
(BITS_PER_DEP_WEAK): Adjust for two extra bits in the word.
(DEP_CONTROL): New macro.
(DEP_TYPES): Include it.
(HARD_DEP): Adjust definition.
(DEP_CANCELLED): New macro.
(enum SCHED_FLAGS): Add DO_PREDICATION.
(sched_get_reverse_condition_uncached, real_insn_for_shadow): Declare.
* sched-rgn.c (concat_INSN_LIST): Remove function.
(deps_join): Handle pending_jump_insns.
(free_pending_lists): Likewise.
* config/c6x/c6x.c (c6x_set_sched_flags): Set DO_PREDICATION for final
schedule.
2011-10-21 Georg-Johann Lay <avr@gjlay.de> 2011-10-21 Georg-Johann Lay <avr@gjlay.de>
PR target/50820 PR target/50820
...@@ -3927,7 +3927,7 @@ c6x_set_sched_flags (spec_info_t spec_info) ...@@ -3927,7 +3927,7 @@ c6x_set_sched_flags (spec_info_t spec_info)
if (*flags & SCHED_EBB) if (*flags & SCHED_EBB)
{ {
*flags |= DO_BACKTRACKING; *flags |= DO_BACKTRACKING | DO_PREDICATION;
} }
spec_info->mask = 0; spec_info->mask = 0;
......
...@@ -2892,17 +2892,6 @@ assign_parm_setup_block (struct assign_parm_data_all *all, ...@@ -2892,17 +2892,6 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
SET_DECL_RTL (parm, stack_parm); SET_DECL_RTL (parm, stack_parm);
} }
/* A subroutine of assign_parm_setup_reg, called through note_stores.
This collects sets and clobbers of hard registers in a HARD_REG_SET,
which is pointed to by DATA. */
static void
record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
{
HARD_REG_SET *pset = (HARD_REG_SET *)data;
if (REG_P (x) && HARD_REGISTER_P (x))
add_to_hard_reg_set (pset, GET_MODE (x), REGNO (x));
}
/* A subroutine of assign_parms. Allocate a pseudo to hold the current /* A subroutine of assign_parms. Allocate a pseudo to hold the current
parameter. Get it there. Perform all ABI specified conversions. */ parameter. Get it there. Perform all ABI specified conversions. */
...@@ -5289,25 +5278,6 @@ prologue_epilogue_contains (const_rtx insn) ...@@ -5289,25 +5278,6 @@ prologue_epilogue_contains (const_rtx insn)
#ifdef HAVE_simple_return #ifdef HAVE_simple_return
/* A for_each_rtx subroutine of record_hard_reg_sets. */
static int
record_hard_reg_uses_1 (rtx *px, void *data)
{
rtx x = *px;
HARD_REG_SET *pused = (HARD_REG_SET *)data;
if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
add_to_hard_reg_set (pused, GET_MODE (x), REGNO (x));
return 0;
}
/* Like record_hard_reg_sets, but called through note_uses. */
static void
record_hard_reg_uses (rtx *px, void *data)
{
for_each_rtx (px, record_hard_reg_uses_1, data);
}
/* Return true if INSN requires the stack frame to be set up. /* Return true if INSN requires the stack frame to be set up.
PROLOGUE_USED contains the hard registers used in the function PROLOGUE_USED contains the hard registers used in the function
prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the
......
...@@ -164,6 +164,37 @@ free_INSN_LIST_list (rtx *listp) ...@@ -164,6 +164,37 @@ free_INSN_LIST_list (rtx *listp)
free_list (listp, &unused_insn_list); free_list (listp, &unused_insn_list);
} }
/* Make a copy of the INSN_LIST list LINK and return it. */
rtx
copy_INSN_LIST (rtx link)
{
rtx new_queue;
rtx *pqueue = &new_queue;
for (; link; link = XEXP (link, 1))
{
rtx x = XEXP (link, 0);
rtx newlink = alloc_INSN_LIST (x, NULL);
*pqueue = newlink;
pqueue = &XEXP (newlink, 1);
}
*pqueue = NULL_RTX;
return new_queue;
}
/* Duplicate the INSN_LIST elements of COPY and prepend them to OLD. */
rtx
concat_INSN_LIST (rtx copy, rtx old)
{
rtx new_rtx = old;
for (; copy ; copy = XEXP (copy, 1))
{
new_rtx = alloc_INSN_LIST (XEXP (copy, 0), new_rtx);
PUT_REG_NOTE_KIND (new_rtx, REG_NOTE_KIND (copy));
}
return new_rtx;
}
/* This function will free up an individual EXPR_LIST node. */ /* This function will free up an individual EXPR_LIST node. */
void void
free_EXPR_LIST_node (rtx ptr) free_EXPR_LIST_node (rtx ptr)
......
...@@ -92,6 +92,7 @@ REG_NOTE (LABEL_OPERAND) ...@@ -92,6 +92,7 @@ REG_NOTE (LABEL_OPERAND)
respectively. */ respectively. */
REG_NOTE (DEP_OUTPUT) REG_NOTE (DEP_OUTPUT)
REG_NOTE (DEP_ANTI) REG_NOTE (DEP_ANTI)
REG_NOTE (DEP_CONTROL)
/* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs. It has an /* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs. It has an
integer value. For jumps, it is the probability that this is a integer value. For jumps, it is the probability that this is a
......
...@@ -1941,6 +1941,11 @@ extern rtx find_last_value (rtx, rtx *, rtx, int); ...@@ -1941,6 +1941,11 @@ extern rtx find_last_value (rtx, rtx *, rtx, int);
extern int refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *); extern int refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *);
extern int reg_overlap_mentioned_p (const_rtx, const_rtx); extern int reg_overlap_mentioned_p (const_rtx, const_rtx);
extern const_rtx set_of (const_rtx, const_rtx); extern const_rtx set_of (const_rtx, const_rtx);
extern void record_hard_reg_sets (rtx, const_rtx, void *);
extern void record_hard_reg_uses (rtx *, void *);
#ifdef HARD_CONST
extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *);
#endif
extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *); extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
extern void note_uses (rtx *, void (*) (rtx *, void *), void *); extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
extern int dead_or_set_p (const_rtx, const_rtx); extern int dead_or_set_p (const_rtx, const_rtx);
...@@ -2036,12 +2041,14 @@ extern void subreg_get_info (unsigned int, enum machine_mode, ...@@ -2036,12 +2041,14 @@ extern void subreg_get_info (unsigned int, enum machine_mode,
/* lists.c */ /* lists.c */
extern void free_EXPR_LIST_list (rtx *); extern void free_EXPR_LIST_list (rtx *);
extern void free_INSN_LIST_list (rtx *); extern void free_INSN_LIST_list (rtx *);
extern void free_EXPR_LIST_node (rtx); extern void free_EXPR_LIST_node (rtx);
extern void free_INSN_LIST_node (rtx); extern void free_INSN_LIST_node (rtx);
extern rtx alloc_INSN_LIST (rtx, rtx); extern rtx alloc_INSN_LIST (rtx, rtx);
extern rtx alloc_EXPR_LIST (int, rtx, rtx); extern rtx copy_INSN_LIST (rtx);
extern rtx concat_INSN_LIST (rtx, rtx);
extern rtx alloc_EXPR_LIST (int, rtx, rtx);
extern void remove_free_INSN_LIST_elem (rtx, rtx *); extern void remove_free_INSN_LIST_elem (rtx, rtx *);
extern rtx remove_list_elem (rtx, rtx *); extern rtx remove_list_elem (rtx, rtx *);
extern rtx remove_free_INSN_LIST_node (rtx *); extern rtx remove_free_INSN_LIST_node (rtx *);
......
...@@ -999,6 +999,56 @@ set_of (const_rtx pat, const_rtx insn) ...@@ -999,6 +999,56 @@ set_of (const_rtx pat, const_rtx insn)
note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data); note_stores (INSN_P (insn) ? PATTERN (insn) : insn, set_of_1, &data);
return data.found; return data.found;
} }
/* This function, called through note_stores, collects sets and
clobbers of hard registers in a HARD_REG_SET, which is pointed to
by DATA. */
void
record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
{
HARD_REG_SET *pset = (HARD_REG_SET *)data;
if (REG_P (x) && HARD_REGISTER_P (x))
add_to_hard_reg_set (pset, GET_MODE (x), REGNO (x));
}
/* Examine INSN, and compute the set of hard registers written by it.
Store it in *PSET. Should only be called after reload. */
void
find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset)
{
rtx link;
CLEAR_HARD_REG_SET (*pset);
note_stores (PATTERN (insn), record_hard_reg_sets, pset);
if (CALL_P (insn))
IOR_HARD_REG_SET (*pset, call_used_reg_set);
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC)
record_hard_reg_sets (XEXP (link, 0), NULL, pset);
}
/* A for_each_rtx subroutine of record_hard_reg_uses. */
static int
record_hard_reg_uses_1 (rtx *px, void *data)
{
rtx x = *px;
HARD_REG_SET *pused = (HARD_REG_SET *)data;
if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
{
int nregs = hard_regno_nregs[REGNO (x)][GET_MODE (x)];
while (nregs-- > 0)
SET_HARD_REG_BIT (*pused, REGNO (x) + nregs);
}
return 0;
}
/* Like record_hard_reg_sets, but called through note_uses. */
void
record_hard_reg_uses (rtx *px, void *data)
{
for_each_rtx (px, record_hard_reg_uses_1, data);
}
/* Given an INSN, return a SET expression if this insn has only a single SET. /* Given an INSN, return a SET expression if this insn has only a single SET.
It may also have CLOBBERs, USEs, or SET whose output It may also have CLOBBERs, USEs, or SET whose output
......
...@@ -431,32 +431,23 @@ add_deps_for_risky_insns (rtx head, rtx tail) ...@@ -431,32 +431,23 @@ add_deps_for_risky_insns (rtx head, rtx tail)
rank. */ rank. */
if (! sched_insns_conditions_mutex_p (insn, prev)) if (! sched_insns_conditions_mutex_p (insn, prev))
{ {
dep_def _dep, *dep = &_dep; if ((current_sched_info->flags & DO_SPECULATION)
&& (spec_info->mask & BEGIN_CONTROL))
init_dep (dep, prev, insn, REG_DEP_ANTI);
if (!(current_sched_info->flags & USE_DEPS_LIST))
{ {
enum DEPS_ADJUST_RESULT res; dep_def _dep, *dep = &_dep;
res = sd_add_or_update_dep (dep, false); init_dep (dep, prev, insn, REG_DEP_ANTI);
/* We can't change an existing dependency with if (current_sched_info->flags & USE_DEPS_LIST)
DEP_ANTI. */ {
gcc_assert (res != DEP_CHANGED); DEP_STATUS (dep) = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
} MAX_DEP_WEAK);
else
{
if ((current_sched_info->flags & DO_SPECULATION)
&& (spec_info->mask & BEGIN_CONTROL))
DEP_STATUS (dep) = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
MAX_DEP_WEAK);
}
sd_add_or_update_dep (dep, false); sd_add_or_update_dep (dep, false);
/* Dep_status could have been changed.
No assertion here. */
} }
else
add_dependence (insn, prev, REG_DEP_CONTROL);
} }
break; break;
......
...@@ -424,6 +424,7 @@ struct deps_reg ...@@ -424,6 +424,7 @@ struct deps_reg
rtx uses; rtx uses;
rtx sets; rtx sets;
rtx implicit_sets; rtx implicit_sets;
rtx control_uses;
rtx clobbers; rtx clobbers;
int uses_length; int uses_length;
int clobbers_length; int clobbers_length;
...@@ -453,6 +454,9 @@ struct deps_desc ...@@ -453,6 +454,9 @@ struct deps_desc
/* An EXPR_LIST containing all MEM rtx's which are pending writes. */ /* An EXPR_LIST containing all MEM rtx's which are pending writes. */
rtx pending_write_mems; rtx pending_write_mems;
/* An INSN_LIST containing all jump insns. */
rtx pending_jump_insns;
/* We must prevent the above lists from ever growing too large since /* We must prevent the above lists from ever growing too large since
the number of dependencies produced is at least O(N*N), the number of dependencies produced is at least O(N*N),
and execution time is at least O(4*N*N), as a function of the and execution time is at least O(4*N*N), as a function of the
...@@ -464,8 +468,9 @@ struct deps_desc ...@@ -464,8 +468,9 @@ struct deps_desc
/* Indicates the length of the pending_write list. */ /* Indicates the length of the pending_write list. */
int pending_write_list_length; int pending_write_list_length;
/* Length of the pending memory flush list. Large functions with no /* Length of the pending memory flush list plus the length of the pending
calls may build up extremely large lists. */ jump insn list. Large functions with no calls may build up extremely
large lists. */
int pending_flush_length; int pending_flush_length;
/* The last insn upon which all memory references must depend. /* The last insn upon which all memory references must depend.
...@@ -699,6 +704,10 @@ struct _haifa_deps_insn_data ...@@ -699,6 +704,10 @@ struct _haifa_deps_insn_data
condition that has been clobbered by a subsequent insn. */ condition that has been clobbered by a subsequent insn. */
rtx cond; rtx cond;
/* For a conditional insn, a list of insns that could set the condition
register. Used when generating control dependencies. */
rtx cond_deps;
/* True if the condition in 'cond' should be reversed to get the actual /* True if the condition in 'cond' should be reversed to get the actual
condition. */ condition. */
unsigned int reverse_cond : 1; unsigned int reverse_cond : 1;
...@@ -799,6 +808,10 @@ struct _haifa_insn_data ...@@ -799,6 +808,10 @@ struct _haifa_insn_data
real insns following them. */ real insns following them. */
unsigned int shadow_p : 1; unsigned int shadow_p : 1;
/* Used internally in unschedule_insns_until to mark insns that must have
their TODO_SPEC recomputed. */
unsigned int must_recompute_spec : 1;
/* '> 0' if priority is valid, /* '> 0' if priority is valid,
'== 0' if priority was not yet computed, '== 0' if priority was not yet computed,
'< 0' if priority in invalid and should be recomputed. */ '< 0' if priority in invalid and should be recomputed. */
...@@ -819,6 +832,10 @@ struct _haifa_insn_data ...@@ -819,6 +832,10 @@ struct _haifa_insn_data
/* Original pattern of the instruction. */ /* Original pattern of the instruction. */
rtx orig_pat; rtx orig_pat;
/* For insns with DEP_CONTROL dependencies, the predicated pattern if it
was ever successfully constructed. */
rtx predicated_pat;
/* The following array contains info how the insn increases register /* The following array contains info how the insn increases register
pressure. There is an element for each cover class of pseudos pressure. There is an element for each cover class of pseudos
referenced in insns. */ referenced in insns. */
...@@ -880,6 +897,7 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d; ...@@ -880,6 +897,7 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d;
#define INSN_SPEC_BACK_DEPS(INSN) (HDID (INSN)->spec_back_deps) #define INSN_SPEC_BACK_DEPS(INSN) (HDID (INSN)->spec_back_deps)
#define INSN_CACHED_COND(INSN) (HDID (INSN)->cond) #define INSN_CACHED_COND(INSN) (HDID (INSN)->cond)
#define INSN_REVERSE_COND(INSN) (HDID (INSN)->reverse_cond) #define INSN_REVERSE_COND(INSN) (HDID (INSN)->reverse_cond)
#define INSN_COND_DEPS(INSN) (HDID (INSN)->cond_deps)
#define CANT_MOVE(INSN) (HDID (INSN)->cant_move) #define CANT_MOVE(INSN) (HDID (INSN)->cant_move)
#define CANT_MOVE_BY_LUID(LUID) (VEC_index (haifa_deps_insn_data_def, h_d_i_d, \ #define CANT_MOVE_BY_LUID(LUID) (VEC_index (haifa_deps_insn_data_def, h_d_i_d, \
LUID)->cant_move) LUID)->cant_move)
...@@ -893,6 +911,7 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d; ...@@ -893,6 +911,7 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d;
#define CHECK_SPEC(INSN) (HID (INSN)->check_spec) #define CHECK_SPEC(INSN) (HID (INSN)->check_spec)
#define RECOVERY_BLOCK(INSN) (HID (INSN)->recovery_block) #define RECOVERY_BLOCK(INSN) (HID (INSN)->recovery_block)
#define ORIG_PAT(INSN) (HID (INSN)->orig_pat) #define ORIG_PAT(INSN) (HID (INSN)->orig_pat)
#define PREDICATED_PAT(INSN) (HID (INSN)->predicated_pat)
/* INSN is either a simple or a branchy speculation check. */ /* INSN is either a simple or a branchy speculation check. */
#define IS_SPECULATION_CHECK_P(INSN) \ #define IS_SPECULATION_CHECK_P(INSN) \
...@@ -932,10 +951,11 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d; ...@@ -932,10 +951,11 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d;
/* We exclude sign bit. */ /* We exclude sign bit. */
#define BITS_PER_DEP_STATUS (HOST_BITS_PER_INT - 1) #define BITS_PER_DEP_STATUS (HOST_BITS_PER_INT - 1)
/* First '4' stands for 3 dep type bits and HARD_DEP bit. /* First '6' stands for 4 dep type bits and the HARD_DEP and DEP_CANCELLED
bits.
Second '4' stands for BEGIN_{DATA, CONTROL}, BE_IN_{DATA, CONTROL} Second '4' stands for BEGIN_{DATA, CONTROL}, BE_IN_{DATA, CONTROL}
dep weakness. */ dep weakness. */
#define BITS_PER_DEP_WEAK ((BITS_PER_DEP_STATUS - 4) / 4) #define BITS_PER_DEP_WEAK ((BITS_PER_DEP_STATUS - 6) / 4)
/* Mask of speculative weakness in dep_status. */ /* Mask of speculative weakness in dep_status. */
#define DEP_WEAK_MASK ((1 << BITS_PER_DEP_WEAK) - 1) #define DEP_WEAK_MASK ((1 << BITS_PER_DEP_WEAK) - 1)
...@@ -1009,13 +1029,16 @@ enum SPEC_TYPES_OFFSETS { ...@@ -1009,13 +1029,16 @@ enum SPEC_TYPES_OFFSETS {
#define DEP_TRUE (((ds_t) 1) << (BE_IN_CONTROL_BITS_OFFSET + BITS_PER_DEP_WEAK)) #define DEP_TRUE (((ds_t) 1) << (BE_IN_CONTROL_BITS_OFFSET + BITS_PER_DEP_WEAK))
#define DEP_OUTPUT (DEP_TRUE << 1) #define DEP_OUTPUT (DEP_TRUE << 1)
#define DEP_ANTI (DEP_OUTPUT << 1) #define DEP_ANTI (DEP_OUTPUT << 1)
#define DEP_CONTROL (DEP_ANTI << 1)
#define DEP_TYPES (DEP_TRUE | DEP_OUTPUT | DEP_ANTI) #define DEP_TYPES (DEP_TRUE | DEP_OUTPUT | DEP_ANTI | DEP_CONTROL)
/* Instruction has non-speculative dependence. This bit represents the /* Instruction has non-speculative dependence. This bit represents the
property of an instruction - not the one of a dependence. property of an instruction - not the one of a dependence.
Therefore, it can appear only in TODO_SPEC field of an instruction. */ Therefore, it can appear only in TODO_SPEC field of an instruction. */
#define HARD_DEP (DEP_ANTI << 1) #define HARD_DEP (DEP_CONTROL << 1)
#define DEP_CANCELLED (HARD_DEP << 1)
/* This represents the results of calling sched-deps.c functions, /* This represents the results of calling sched-deps.c functions,
which modify dependencies. */ which modify dependencies. */
...@@ -1041,7 +1064,8 @@ enum SCHED_FLAGS { ...@@ -1041,7 +1064,8 @@ enum SCHED_FLAGS {
Requires USE_DEPS_LIST set. */ Requires USE_DEPS_LIST set. */
DO_SPECULATION = USE_DEPS_LIST << 1, DO_SPECULATION = USE_DEPS_LIST << 1,
DO_BACKTRACKING = DO_SPECULATION << 1, DO_BACKTRACKING = DO_SPECULATION << 1,
SCHED_RGN = DO_BACKTRACKING << 1, DO_PREDICATION = DO_BACKTRACKING << 1,
SCHED_RGN = DO_PREDICATION << 1,
SCHED_EBB = SCHED_RGN << 1, SCHED_EBB = SCHED_RGN << 1,
/* Scheduler can possibly create new basic blocks. Used for assertions. */ /* Scheduler can possibly create new basic blocks. Used for assertions. */
NEW_BBS = SCHED_EBB << 1, NEW_BBS = SCHED_EBB << 1,
...@@ -1202,6 +1226,7 @@ extern struct sched_deps_info_def *sched_deps_info; ...@@ -1202,6 +1226,7 @@ extern struct sched_deps_info_def *sched_deps_info;
/* Functions in sched-deps.c. */ /* Functions in sched-deps.c. */
extern rtx sched_get_reverse_condition_uncached (const_rtx);
extern bool sched_insns_conditions_mutex_p (const_rtx, const_rtx); extern bool sched_insns_conditions_mutex_p (const_rtx, const_rtx);
extern bool sched_insn_is_legitimate_for_speculation_p (const_rtx, ds_t); extern bool sched_insn_is_legitimate_for_speculation_p (const_rtx, ds_t);
extern void add_dependence (rtx, rtx, enum reg_note); extern void add_dependence (rtx, rtx, enum reg_note);
...@@ -1337,6 +1362,7 @@ extern bool sched_no_dce; ...@@ -1337,6 +1362,7 @@ extern bool sched_no_dce;
extern void set_modulo_params (int, int, int, int); extern void set_modulo_params (int, int, int, int);
extern void record_delay_slot_pair (rtx, rtx, int, int); extern void record_delay_slot_pair (rtx, rtx, int, int);
extern rtx real_insn_for_shadow (rtx);
extern void discard_delay_pairs_above (int); extern void discard_delay_pairs_above (int);
extern void free_delay_pairs (void); extern void free_delay_pairs (void);
extern void add_delay_dependencies (rtx); extern void add_delay_dependencies (rtx);
...@@ -1527,3 +1553,4 @@ extern void print_pattern (char *, const_rtx, int); ...@@ -1527,3 +1553,4 @@ extern void print_pattern (char *, const_rtx, int);
extern void print_value (char *, const_rtx, int); extern void print_value (char *, const_rtx, int);
#endif /* GCC_SCHED_INT_H */ #endif /* GCC_SCHED_INT_H */
...@@ -234,7 +234,6 @@ static void add_branch_dependences (rtx, rtx); ...@@ -234,7 +234,6 @@ static void add_branch_dependences (rtx, rtx);
static void compute_block_dependences (int); static void compute_block_dependences (int);
static void schedule_region (int); static void schedule_region (int);
static rtx concat_INSN_LIST (rtx, rtx);
static void concat_insn_mem_list (rtx, rtx, rtx *, rtx *); static void concat_insn_mem_list (rtx, rtx, rtx *, rtx *);
static void propagate_deps (int, struct deps_desc *); static void propagate_deps (int, struct deps_desc *);
static void free_pending_lists (void); static void free_pending_lists (void);
...@@ -2552,20 +2551,6 @@ add_branch_dependences (rtx head, rtx tail) ...@@ -2552,20 +2551,6 @@ add_branch_dependences (rtx head, rtx tail)
static struct deps_desc *bb_deps; static struct deps_desc *bb_deps;
/* Duplicate the INSN_LIST elements of COPY and prepend them to OLD. */
static rtx
concat_INSN_LIST (rtx copy, rtx old)
{
rtx new_rtx = old;
for (; copy ; copy = XEXP (copy, 1))
{
new_rtx = alloc_INSN_LIST (XEXP (copy, 0), new_rtx);
PUT_REG_NOTE_KIND (new_rtx, REG_NOTE_KIND (copy));
}
return new_rtx;
}
static void static void
concat_insn_mem_list (rtx copy_insns, rtx copy_mems, rtx *old_insns_p, concat_insn_mem_list (rtx copy_insns, rtx copy_mems, rtx *old_insns_p,
rtx *old_mems_p) rtx *old_mems_p)
...@@ -2619,6 +2604,9 @@ deps_join (struct deps_desc *succ_deps, struct deps_desc *pred_deps) ...@@ -2619,6 +2604,9 @@ deps_join (struct deps_desc *succ_deps, struct deps_desc *pred_deps)
&succ_deps->pending_write_insns, &succ_deps->pending_write_insns,
&succ_deps->pending_write_mems); &succ_deps->pending_write_mems);
succ_deps->pending_jump_insns
= concat_INSN_LIST (pred_deps->pending_jump_insns,
succ_deps->pending_jump_insns);
succ_deps->last_pending_memory_flush succ_deps->last_pending_memory_flush
= concat_INSN_LIST (pred_deps->last_pending_memory_flush, = concat_INSN_LIST (pred_deps->last_pending_memory_flush,
succ_deps->last_pending_memory_flush); succ_deps->last_pending_memory_flush);
...@@ -2670,12 +2658,14 @@ propagate_deps (int bb, struct deps_desc *pred_deps) ...@@ -2670,12 +2658,14 @@ propagate_deps (int bb, struct deps_desc *pred_deps)
bb_deps[bb].pending_read_mems = pred_deps->pending_read_mems; bb_deps[bb].pending_read_mems = pred_deps->pending_read_mems;
bb_deps[bb].pending_write_insns = pred_deps->pending_write_insns; bb_deps[bb].pending_write_insns = pred_deps->pending_write_insns;
bb_deps[bb].pending_write_mems = pred_deps->pending_write_mems; bb_deps[bb].pending_write_mems = pred_deps->pending_write_mems;
bb_deps[bb].pending_jump_insns = pred_deps->pending_jump_insns;
/* Can't allow these to be freed twice. */ /* Can't allow these to be freed twice. */
pred_deps->pending_read_insns = 0; pred_deps->pending_read_insns = 0;
pred_deps->pending_read_mems = 0; pred_deps->pending_read_mems = 0;
pred_deps->pending_write_insns = 0; pred_deps->pending_write_insns = 0;
pred_deps->pending_write_mems = 0; pred_deps->pending_write_mems = 0;
pred_deps->pending_jump_insns = 0;
} }
/* Compute dependences inside bb. In a multiple blocks region: /* Compute dependences inside bb. In a multiple blocks region:
...@@ -2754,6 +2744,7 @@ free_pending_lists (void) ...@@ -2754,6 +2744,7 @@ free_pending_lists (void)
free_INSN_LIST_list (&bb_deps[bb].pending_write_insns); free_INSN_LIST_list (&bb_deps[bb].pending_write_insns);
free_EXPR_LIST_list (&bb_deps[bb].pending_read_mems); free_EXPR_LIST_list (&bb_deps[bb].pending_read_mems);
free_EXPR_LIST_list (&bb_deps[bb].pending_write_mems); free_EXPR_LIST_list (&bb_deps[bb].pending_write_mems);
free_INSN_LIST_list (&bb_deps[bb].pending_jump_insns);
} }
} }
......
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