sched-int.h (sched_info): New field sched_max_insns_priority.
authorDorit Naishlos <dorit@il.ibm.com>
Tue, 7 Oct 2003 08:18:42 +0000 (08:18 +0000)
committerDorit Nuzman <dorit@gcc.gnu.org>
Tue, 7 Oct 2003 08:18:42 +0000 (08:18 +0000)
        * 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
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/doc/invoke.texi
gcc/haifa-sched.c
gcc/sched-ebb.c
gcc/sched-int.h
gcc/sched-rgn.c

index 411503e..3298828 100644 (file)
@@ -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.
index be79acc..2dd108a 100644 (file)
@@ -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;
 }
 
index dd10fa9..beaf8d3 100644 (file)
@@ -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.  */
index e97bf38..d6ab928 100644 (file)
@@ -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
index 2776ec1..652ad18 100644 (file)
@@ -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;
 }
index dd9ec63..06637d7 100644 (file)
@@ -204,7 +204,7 @@ static struct sched_info ebb_sched_info =
 
   NULL, NULL,
   NULL, NULL,
-  0, 1
+  0, 1, 0
 };
 \f
 /* It is possible that ebb scheduling eliminated some blocks.
index 061ebe4..ba056e0 100644 (file)
@@ -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;
index f921061..0b89e35 100644 (file)
@@ -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.  */