Commit 26965010 by Bernd Schmidt Committed by Bernd Schmidt

haifa-sched.c: Include "hashtab.h"

	* haifa-sched.c: Include "hashtab.h"
	(sched_no_dce): New global variable.
	(INSN_EXACT_TICK, INSN_TICK_ESTIMATE, FEEDS_BACKTRACK_INSN,
	SHADOW_P): New macros.
	(last_clock_var, cycle_issued_insns): Move declarations.
	(must_backtrack): New static variable.
	(struct delay_pair): New structure.
	(delay_htab, delay_htab_i2): New static variables.
	(delay_hash_i1, delay_hash_i2, delay_i1_eq, delay_i2_eq,
	record_delay_slot_pair, pair_delay, add_delay_dependencies): New
	functions.
	(dep_cost_1): If delay pairs exist, try to look up the insns and
	use the correct pair delay if we find them.
	(rank-for_schedule): Tweak priority for insns that must be scheduled
	soon to avoid backtracking.
	(queue_insn): Detect conditions which force backtracking.
	(ready_add): Likewise.
	(struct sched_block_state): Add member shadows_only_p.
	(struct haifa_save_data): New structure.
	(backtrack_queue): New static variable.
	(mark_backtrack_feeds, copy_insn_list, save_backtrack_point,
	unschedule_insns_until, restore_last_backtrack_point,
	free_topmost_backtrack_point, free_backtrack_queue,
	estimate_insn_tick, estimate_shadow_tick): New functions.
	(prune_ready_list): New arg shadows_only_p.  All callers changed.
	If true, remove everything that isn't SHADOW_P.  Look up delay
	pairs and estimate ticks to avoid scheduling the first insn too
	early.
	(verify_shadows): New function.
	(schedule_block): Add machinery to enable backtracking.
	(sched_init): Take sched_no_dce into account when setting
	DF_LR_RUN_DCE.
	(free_delay_pairs): New function.
	(init_h_i_d): Initialize INSN_EXACT_TICK.
	* Makefile.in (haifa-sched.o): Add $(HASHTAB_H).
	* sched-deps.c (sd_unresolve_dep): New function.
	* sched-int.h (struct haifa_sched_info): New fields save_state
	and restore_state.
	(struct _haifa_insn_data): New fields exact_tick, tick_estimate,
	feeds_backtrack_insn and shadow_p.
	(DO_BACKTRACKING): New value in enum SCHED_FLAGS.
	(sched_no_dce): Declare variable.
	(record_delay_slot_pair, free_delay_pairs, add_delay_dependencies,
	sd_unresolve_dep): Declare functions.
	* modulo-sched.c (sms_sched_info): Clear the two new fields.
	* sched-rgn.c (rgn_const_sched_info): Likewise.
	* sel-sched-ir.c (sched_sel_haifa_sched_info): Likewise.
	* sched-ebb.c (save_ebb_state, restore_ebb_state): New functions.
	(ebb_sched_info): Add them for the two new fields.
	(add_deps_for_risky_insns): Call add_delay_dependencies.

