From 79ae11c4a302d90b678ed23fe4ccfb6a163a19fc Mon Sep 17 00:00:00 2001 From: Dorit Naishlos Date: Tue, 7 Oct 2003 08:18:42 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 21 +++++++++++ gcc/config/rs6000/rs6000.c | 77 +++++++++++++++++++++++++++++++++++++- gcc/config/rs6000/rs6000.h | 7 ++++ gcc/doc/invoke.texi | 9 +++++ gcc/haifa-sched.c | 11 +++++- gcc/sched-ebb.c | 2 +- gcc/sched-int.h | 3 ++ gcc/sched-rgn.c | 18 +++++++-- 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 + + * 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 * 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. */