summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDorit Naishlos <dorit@il.ibm.com>2003-10-07 08:18:42 +0000
committerDorit Nuzman <dorit@gcc.gnu.org>2003-10-07 08:18:42 +0000
commit79ae11c4a302d90b678ed23fe4ccfb6a163a19fc (patch)
treef042ad15742db1c1a7071c97d5bdc6214b27d841 /gcc
parent118355a03a02364b065d54f0d2fcfba4280b1226 (diff)
downloadgcc-79ae11c4a302d90b678ed23fe4ccfb6a163a19fc.tar.gz
sched-int.h (sched_info): New field sched_max_insns_priority.
* sched-int.h (sched_info): New field sched_max_insns_priority. * sched-rgn.c (init_ready_list): Add invocations to targetm.sched.adjust_priority. (sched_max_insns_priority): Init new field. * sched-ebb.c (sched_max_insns_priority): Init new field. * haifa-sched.c (set_priorities): Set sched_info->sched_max_insns_priority. * config/rs6000/rs6000.h: (rs6000_sched_restricted_insns_priority_str): Support new flag -mprioritize-restricted-insns. (DEFAULT_RESTRICTED_INSNS_PRIORITY): Define. * config/rs6000/rs6000.c (is_dispatch_slot_restricted): New function. (rs6000_adjust_priority): Change priority of restricted insns, using above new function and new flag. * doc/invoke.texi (-mprioritize-restricted-insns): Document new option. From-SVN: r72186
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config/rs6000/rs6000.c77
-rw-r--r--gcc/config/rs6000/rs6000.h7
-rw-r--r--gcc/doc/invoke.texi9
-rw-r--r--gcc/haifa-sched.c11
-rw-r--r--gcc/sched-ebb.c2
-rw-r--r--gcc/sched-int.h3
-rw-r--r--gcc/sched-rgn.c18
8 files changed, 141 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 411503e7b0f..3298828987b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2003-10-07 Dorit Naishlos <dorit@il.ibm.com>
+
+ * sched-int.h (sched_info): New field
+ sched_max_insns_priority.
+ * sched-rgn.c (init_ready_list): Add invocations to
+ targetm.sched.adjust_priority.
+ (sched_max_insns_priority): Init new field.
+ * sched-ebb.c (sched_max_insns_priority): Init new field.
+ * haifa-sched.c (set_priorities): Set
+ sched_info->sched_max_insns_priority.
+ * config/rs6000/rs6000.h:
+ (rs6000_sched_restricted_insns_priority_str): Support new
+ flag -mprioritize-restricted-insns.
+ (DEFAULT_RESTRICTED_INSNS_PRIORITY): Define.
+ * config/rs6000/rs6000.c (is_dispatch_slot_restricted): New
+ function.
+ (rs6000_adjust_priority): Change priority of restricted
+ insns, using above new function and new flag.
+ * doc/invoke.texi (-mprioritize-restricted-insns): Document
+ new option.
+
2003-10-07 Zack Weinberg <zack@codesourcery.com>
* expr.c (cmpstr_optab, cmpmem_optab): New.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index be79acc3f68..2dd108a4137 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -51,6 +51,7 @@
#include "langhooks.h"
#include "reload.h"
#include "cfglayout.h"
+#include "sched-int.h"
#if TARGET_XCOFF
#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
#endif
@@ -80,6 +81,11 @@ struct rs6000_cpu_select rs6000_select[3] =
{ (const char *)0, "-mtune=", 1, 0 },
};
+/* Support adjust_priority scheduler hook
+ and -mprioritize-restricted-insns= option. */
+const char *rs6000_sched_restricted_insns_priority_str;
+int rs6000_sched_restricted_insns_priority;
+
/* Size of long double */
const char *rs6000_long_double_size_string;
int rs6000_long_double_type_size;
@@ -268,6 +274,7 @@ static int rs6000_use_dfa_pipeline_interface (void);
static int rs6000_variable_issue (FILE *, int, rtx, int);
static bool rs6000_rtx_costs (rtx, int, int, int *);
static int rs6000_adjust_cost (rtx, rtx, rtx, int);
+static int is_dispatch_slot_restricted (rtx);
static int rs6000_adjust_priority (rtx, int);
static int rs6000_issue_rate (void);
static int rs6000_use_sched_lookahead (void);
@@ -824,6 +831,12 @@ rs6000_override_options (const char *default_cpu)
rs6000_default_long_calls = (base[0] != 'n');
}
+ /* Handle -mprioritize-restrcted-insns option. */
+ rs6000_sched_restricted_insns_priority = DEFAULT_RESTRICTED_INSNS_PRIORITY;
+ if (rs6000_sched_restricted_insns_priority_str)
+ rs6000_sched_restricted_insns_priority =
+ atoi (rs6000_sched_restricted_insns_priority_str);
+
#ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the
alternate names now. */
@@ -13097,9 +13110,50 @@ rs6000_adjust_cost (rtx insn, rtx link, rtx dep_insn ATTRIBUTE_UNUSED,
return cost;
}
+/* The function returns a non-zero value if INSN can be scheduled only
+ as the first insn in a dispatch group ("dispatch-slot restricted").
+ In this case, the returned value indicates how many dispatch slots
+ the insn occupies (at the beginning of the group).
+ Return 0 otherwise. */
+
+static int
+is_dispatch_slot_restricted (rtx insn)
+{
+ enum attr_type type;
+
+ if (rs6000_cpu != PROCESSOR_POWER4)
+ return 0;
+
+ if (!insn
+ || insn == NULL_RTX
+ || GET_CODE (insn) == NOTE
+ || GET_CODE (PATTERN (insn)) == USE
+ || GET_CODE (PATTERN (insn)) == CLOBBER)
+ return 0;
+
+ type = get_attr_type (insn);
+
+ switch (type){
+ case TYPE_MFCR:
+ case TYPE_MFCRF:
+ case TYPE_MTCR:
+ case TYPE_DELAYED_CR:
+ case TYPE_CR_LOGICAL:
+ case TYPE_MTJMPR:
+ case TYPE_MFJMPR:
+ return 1;
+ case TYPE_IDIV:
+ case TYPE_LDIV:
+ return 2;
+ default:
+ return 0;
+ }
+}
+
+
/* A C statement (sans semicolon) to update the integer scheduling
- priority INSN_PRIORITY (INSN). Reduce the priority to execute the
- INSN earlier, increase the priority to execute INSN later. Do not
+ priority INSN_PRIORITY (INSN). Increase the priority to execute the
+ INSN earlier, reduce the priority to execute INSN later. Do not
define this macro if you do not need to adjust the scheduling
priorities of insns. */
@@ -13136,6 +13190,25 @@ rs6000_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority)
}
#endif
+ if (is_dispatch_slot_restricted (insn)
+ && reload_completed
+ && current_sched_info->sched_max_insns_priority
+ && rs6000_sched_restricted_insns_priority)
+ {
+
+ /* Prioritize insns that can be dispatched only in the first dispatch slot. */
+ if (rs6000_sched_restricted_insns_priority == 1)
+ /* Attach highest priority to insn. This means that in
+ haifa-sched.c:ready_sort(), dispatch-slot restriction considerations
+ precede 'priority' (critical path) considerations. */
+ return current_sched_info->sched_max_insns_priority;
+ else if (rs6000_sched_restricted_insns_priority == 2)
+ /* Increase priority of insn by a minimal amount. This means that in
+ haifa-sched.c:ready_sort(), only 'priority' (critical path) considerations
+ precede dispatch-slot restriction considerations. */
+ return (priority + 1);
+ }
+
return priority;
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index dd10fa9953b..beaf8d3b212 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -404,6 +404,8 @@ extern enum processor_type rs6000_cpu;
{"no-longcall", &rs6000_longcall_switch, "", 0}, \
{"align-", &rs6000_alignment_string, \
N_("Specify alignment of structure fields default/natural"), 0}, \
+ {"prioritize-restricted-insns=", &rs6000_sched_restricted_insns_priority_str, \
+ N_("Specify scheduling priority for dispatch slot restricted insns"), 0}, \
SUBTARGET_OPTIONS \
}
@@ -457,6 +459,8 @@ extern const char *rs6000_longcall_switch;
extern int rs6000_default_long_calls;
extern const char* rs6000_alignment_string;
extern int rs6000_alignment_flags;
+extern const char *rs6000_sched_restricted_insns_priority_str;
+extern int rs6000_sched_restricted_insns_priority;
/* Alignment options for fields in structures for sub-targets following
AIX-like ABI.
@@ -475,6 +479,9 @@ extern int rs6000_alignment_flags;
#define TARGET_ALIGN_NATURAL 0
#endif
+/* Define if the target has restricted dispatch slot instructions. */
+#define DEFAULT_RESTRICTED_INSNS_PRIORITY (rs6000_cpu == PROCESSOR_POWER4 ? 1 : 0)
+
/* Define TARGET_MFCRF if the target assembler supports the optional
field operand for mfcr and the target processor supports the
instruction. */
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index e97bf38f294..d6ab928ae51 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -431,6 +431,7 @@ in the following sections.
-mno-relocatable -mrelocatable-lib -mno-relocatable-lib @gol
-mtoc -mno-toc -mlittle -mlittle-endian -mbig -mbig-endian @gol
-mdynamic-no-pic @gol
+-mprioritize-restricted-insns=@var{priority} @gol
-mcall-sysv -mcall-netbsd @gol
-maix-struct-return -msvr4-struct-return @gol
-mabi=altivec -mabi=no-altivec @gol
@@ -7526,6 +7527,14 @@ relocatable, but that its external references are relocatable. The
resulting code is suitable for applications, but not shared
libraries.
+@item -mprioritize-restricted-insns=@var{priority}
+@opindex mprioritize-restricted-insns
+This option controls the priority that is assigned to
+dispatch-slot restricted instructions during the second scheduling
+pass. The argument @var{priority} takes the value @var{0/1/2} to assign
+@var{no/highest/second-highest} priority to dispatch slot restricted
+instructions.
+
@item -mcall-sysv
@opindex mcall-sysv
On System V.4 and embedded PowerPC systems compile code using calling
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 2776ec12c7f..652ad18b83b 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -2517,7 +2517,8 @@ set_priorities (rtx head, rtx tail)
{
rtx insn;
int n_insn;
-
+ int sched_max_insns_priority =
+ current_sched_info->sched_max_insns_priority;
rtx prev_head;
prev_head = PREV_INSN (head);
@@ -2526,6 +2527,7 @@ set_priorities (rtx head, rtx tail)
return 0;
n_insn = 0;
+ sched_max_insns_priority = 0;
for (insn = tail; insn != prev_head; insn = PREV_INSN (insn))
{
if (GET_CODE (insn) == NOTE)
@@ -2533,7 +2535,14 @@ set_priorities (rtx head, rtx tail)
n_insn++;
(void) priority (insn);
+
+ if (INSN_PRIORITY_KNOWN (insn))
+ sched_max_insns_priority =
+ MAX (sched_max_insns_priority, INSN_PRIORITY (insn));
}
+ sched_max_insns_priority += 1;
+ current_sched_info->sched_max_insns_priority =
+ sched_max_insns_priority;
return n_insn;
}
diff --git a/gcc/sched-ebb.c b/gcc/sched-ebb.c
index dd9ec63e7b9..06637d75593 100644
--- a/gcc/sched-ebb.c
+++ b/gcc/sched-ebb.c
@@ -204,7 +204,7 @@ static struct sched_info ebb_sched_info =
NULL, NULL,
NULL, NULL,
- 0, 1
+ 0, 1, 0
};
/* It is possible that ebb scheduling eliminated some blocks.
diff --git a/gcc/sched-int.h b/gcc/sched-int.h
index 061ebe419bd..ba056e051a4 100644
--- a/gcc/sched-int.h
+++ b/gcc/sched-int.h
@@ -167,6 +167,9 @@ struct sched_info
has completed, e.g. if we're using it to initialize state for successor
blocks in region scheduling. */
unsigned int use_cselib:1;
+
+ /* Maximum priority that has been assigned to an insn. */
+ int sched_max_insns_priority;
};
extern struct sched_info *current_sched_info;
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index f921061deae..0b89e35ee3e 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -1756,7 +1756,13 @@ init_ready_list (struct ready_list *ready)
for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
{
if (INSN_DEP_COUNT (insn) == 0)
- ready_add (ready, insn);
+ {
+ ready_add (ready, insn);
+
+ if (targetm.sched.adjust_priority)
+ INSN_PRIORITY (insn) =
+ (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
+ }
target_n_insns++;
}
@@ -1792,7 +1798,13 @@ init_ready_list (struct ready_list *ready)
&& check_live (insn, bb_src)
&& is_exception_free (insn, bb_src, target_bb))))
if (INSN_DEP_COUNT (insn) == 0)
- ready_add (ready, insn);
+ {
+ ready_add (ready, insn);
+
+ if (targetm.sched.adjust_priority)
+ INSN_PRIORITY (insn) =
+ (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
+ }
}
}
}
@@ -1982,7 +1994,7 @@ static struct sched_info region_sched_info =
NULL, NULL,
NULL, NULL,
- 0, 0
+ 0, 0, 0
};
/* Determine if PAT sets a CLASS_LIKELY_SPILLED_P register. */