From-SVN: r176255
parent 13b7a7b9
2011-07-14 Bernd Schmidt <bernds@codesourcery.com>
* haifa-sched.c: Include "hashtab.h"
(sched_no_dce): New global variable.
(INSN_EXACT_TICK, INSN_TICK_ESTIMATE, FEEDS_BACKTRACK_INSN,
SHADOW_P): New macros.
(last_clock_var, cycle_issued_insns): Move declarations.
(must_backtrack): New static variable.
(struct delay_pair): New structure.
(delay_htab, delay_htab_i2): New static variables.
(delay_hash_i1, delay_hash_i2, delay_i1_eq, delay_i2_eq,
record_delay_slot_pair, pair_delay, add_delay_dependencies): New
functions.
(dep_cost_1): If delay pairs exist, try to look up the insns and
use the correct pair delay if we find them.
(rank-for_schedule): Tweak priority for insns that must be scheduled
soon to avoid backtracking.
(queue_insn): Detect conditions which force backtracking.
(ready_add): Likewise.
(struct sched_block_state): Add member shadows_only_p.
(struct haifa_save_data): New structure.
(backtrack_queue): New static variable.
(mark_backtrack_feeds, copy_insn_list, save_backtrack_point,
unschedule_insns_until, restore_last_backtrack_point,
free_topmost_backtrack_point, free_backtrack_queue,
estimate_insn_tick, estimate_shadow_tick): New functions.
(prune_ready_list): New arg shadows_only_p. All callers changed.
If true, remove everything that isn't SHADOW_P. Look up delay
pairs and estimate ticks to avoid scheduling the first insn too
early.
(verify_shadows): New function.
(schedule_block): Add machinery to enable backtracking.
(sched_init): Take sched_no_dce into account when setting
DF_LR_RUN_DCE.
(free_delay_pairs): New function.
(init_h_i_d): Initialize INSN_EXACT_TICK.
* Makefile.in (haifa-sched.o): Add $(HASHTAB_H).
* sched-deps.c (sd_unresolve_dep): New function.
* sched-int. (struct haifa_sched_info): New fields save_state
and restore_state.
(struct _haifa_insn_data): New fields exact_tick, tick_estimate,
feeds_backtrack_insn and shadow_p.
(DO_BACKTRACKING): New value in enum SCHED_FLAGS.
(sched_no_dce): Declare variable.
(record_delay_slot_pair, free_delay_pairs, add_delay_dependencies,
sd_unresolve_dep): Declare functions.
* modulo-sched.c (sms_sched_info): Clear the two new fields.
* sched-rgn.c (rgn_const_sched_info): Likewise.
* sel-sched-ir.c (sched_sel_haifa_sched_info): Likewise.
* sched-ebb.c (save_ebb_state, restore_ebb_state): New functions.
(ebb_sched_info): Add them for the two new fields.
(add_deps_for_risky_insns): Call add_delay_dependencies.
2011-07-13 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.opt (-mpointers-to-nested-functions):
......
......@@ -3397,7 +3397,8 @@ modulo-sched.o : modulo-sched.c $(DDG_H) $(CONFIG_H) $(CONFIG_H) $(SYSTEM_H) \
haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h $(FUNCTION_H) \
$(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) $(TM_P_H) $(TARGET_H) output.h \
$(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) $(COMMON_TARGET_H)
$(PARAMS_H) $(DBGCNT_H) $(CFGLOOP_H) ira.h $(EMIT_RTL_H) $(COMMON_TARGET_H) \
$(HASHTAB_H)
sched-deps.o : sched-deps.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(FUNCTION_H) $(INSN_ATTR_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(EXCEPT_H) cselib.h \
......
......@@ -283,6 +283,7 @@ static struct haifa_sched_info sms_sched_info =
0, 0,
NULL, NULL, NULL, NULL,
NULL, NULL,
0
};
......
......@@ -1301,6 +1301,28 @@ sd_resolve_dep (sd_iterator_def sd_it)
INSN_RESOLVED_FORW_DEPS (pro));
}
/* Perform the inverse operation of sd_resolve_dep. Restore the dependence
pointed to by SD_IT to unresolved state. */
void
sd_unresolve_dep (sd_iterator_def sd_it)
{
dep_node_t node = DEP_LINK_NODE (*sd_it.linkp);
dep_t dep = DEP_NODE_DEP (node);
rtx pro = DEP_PRO (dep);
rtx con = DEP_CON (dep);
if ((current_sched_info->flags & DO_SPECULATION)
&& (DEP_STATUS (dep) & SPECULATIVE))
move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con),
INSN_SPEC_BACK_DEPS (con));
else
move_dep_link (DEP_NODE_BACK (node), INSN_RESOLVED_BACK_DEPS (con),
INSN_HARD_BACK_DEPS (con));
move_dep_link (DEP_NODE_FORW (node), INSN_RESOLVED_FORW_DEPS (pro),
INSN_FORW_DEPS (pro));
}
/* Make TO depend on all the FROM's producers.
If RESOLVED_P is true add dependencies to the resolved lists. */
void
......
......@@ -74,6 +74,25 @@ static void ebb_add_block (basic_block, basic_block);
static basic_block advance_target_bb (basic_block, rtx);
static void ebb_fix_recovery_cfg (int, int, int);
/* Allocate memory and store the state of the frontend. Return the allocated
memory. */
static void *
save_ebb_state (void)
{
int *p = XNEW (int);
*p = sched_rgn_n_insns;
return p;
}
/* Restore the state of the frontend from P_, then free it. */
static void
restore_ebb_state (void *p_)
{
int *p = (int *)p_;
sched_rgn_n_insns = *p;
free (p_);
}
/* Return nonzero if there are more insns that should be scheduled. */
static int
......@@ -295,6 +314,10 @@ static struct haifa_sched_info ebb_sched_info =
begin_schedule_ready,
begin_move_insn,
advance_target_bb,
save_ebb_state,
restore_ebb_state,
SCHED_EBB
/* We can create new blocks in begin_schedule_ready (). */
| NEW_BBS
......@@ -377,76 +400,80 @@ add_deps_for_risky_insns (rtx head, rtx tail)
basic_block last_block = NULL, bb;
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
if (control_flow_insn_p (insn))
{
bb = BLOCK_FOR_INSN (insn);
bb->aux = last_block;
last_block = bb;
last_jump = insn;
}
else if (INSN_P (insn) && last_jump != NULL_RTX)
{
classification = haifa_classify_insn (insn);
prev = last_jump;
switch (classification)
{
case PFREE_CANDIDATE:
if (flag_schedule_speculative_load)
{
bb = earliest_block_with_similiar_load (last_block, insn);
if (bb)
{
bb = (basic_block) bb->aux;
if (!bb)
break;
prev = BB_END (bb);
}
}
/* Fall through. */
case TRAP_RISKY:
case IRISKY:
case PRISKY_CANDIDATE:
/* ??? We could implement better checking PRISKY_CANDIDATEs
analogous to sched-rgn.c. */
/* We can not change the mode of the backward
dependency because REG_DEP_ANTI has the lowest
rank. */
if (! sched_insns_conditions_mutex_p (insn, prev))
{
dep_def _dep, *dep = &_dep;
init_dep (dep, prev, insn, REG_DEP_ANTI);
if (!(current_sched_info->flags & USE_DEPS_LIST))
{
enum DEPS_ADJUST_RESULT res;
res = sd_add_or_update_dep (dep, false);
/* We can't change an existing dependency with
DEP_ANTI. */
gcc_assert (res != DEP_CHANGED);
}
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);
/* Dep_status could have been changed.
No assertion here. */
}
}
break;
default:
break;
}
}
{
add_delay_dependencies (insn);
if (control_flow_insn_p (insn))
{
bb = BLOCK_FOR_INSN (insn);
bb->aux = last_block;
last_block = bb;
last_jump = insn;
}
else if (INSN_P (insn) && last_jump != NULL_RTX)
{
classification = haifa_classify_insn (insn);
prev = last_jump;
switch (classification)
{
case PFREE_CANDIDATE:
if (flag_schedule_speculative_load)
{
bb = earliest_block_with_similiar_load (last_block, insn);
if (bb)
{
bb = (basic_block) bb->aux;
if (!bb)
break;
prev = BB_END (bb);
}
}
/* Fall through. */
case TRAP_RISKY:
case IRISKY:
case PRISKY_CANDIDATE:
/* ??? We could implement better checking PRISKY_CANDIDATEs
analogous to sched-rgn.c. */
/* We can not change the mode of the backward
dependency because REG_DEP_ANTI has the lowest
rank. */
if (! sched_insns_conditions_mutex_p (insn, prev))
{
dep_def _dep, *dep = &_dep;
init_dep (dep, prev, insn, REG_DEP_ANTI);
if (!(current_sched_info->flags & USE_DEPS_LIST))
{
enum DEPS_ADJUST_RESULT res;
res = sd_add_or_update_dep (dep, false);
/* We can't change an existing dependency with
DEP_ANTI. */
gcc_assert (res != DEP_CHANGED);
}
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);
/* Dep_status could have been changed.
No assertion here. */
}
}
break;
default:
break;
}
}
}
/* Maintain the invariant that bb->aux is clear after use. */
while (last_block)
{
......
......@@ -603,6 +603,13 @@ struct haifa_sched_info
The first parameter is the current basic block in EBB. */
basic_block (*advance_target_bb) (basic_block, rtx);
/* Allocate memory, store the frontend scheduler state in it, and
return it. */
void *(*save_state) (void);
/* Restore frontend scheduler state from the argument, and free the
memory. */
void (*restore_state) (void *);
/* ??? FIXME: should use straight bitfields inside sched_info instead of
this flag field. */
unsigned int flags;
......@@ -762,10 +769,18 @@ struct _haifa_insn_data
used to note timing constraints for the insns in the pending list. */
int tick;
/* For insns that are scheduled at a fixed difference from another,
this records the tick in which they must be ready. */
int exact_tick;
/* INTER_TICK is used to adjust INSN_TICKs of instructions from the
subsequent blocks in a region. */
int inter_tick;
/* Used temporarily to estimate an INSN_TICK value for an insn given
current knowledge. */
int tick_estimate;
/* See comment on QUEUE_INDEX macro in haifa-sched.c. */
int queue_index;
......@@ -775,6 +790,14 @@ struct _haifa_insn_data
moved load insn and this one. */
unsigned int fed_by_spec_load : 1;
unsigned int is_load_insn : 1;
/* Nonzero if this insn has negative-cost forward dependencies against
an already scheduled insn. */
unsigned int feeds_backtrack_insn : 1;
/* Nonzero if this insn is a shadow of another, scheduled after a fixed
delay. We only emit shadows at the end of a cycle, with no other
real insns following them. */
unsigned int shadow_p : 1;
/* '> 0' if priority is valid,
'== 0' if priority was not yet computed,
......@@ -1017,7 +1040,8 @@ enum SCHED_FLAGS {
Results in generation of data and control speculative dependencies.
Requires USE_DEPS_LIST set. */
DO_SPECULATION = USE_DEPS_LIST << 1,
SCHED_RGN = DO_SPECULATION << 1,
DO_BACKTRACKING = DO_SPECULATION << 1,
SCHED_RGN = DO_BACKTRACKING << 1,
SCHED_EBB = SCHED_RGN << 1,
/* Scheduler can possibly create new basic blocks. Used for assertions. */
NEW_BBS = SCHED_EBB << 1,
......@@ -1304,7 +1328,11 @@ extern int *ebb_head;
extern int current_nr_blocks;
extern int current_blocks;
extern int target_bb;
extern bool sched_no_dce;
extern void record_delay_slot_pair (rtx, rtx, int);
extern void free_delay_pairs (void);
extern void add_delay_dependencies (rtx);
extern bool sched_is_disabled_for_current_region_p (void);
extern void sched_rgn_init (bool);
extern void sched_rgn_finish (void);
......@@ -1478,6 +1506,7 @@ extern dep_t sd_find_dep_between (rtx, rtx, bool);
extern void sd_add_dep (dep_t, bool);
extern enum DEPS_ADJUST_RESULT sd_add_or_update_dep (dep_t, bool);
extern void sd_resolve_dep (sd_iterator_def);
extern void sd_unresolve_dep (sd_iterator_def);
extern void sd_copy_back_deps (rtx, rtx, bool);
extern void sd_delete_dep (sd_iterator_def);
extern void sd_debug_lists (rtx, sd_list_types_def);
......
......@@ -2371,6 +2371,7 @@ static const struct haifa_sched_info rgn_const_sched_info =
begin_schedule_ready,
NULL,
advance_target_bb,
NULL, NULL,
SCHED_RGN
};
......
......@@ -5700,6 +5700,10 @@ static struct haifa_sched_info sched_sel_haifa_sched_info =
NULL, /* begin_schedule_ready */
NULL, /* begin_move_insn */
NULL, /* advance_target_bb */
NULL,
NULL,
SEL_SCHED | NEW_BBS
};
......
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