Commit 39ba1719 by Richard Sandiford Committed by Richard Sandiford

mips-protos.h (mips_linked_macc_p): Declare.

	* config/mips/mips-protos.h (mips_linked_macc_p): Declare.
	* config/mips/mips.h (TUNE_MACC_CHAINS): New macro.
	* config/mips/mips.c (TARGET_SCHED_REORDER): Define.
	(TARGET_SCHED_VARIABLE_ISSUE): Define.
	(mips_adjust_cost): Move later in file, next to other sched hooks.
	(mips_macc_chains_last_hilo): New variable.
	(mips_linked_madd_p, mips_macc_chains_record, mips_macc_chains_reorder)
	(mips_promote_ready, mips_sched_reorder, mips_variable_issue): New.
	* config/mips/mips.md (may_clobber_hilo): New attribute.

From-SVN: r81157
parent c1fcbbc3
2004-04-25 Richard Sandiford <rsandifo@redhat.com>
* config/mips/mips-protos.h (mips_linked_macc_p): Declare.
* config/mips/mips.h (TUNE_MACC_CHAINS): New macro.
* config/mips/mips.c (TARGET_SCHED_REORDER): Define.
(TARGET_SCHED_VARIABLE_ISSUE): Define.
(mips_adjust_cost): Move later in file, next to other sched hooks.
(mips_macc_chains_last_hilo): New variable.
(mips_linked_madd_p, mips_macc_chains_record, mips_macc_chains_reorder)
(mips_promote_ready, mips_sched_reorder, mips_variable_issue): New.
* config/mips/mips.md (may_clobber_hilo): New attribute.
2004-04-24 Roger Sayle <roger@eyesopen.com>
Bruce Korb <bkorb@gnu.org>
......
......@@ -201,6 +201,7 @@ extern const char *mips_output_conditional_branch (rtx, rtx *, int, int,
int, int);
extern const char *mips_output_division (const char *, rtx *);
extern unsigned int mips_hard_regno_nregs (int, enum machine_mode);
extern bool mips_linked_madd_p (rtx, rtx);
extern const char *mips_emit_prefetch (rtx *);
extern void irix_asm_output_align (FILE *, unsigned);
......
......@@ -226,9 +226,14 @@ static bool mips_strict_matching_cpu_name_p (const char *, const char *);
static bool mips_matching_cpu_name_p (const char *, const char *);
static const struct mips_cpu_info *mips_parse_cpu (const char *, const char *);
static const struct mips_cpu_info *mips_cpu_info_from_isa (int);
static int mips_adjust_cost (rtx, rtx, rtx, int);
static bool mips_return_in_memory (tree, tree);
static bool mips_strict_argument_naming (CUMULATIVE_ARGS *);
static void mips_macc_chains_record (rtx);
static void mips_macc_chains_reorder (rtx *, int);
static void mips_promote_ready (rtx *, int, int);
static int mips_sched_reorder (FILE *, int, rtx *, int *, int);
static int mips_variable_issue (FILE *, int, rtx, int);
static int mips_adjust_cost (rtx, rtx, rtx, int);
static int mips_issue_rate (void);
static int mips_use_dfa_pipeline_interface (void);
static int mips_multipass_dfa_lookahead (void);
......@@ -670,6 +675,10 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
#undef TARGET_ASM_SELECT_RTX_SECTION
#define TARGET_ASM_SELECT_RTX_SECTION mips_select_rtx_section
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER mips_sched_reorder
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE mips_variable_issue
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST mips_adjust_cost
#undef TARGET_SCHED_ISSUE_RATE
......@@ -9152,20 +9161,6 @@ mips_cpu_info_from_isa (int isa)
return 0;
}
/* Adjust the cost of INSN based on the relationship between INSN that
is dependent on DEP_INSN through the dependence LINK. The default
is to make no adjustment to COST.
On the MIPS, ignore the cost of anti- and output-dependencies. */
static int
mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
rtx dep ATTRIBUTE_UNUSED, int cost)
{
if (REG_NOTE_KIND (link) != 0)
return 0; /* Anti or output dependence. */
return cost;
}
/* Implement HARD_REGNO_NREGS. The size of FP registers are controlled
by UNITS_PER_FPREG. All other registers are word sized. */
......@@ -9200,6 +9195,140 @@ mips_strict_argument_naming (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED)
return !TARGET_OLDABI;
}
/* Return true if INSN is a multiply-add or multiply-subtract
instruction and PREV assigns to the accumulator operand. */
bool
mips_linked_madd_p (rtx prev, rtx insn)
{
rtx x;
x = single_set (insn);
if (x == 0)
return false;
x = SET_SRC (x);
if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == MULT
&& reg_set_p (XEXP (x, 1), prev))
return true;
if (GET_CODE (x) == MINUS
&& GET_CODE (XEXP (x, 1)) == MULT
&& reg_set_p (XEXP (x, 0), prev))
return true;
return false;
}
/* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
that may clobber hi or lo. */
static rtx mips_macc_chains_last_hilo;
/* A TUNE_MACC_CHAINS helper function. Record that instruction INSN has
been scheduled, updating mips_macc_chains_last_hilo appropriately. */
static void
mips_macc_chains_record (rtx insn)
{
if (get_attr_may_clobber_hilo (insn))
mips_macc_chains_last_hilo = insn;
}
/* A TUNE_MACC_CHAINS helper function. Search ready queue READY, which
has NREADY elements, looking for a multiply-add or multiply-subtract
instruction that is cumulative with mips_macc_chains_last_hilo.
If there is one, promote it ahead of anything else that might
clobber hi or lo. */
static void
mips_macc_chains_reorder (rtx *ready, int nready)
{
int i, j;
if (mips_macc_chains_last_hilo != 0)
for (i = nready - 1; i >= 0; i--)
if (mips_linked_madd_p (mips_macc_chains_last_hilo, ready[i]))
{
for (j = nready - 1; j > i; j--)
if (recog_memoized (ready[j]) >= 0
&& get_attr_may_clobber_hilo (ready[j]))
{
mips_promote_ready (ready, i, j);
break;
}
break;
}
}
/* Remove the instruction at index LOWER from ready queue READY and
reinsert it in front of the instruction at index HIGHER. LOWER must
be <= HIGHER. */
static void
mips_promote_ready (rtx *ready, int lower, int higher)
{
rtx new_head;
int i;
new_head = ready[lower];
for (i = lower; i < higher; i++)
ready[i] = ready[i + 1];
ready[i] = new_head;
}
/* Implement TARGET_SCHED_REORDER. */
static int
mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
rtx *ready, int *nreadyp, int cycle)
{
if (!reload_completed && TUNE_MACC_CHAINS)
{
if (cycle == 0)
mips_macc_chains_last_hilo = 0;
if (*nreadyp > 0)
mips_macc_chains_reorder (ready, *nreadyp);
}
return mips_issue_rate ();
}
/* Implement TARGET_SCHED_VARIABLE_ISSUE. */
static int
mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
rtx insn, int more)
{
switch (GET_CODE (PATTERN (insn)))
{
case USE:
case CLOBBER:
/* Don't count USEs and CLOBBERs against the issue rate. */
break;
default:
more--;
if (!reload_completed && TUNE_MACC_CHAINS)
mips_macc_chains_record (insn);
break;
}
return more;
}
/* Implement TARGET_SCHED_ADJUST_COST. We assume that anti and output
dependencies have no cost. */
static int
mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
rtx dep ATTRIBUTE_UNUSED, int cost)
{
if (REG_NOTE_KIND (link) != 0)
return 0;
return cost;
}
/* Return the number of instructions that can be issued per cycle. */
static int
......
......@@ -340,6 +340,39 @@ extern const struct mips_cpu_info *mips_tune_info;
#define TUNE_MIPS9000 (mips_tune == PROCESSOR_R9000)
#define TUNE_SB1 (mips_tune == PROCESSOR_SB1)
/* True if the pre-reload scheduler should try to create chains of
multiply-add or multiply-subtract instructions. For example,
suppose we have:
t1 = a * b
t2 = t1 + c * d
t3 = c * d
t4 = t3 - c * d
t1 will have a higher priority and t2 and t3 will have a higher
priority than t4. However, before reload, there is no dependence
between t1 and t3, and they can often have similar priorities.
The scheduler will then tend to prefer:
t1 = a * b
t3 = e * f
t2 = t1 + c * d
t4 = t3 - g * h
which stops us from making full use of macc/madd-style instructions.
This sort of situation occurs frequently in Fourier transforms and
in unrolled loops.
To counter this, the TUNE_MACC_CHAINS code will reorder the ready
queue so that chained multiply-add and multiply-subtract instructions
appear ahead of any other instruction that is likely to clobber lo.
In the example above, if t2 and t3 become ready at the same time,
the code ensures that t2 is scheduled first.
Multiply-accumulate instructions are a bigger win for some targets
than others, so this macro is defined on an opt-in basis. */
#define TUNE_MACC_CHAINS TUNE_MIPS5500
#define TARGET_OLDABI (mips_abi == ABI_32 || mips_abi == ABI_O64)
#define TARGET_NEWABI (mips_abi == ABI_N32 || mips_abi == ABI_64)
......
......@@ -277,6 +277,13 @@
(const_string "yes")
(const_string "no"))))
;; True if an instruction might assign to hi or lo when reloaded.
;; This is used by the TUNE_MACC_CHAINS code.
(define_attr "may_clobber_hilo" "no,yes"
(if_then_else (eq_attr "type" "imul,imadd,idiv,mthilo")
(const_string "yes")
(const_string "no")))
;; Describe a user's asm statement.
(define_asm_attributes
[(set_attr "type" "multi")])
......
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