target-def.h (TARGET_SCHED_INIT_GLOBAL, [...]): New macros.
2003-02-24 Sanjiv Kumar Gupta <sanjivg@noida.hcltech.com> * target-def.h (TARGET_SCHED_INIT_GLOBAL, TARGET_SCHED_FINISH_GLOBAL): New macros. * target.h (md_init_global, md_finish_global): Function declarations corresponding to new target macros. * haifa-sched.c (sched_init, sched_finish): Allow target to call the new schedular hooks. * flow.c (recompute_reg_usage): Add PROP_DEATH_NOTES flag in call to update_life_info. * config/sh/sh.h (OVERRIDE_OPTIONS): Re-enable flag_schedule_insns for SH4. * config/sh/sh.c (sh_md_init_global, sh_md_finish_global, find_set_regmode_weight, find_insn_regmode_weight, find_regmode_weight), sh_md_init, sh_dfa_new_cycle, sh_variable_issue, high_pressure, ready_reorder, rank_for_reorder, swap_reorder, sh_reorder, sh_reorder2): New functions used to throttle the insn movement in first scheduling pass for SH. * gcc/doc/tm.texi: Document TARGET_SCHED_INIT_GLOBAL and TARGET_SCHED_FINISH_GLOBAL. From-SVN: r78374
This commit is contained in:
parent
34208acf14
commit
58565a33ed
|
@ -1,3 +1,31 @@
|
|||
2003-02-24 Sanjiv Kumar Gupta <sanjivg@noida.hcltech.com>
|
||||
|
||||
* target-def.h (TARGET_SCHED_INIT_GLOBAL,
|
||||
TARGET_SCHED_FINISH_GLOBAL): New macros.
|
||||
|
||||
* target.h (md_init_global, md_finish_global): Function
|
||||
declarations corresponding to new target macros.
|
||||
|
||||
* haifa-sched.c (sched_init, sched_finish): Allow target to
|
||||
call the new schedular hooks.
|
||||
|
||||
* flow.c (recompute_reg_usage): Add PROP_DEATH_NOTES flag in
|
||||
call to update_life_info.
|
||||
|
||||
* config/sh/sh.h (OVERRIDE_OPTIONS): Re-enable
|
||||
flag_schedule_insns for SH4.
|
||||
|
||||
* config/sh/sh.c (sh_md_init_global, sh_md_finish_global,
|
||||
find_set_regmode_weight, find_insn_regmode_weight,
|
||||
find_regmode_weight), sh_md_init, sh_dfa_new_cycle,
|
||||
sh_variable_issue, high_pressure, ready_reorder,
|
||||
rank_for_reorder, swap_reorder, sh_reorder, sh_reorder2): New
|
||||
functions used to throttle the insn movement in first
|
||||
scheduling pass for SH.
|
||||
|
||||
* gcc/doc/tm.texi: Document TARGET_SCHED_INIT_GLOBAL and
|
||||
TARGET_SCHED_FINISH_GLOBAL.
|
||||
|
||||
2004-02-24 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
Implement FR-V FDPIC ABI support for frv-uclinux and frv-linux.
|
||||
|
|
|
@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "ra.h"
|
||||
#include "cfglayout.h"
|
||||
#include "intl.h"
|
||||
#include "sched-int.h"
|
||||
#include "ggc.h"
|
||||
|
||||
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
|
||||
|
@ -101,6 +102,21 @@ int current_function_anonymous_args;
|
|||
/* Which cpu are we scheduling for. */
|
||||
enum processor_type sh_cpu;
|
||||
|
||||
/* Definitions used in ready queue reordering for first scheduling pass. */
|
||||
|
||||
/* Reg weights arrays for modes SFmode and SImode, indexed by insn LUID. */
|
||||
static short *regmode_weight[2];
|
||||
|
||||
/* Total SFmode and SImode weights of scheduled insns. */
|
||||
static int curr_regmode_pressure[2];
|
||||
|
||||
/* If true, skip cycles for Q -> R movement. */
|
||||
static int skip_cycles = 0;
|
||||
|
||||
/* Cached value of can_issue_more. This is cached in sh_variable_issue hook
|
||||
and returned from sh_reorder2. */
|
||||
static short cached_can_issue_more;
|
||||
|
||||
/* Saved operands from the last compare to use when we generate an scc
|
||||
or bcc insn. */
|
||||
|
||||
|
@ -211,6 +227,21 @@ static void sh_insert_attributes (tree, tree *);
|
|||
static int sh_adjust_cost (rtx, rtx, rtx, int);
|
||||
static int sh_use_dfa_interface (void);
|
||||
static int sh_issue_rate (void);
|
||||
static int sh_dfa_new_cycle (FILE *, int, rtx, int, int, int *sort_p);
|
||||
static short find_set_regmode_weight (rtx, enum machine_mode);
|
||||
static short find_insn_regmode_weight (rtx, enum machine_mode);
|
||||
static void find_regmode_weight (int, enum machine_mode);
|
||||
static void sh_md_init_global (FILE *, int, int);
|
||||
static void sh_md_finish_global (FILE *, int);
|
||||
static int rank_for_reorder (const void *, const void *);
|
||||
static void swap_reorder (rtx *, int);
|
||||
static void ready_reorder (rtx *, int);
|
||||
static short high_pressure (enum machine_mode);
|
||||
static int sh_reorder (FILE *, int, rtx *, int *, int);
|
||||
static int sh_reorder2 (FILE *, int, rtx *, int *, int);
|
||||
static void sh_md_init (FILE *, int, int);
|
||||
static int sh_variable_issue (FILE *, int, rtx, int);
|
||||
|
||||
static bool sh_function_ok_for_sibcall (tree, tree);
|
||||
|
||||
static bool sh_cannot_modify_jumps_p (void);
|
||||
|
@ -293,6 +324,62 @@ static tree sh_build_builtin_va_list (void);
|
|||
#undef TARGET_SCHED_ISSUE_RATE
|
||||
#define TARGET_SCHED_ISSUE_RATE sh_issue_rate
|
||||
|
||||
/* The next 5 hooks have been implemented for reenabling sched1. With the
|
||||
help of these macros we are limiting the movement of insns in sched1 to
|
||||
reduce the register pressure. The overall idea is to keep count of SImode
|
||||
and SFmode regs required by already scheduled insns. When these counts
|
||||
cross some threshold values; give priority to insns that free registers.
|
||||
The insn that frees registers is most likely to be the insn with lowest
|
||||
LUID (original insn order); but such an insn might be there in the stalled
|
||||
queue (Q) instead of the ready queue (R). To solve this, we skip cycles
|
||||
upto a max of 8 cycles so that such insns may move from Q -> R.
|
||||
|
||||
The description of the hooks are as below:
|
||||
|
||||
TARGET_SCHED_INIT_GLOBAL: Added a new target hook in the generic
|
||||
scheduler; it is called inside the sched_init function just after
|
||||
find_insn_reg_weights function call. It is used to calculate the SImode
|
||||
and SFmode weights of insns of basic blocks; much similiar to what
|
||||
find_insn_reg_weights does.
|
||||
TARGET_SCHED_FINISH_GLOBAL: Corresponding cleanup hook.
|
||||
|
||||
TARGET_SCHED_DFA_NEW_CYCLE: Skip cycles if high register pressure is
|
||||
indicated by TARGET_SCHED_REORDER2; doing this may move insns from
|
||||
(Q)->(R).
|
||||
|
||||
TARGET_SCHED_REORDER: If the register pressure for SImode or SFmode is
|
||||
high; reorder the ready queue so that the insn with lowest LUID will be
|
||||
issued next.
|
||||
|
||||
TARGET_SCHED_REORDER2: If the register pressure is high, indicate to
|
||||
TARGET_SCHED_DFA_NEW_CYCLE to skip cycles.
|
||||
|
||||
TARGET_SCHED_VARIABLE_ISSUE: Cache the value of can_issue_more so that it
|
||||
can be returned from TARGET_SCHED_REORDER2.
|
||||
|
||||
TARGET_SCHED_INIT: Reset the register pressure counting variables. */
|
||||
|
||||
#undef TARGET_SCHED_DFA_NEW_CYCLE
|
||||
#define TARGET_SCHED_DFA_NEW_CYCLE sh_dfa_new_cycle
|
||||
|
||||
#undef TARGET_SCHED_INIT_GLOBAL
|
||||
#define TARGET_SCHED_INIT_GLOBAL sh_md_init_global
|
||||
|
||||
#undef TARGET_SCHED_FINISH_GLOBAL
|
||||
#define TARGET_SCHED_FINISH_GLOBAL sh_md_finish_global
|
||||
|
||||
#undef TARGET_SCHED_VARIABLE_ISSUE
|
||||
#define TARGET_SCHED_VARIABLE_ISSUE sh_variable_issue
|
||||
|
||||
#undef TARGET_SCHED_REORDER
|
||||
#define TARGET_SCHED_REORDER sh_reorder
|
||||
|
||||
#undef TARGET_SCHED_REORDER2
|
||||
#define TARGET_SCHED_REORDER2 sh_reorder2
|
||||
|
||||
#undef TARGET_SCHED_INIT
|
||||
#define TARGET_SCHED_INIT sh_md_init
|
||||
|
||||
#undef TARGET_CANNOT_MODIFY_JUMPS_P
|
||||
#define TARGET_CANNOT_MODIFY_JUMPS_P sh_cannot_modify_jumps_p
|
||||
#undef TARGET_BRANCH_TARGET_REGISTER_CLASS
|
||||
|
@ -354,6 +441,12 @@ static tree sh_build_builtin_va_list (void);
|
|||
#undef TARGET_PCH_VALID_P
|
||||
#define TARGET_PCH_VALID_P sh_pch_valid_p
|
||||
|
||||
/* Return regmode weight for insn. */
|
||||
#define INSN_REGMODE_WEIGHT(INSN, MODE) regmode_weight[((MODE) == SImode) ? 0 : 1][INSN_UID (INSN)]
|
||||
|
||||
/* Return current register pressure for regmode. */
|
||||
#define CURR_REGMODE_PRESSURE(MODE) curr_regmode_pressure[((MODE) == SImode) ? 0 : 1]
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Print the operand address in x to the stream. */
|
||||
|
@ -8264,6 +8357,323 @@ sh_issue_rate(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Functions for ready queue reordering for sched1. */
|
||||
|
||||
/* Get weight for mode for a set x. */
|
||||
static short
|
||||
find_set_regmode_weight (x, mode)
|
||||
rtx x;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
if (GET_CODE (x) == CLOBBER && register_operand (SET_DEST (x), mode))
|
||||
return 1;
|
||||
if (GET_CODE (x) == SET && register_operand (SET_DEST (x), mode))
|
||||
{
|
||||
if (GET_CODE (SET_DEST (x)) == REG)
|
||||
{
|
||||
if (!reg_mentioned_p (SET_DEST (x), SET_SRC (x)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get regmode weight for insn. */
|
||||
static short
|
||||
find_insn_regmode_weight (insn, mode)
|
||||
rtx insn;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
short reg_weight = 0;
|
||||
rtx x;
|
||||
|
||||
/* Increment weight for each register born here. */
|
||||
x = PATTERN (insn);
|
||||
reg_weight += find_set_regmode_weight (x, mode);
|
||||
if (GET_CODE (x) == PARALLEL)
|
||||
{
|
||||
int j;
|
||||
for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
|
||||
{
|
||||
x = XVECEXP (PATTERN (insn), 0, j);
|
||||
reg_weight += find_set_regmode_weight (x, mode);
|
||||
}
|
||||
}
|
||||
/* Decrement weight for each register that dies here. */
|
||||
for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
|
||||
{
|
||||
if (REG_NOTE_KIND (x) == REG_DEAD || REG_NOTE_KIND (x) == REG_UNUSED)
|
||||
{
|
||||
rtx note = XEXP (x, 0);
|
||||
if (GET_CODE (note) == REG && GET_MODE (note) == mode)
|
||||
reg_weight--;
|
||||
}
|
||||
}
|
||||
return reg_weight;
|
||||
}
|
||||
|
||||
/* Calculate regmode weights for all insns of a basic block. */
|
||||
static void
|
||||
find_regmode_weight (b, mode)
|
||||
int b;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
rtx insn, next_tail, head, tail;
|
||||
|
||||
get_block_head_tail (b, &head, &tail);
|
||||
next_tail = NEXT_INSN (tail);
|
||||
|
||||
for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
|
||||
{
|
||||
/* Handle register life information. */
|
||||
if (!INSN_P (insn))
|
||||
continue;
|
||||
|
||||
if (mode == SFmode)
|
||||
INSN_REGMODE_WEIGHT (insn, mode) =
|
||||
find_insn_regmode_weight (insn, mode) + 2 * find_insn_regmode_weight (insn, DFmode);
|
||||
else if (mode == SImode)
|
||||
INSN_REGMODE_WEIGHT (insn, mode) =
|
||||
find_insn_regmode_weight (insn, mode) + 2 * find_insn_regmode_weight (insn, DImode);
|
||||
}
|
||||
}
|
||||
|
||||
/* Comparison function for ready queue sorting. */
|
||||
static int
|
||||
rank_for_reorder (x, y)
|
||||
const void *x;
|
||||
const void *y;
|
||||
{
|
||||
rtx tmp = *(const rtx *) y;
|
||||
rtx tmp2 = *(const rtx *) x;
|
||||
|
||||
/* The insn in a schedule group should be issued the first. */
|
||||
if (SCHED_GROUP_P (tmp) != SCHED_GROUP_P (tmp2))
|
||||
return SCHED_GROUP_P (tmp2) ? 1 : -1;
|
||||
|
||||
/* If insns are equally good, sort by INSN_LUID (original insn order), This
|
||||
minimizes instruction movement, thus minimizing sched's effect on
|
||||
register pressure. */
|
||||
return INSN_LUID (tmp) - INSN_LUID (tmp2);
|
||||
}
|
||||
|
||||
/* Resort the array A in which only element at index N may be out of order. */
|
||||
static void
|
||||
swap_reorder (a, n)
|
||||
rtx *a;
|
||||
int n;
|
||||
{
|
||||
rtx insn = a[n - 1];
|
||||
int i = n - 2;
|
||||
|
||||
while (i >= 0 && rank_for_reorder (a + i, &insn) >= 0)
|
||||
{
|
||||
a[i + 1] = a[i];
|
||||
i -= 1;
|
||||
}
|
||||
a[i + 1] = insn;
|
||||
}
|
||||
|
||||
#define SCHED_REORDER(READY, N_READY) \
|
||||
do { if ((N_READY) == 2) \
|
||||
swap_reorder (READY, N_READY); \
|
||||
else if ((N_READY) > 2) \
|
||||
qsort (READY, N_READY, sizeof (rtx), rank_for_reorder); } \
|
||||
while (0)
|
||||
|
||||
/* Sort the ready list READY by ascending priority, using the SCHED_REORDER
|
||||
macro. */
|
||||
static void
|
||||
ready_reorder (ready, nready)
|
||||
rtx *ready;
|
||||
int nready;
|
||||
{
|
||||
SCHED_REORDER (ready, nready);
|
||||
}
|
||||
|
||||
/* Calculate regmode weights for all insns of all basic block. */
|
||||
static void
|
||||
sh_md_init_global (dump, verbose, old_max_uid)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int verbose ATTRIBUTE_UNUSED;
|
||||
int old_max_uid;
|
||||
{
|
||||
basic_block b;
|
||||
|
||||
regmode_weight[0] = (short *) xcalloc (old_max_uid, sizeof (short));
|
||||
regmode_weight[1] = (short *) xcalloc (old_max_uid, sizeof (short));
|
||||
|
||||
FOR_EACH_BB_REVERSE (b)
|
||||
{
|
||||
find_regmode_weight (b->index, SImode);
|
||||
find_regmode_weight (b->index, SFmode);
|
||||
}
|
||||
|
||||
CURR_REGMODE_PRESSURE (SImode) = 0;
|
||||
CURR_REGMODE_PRESSURE (SFmode) = 0;
|
||||
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
static void
|
||||
sh_md_finish_global (dump, verbose)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int verbose ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (regmode_weight[0])
|
||||
{
|
||||
free (regmode_weight[0]);
|
||||
regmode_weight[0] = NULL;
|
||||
}
|
||||
if (regmode_weight[1])
|
||||
{
|
||||
free (regmode_weight[1]);
|
||||
regmode_weight[1] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cache the can_issue_more so that we can return it from reorder2. Also,
|
||||
keep count of register pressures on SImode and SFmode. */
|
||||
static int
|
||||
sh_variable_issue (dump, sched_verbose, insn, can_issue_more)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
rtx insn;
|
||||
int can_issue_more;
|
||||
{
|
||||
if (GET_CODE (PATTERN (insn)) != USE
|
||||
&& GET_CODE (PATTERN (insn)) != CLOBBER)
|
||||
cached_can_issue_more = can_issue_more - 1;
|
||||
else
|
||||
cached_can_issue_more = can_issue_more;
|
||||
|
||||
if (reload_completed)
|
||||
return cached_can_issue_more;
|
||||
|
||||
CURR_REGMODE_PRESSURE (SImode) += INSN_REGMODE_WEIGHT (insn, SImode);
|
||||
CURR_REGMODE_PRESSURE (SFmode) += INSN_REGMODE_WEIGHT (insn, SFmode);
|
||||
|
||||
return cached_can_issue_more;
|
||||
}
|
||||
|
||||
static void
|
||||
sh_md_init (dump, verbose, veclen)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int verbose ATTRIBUTE_UNUSED;
|
||||
int veclen ATTRIBUTE_UNUSED;
|
||||
{
|
||||
CURR_REGMODE_PRESSURE (SImode) = 0;
|
||||
CURR_REGMODE_PRESSURE (SFmode) = 0;
|
||||
}
|
||||
|
||||
/* Some magic numbers. */
|
||||
/* Pressure on register r0 can lead to spill failures. so avoid sched1 for
|
||||
functions that already have high pressure on r0. */
|
||||
#define R0_MAX_LIFE_REGIONS 2
|
||||
#define R0_MAX_LIVE_LENGTH 12
|
||||
/* Register Pressure threshols for SImode and SFmode registers. */
|
||||
#define SIMODE_MAX_WEIGHT 5
|
||||
#define SFMODE_MAX_WEIGHT 10
|
||||
|
||||
/* Return true if the pressure is high for MODE. */
|
||||
static short
|
||||
high_pressure (mode)
|
||||
enum machine_mode mode;
|
||||
{
|
||||
/* Pressure on register r0 can lead to spill failures. so avoid sched1 for
|
||||
functions that already have high pressure on r0. */
|
||||
if ((REG_N_SETS (0) - REG_N_DEATHS (0)) >= R0_MAX_LIFE_REGIONS
|
||||
&& REG_LIVE_LENGTH (0) >= R0_MAX_LIVE_LENGTH)
|
||||
return 1;
|
||||
|
||||
if (mode == SFmode)
|
||||
return (CURR_REGMODE_PRESSURE (SFmode) > SFMODE_MAX_WEIGHT);
|
||||
else
|
||||
return (CURR_REGMODE_PRESSURE (SImode) > SIMODE_MAX_WEIGHT);
|
||||
}
|
||||
|
||||
/* Reorder ready queue if register pressure is high. */
|
||||
static int
|
||||
sh_reorder (dump, sched_verbose, ready, n_readyp, clock_var)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
rtx *ready;
|
||||
int *n_readyp;
|
||||
int clock_var ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (reload_completed)
|
||||
return sh_issue_rate ();
|
||||
|
||||
if (high_pressure (SFmode) || high_pressure (SImode))
|
||||
{
|
||||
ready_reorder (ready, *n_readyp);
|
||||
}
|
||||
|
||||
return sh_issue_rate ();
|
||||
}
|
||||
|
||||
/* Skip cycles if the current register pressure is high. */
|
||||
static int
|
||||
sh_reorder2 (dump, sched_verbose, ready, n_readyp, clock_var)
|
||||
FILE *dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
rtx *ready ATTRIBUTE_UNUSED;
|
||||
int *n_readyp ATTRIBUTE_UNUSED;
|
||||
int clock_var ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (reload_completed)
|
||||
return cached_can_issue_more;
|
||||
|
||||
if (high_pressure(SFmode) || high_pressure (SImode))
|
||||
skip_cycles = 1;
|
||||
|
||||
return cached_can_issue_more;
|
||||
}
|
||||
|
||||
/* Skip cycles without sorting the ready queue. This will move insn from
|
||||
Q->R. If this is the last cycle we are skipping; allow sorting of ready
|
||||
queue by sh_reorder. */
|
||||
|
||||
/* Generally, skipping these many cycles are sufficient for all insns to move
|
||||
from Q -> R. */
|
||||
#define MAX_SKIPS 8
|
||||
|
||||
static int
|
||||
sh_dfa_new_cycle (sched_dump, sched_verbose, insn, last_clock_var,
|
||||
clock_var, sort_p)
|
||||
FILE *sched_dump ATTRIBUTE_UNUSED;
|
||||
int sched_verbose ATTRIBUTE_UNUSED;
|
||||
rtx insn ATTRIBUTE_UNUSED;
|
||||
int last_clock_var;
|
||||
int clock_var;
|
||||
int *sort_p;
|
||||
{
|
||||
if (reload_completed)
|
||||
return 0;
|
||||
|
||||
if (skip_cycles)
|
||||
{
|
||||
if ((clock_var - last_clock_var) < MAX_SKIPS)
|
||||
{
|
||||
*sort_p = 0;
|
||||
return 1;
|
||||
}
|
||||
/* If this is the last cycle we are skipping, allow reordering of R. */
|
||||
if ((clock_var - last_clock_var) == MAX_SKIPS)
|
||||
{
|
||||
*sort_p = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
skip_cycles = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SHmedia requires registers for branches, so we can't generate new
|
||||
branches past reload. */
|
||||
static bool
|
||||
|
|
|
@ -516,7 +516,11 @@ do { \
|
|||
/* Never run scheduling before reload, since that can \
|
||||
break global alloc, and generates slower code anyway due \
|
||||
to the pressure on R0. */ \
|
||||
flag_schedule_insns = 0; \
|
||||
/* Enable sched1 for SH4; ready queue will be reordered by \
|
||||
the target hooks when pressure is high. We can not do this for \
|
||||
SH3 and lower as they give spill failures for R0. */ \
|
||||
if (!TARGET_HARD_SH4) \
|
||||
flag_schedule_insns = 0; \
|
||||
} \
|
||||
\
|
||||
if (align_loops == 0) \
|
||||
|
|
|
@ -5571,6 +5571,19 @@ to. @var{verbose} is the verbose level provided by
|
|||
@option{-fsched-verbose-@var{n}}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} void TARGET_SCHED_INIT_GLOBAL (FILE *@var{file}, int @var{verbose}, int @var{old_max_uid})
|
||||
This hook is executed by the scheduler after function level initializations.
|
||||
@var{file} is either a null pointer, or a stdio stream to write any debug output to.
|
||||
@var{verbose} is the verbose level provided by @option{-fsched-verbose-@var{n}}.
|
||||
@var{old_max_uid} is the maximum insn uid when scheduling begins.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} void TARGET_SCHED_FINISH_GLOBAL (FILE *@var{file}, int @var{verbose})
|
||||
This is the cleanup hook corresponding to TARGET_SCHED_INIT_GLOBAL.
|
||||
@var{file} is either a null pointer, or a stdio stream to write any debug output to.
|
||||
@var{verbose} is the verbose level provided by @option{-fsched-verbose-@var{n}}.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} int TARGET_SCHED_USE_DFA_PIPELINE_INTERFACE (void)
|
||||
This hook is called many times during insn scheduling. If the hook
|
||||
returns nonzero, the automaton based pipeline description is used for
|
||||
|
|
|
@ -4260,7 +4260,10 @@ void
|
|||
recompute_reg_usage (rtx f ATTRIBUTE_UNUSED, int loop_step ATTRIBUTE_UNUSED)
|
||||
{
|
||||
allocate_reg_life_data ();
|
||||
update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO);
|
||||
/* distribute_notes in combiner fails to convert some of the REG_UNUSED notes
|
||||
to REG_DEAD notes. This causes CHECK_DEAD_NOTES in sched1 to abort. To
|
||||
solve this update the DEATH_NOTES here. */
|
||||
update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO | PROP_DEATH_NOTES);
|
||||
}
|
||||
|
||||
/* Optionally removes all the REG_DEAD and REG_UNUSED notes from a set of
|
||||
|
|
|
@ -2856,6 +2856,9 @@ sched_init (FILE *dump_file)
|
|||
removing death notes. */
|
||||
FOR_EACH_BB_REVERSE (b)
|
||||
find_insn_reg_weight (b->index);
|
||||
|
||||
if (targetm.sched.md_init_global)
|
||||
(*targetm.sched.md_init_global) (sched_dump, sched_verbose, old_max_uid);
|
||||
}
|
||||
|
||||
/* Free global data used during insn scheduling. */
|
||||
|
@ -2875,5 +2878,8 @@ sched_finish (void)
|
|||
end_alias_analysis ();
|
||||
if (write_symbols != NO_DEBUG)
|
||||
free (line_note_head);
|
||||
|
||||
if (targetm.sched.md_finish_global)
|
||||
(*targetm.sched.md_finish_global) (sched_dump, sched_verbose);
|
||||
}
|
||||
#endif /* INSN_SCHEDULING */
|
||||
|
|
|
@ -217,6 +217,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define TARGET_SCHED_VARIABLE_ISSUE 0
|
||||
#define TARGET_SCHED_INIT 0
|
||||
#define TARGET_SCHED_FINISH 0
|
||||
#define TARGET_SCHED_INIT_GLOBAL 0
|
||||
#define TARGET_SCHED_FINISH_GLOBAL 0
|
||||
#define TARGET_SCHED_REORDER 0
|
||||
#define TARGET_SCHED_REORDER2 0
|
||||
#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK 0
|
||||
|
@ -239,6 +241,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
TARGET_SCHED_VARIABLE_ISSUE, \
|
||||
TARGET_SCHED_INIT, \
|
||||
TARGET_SCHED_FINISH, \
|
||||
TARGET_SCHED_INIT_GLOBAL, \
|
||||
TARGET_SCHED_FINISH_GLOBAL, \
|
||||
TARGET_SCHED_REORDER, \
|
||||
TARGET_SCHED_REORDER2, \
|
||||
TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK, \
|
||||
|
|
|
@ -183,6 +183,12 @@ struct gcc_target
|
|||
/* Finalize machine-dependent scheduling code. */
|
||||
void (* md_finish) (FILE *, int);
|
||||
|
||||
/* Initialize machine-dependent function while scheduling code. */
|
||||
void (* md_init_global) (FILE *, int, int);
|
||||
|
||||
/* Finalize machine-dependent function wide scheduling code. */
|
||||
void (* md_finish_global) (FILE *, int);
|
||||
|
||||
/* Reorder insns in a machine-dependent fashion, in two different
|
||||
places. Default does nothing. */
|
||||
int (* reorder) (FILE *, int, rtx *, int *, int);
|
||||
|
|
Loading…
Reference in New Issue