This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] insn priority adjustments in scheduler and rs6000 port


The following patch affects instruction scheduling, and is mostly specific
to the power4 target (in the rs6000 port). Bootstrap and regression passed
on powerpc-apple-darwin6.4.

The power4 target dispatches in each cycle a group of upto 4 instructions
(+ a branch). Some instructions have restrictions on which of the 4
dispatch slots they can be assigned to. Specifically, there's a set of
instructions that can only be dispatched as the first instruction in a
dispatch group. Choosing a non-restricted instruction as the first
instruction in a group, may cause a premature termination of the dispatch
group (for example, if the only remaining ready instruction for this cycle
is dispatch-slot restricted).

The scheduler defines a target hook - adjust_priority - to modify the
priority of insns during scheduling. We define this hook in the rs6000 port
to give higher priority to dispatch-slot restricted insns.

Currently, this hook is invoked each time an insn is removed from the
"Pending" list (in schedule_insn()), *except* for when the ready list is
first initialized. This means that for certain insns the target cannot
affect the priority. We want to make sure that the adjust_priority hook is
applied to *all* the insns; therefore we introduce a few minor changes to
the scheduler itself as well.

Specifically, this patch contains the following:

1) Add invocations of the target hook adjust_priority at ready_list
initialization (in sched-rgn.c)
2) Keep track of the maximum priority in order to allow the target hook to
assign the highest priority if it needs to ("sched_max_insns_priority", in
haifa-sched.c)
3) Define adjust_priority hook for the rs6000 port, according to a new
rs6000 specific flag: -mprioritize-restricted-insns=X, as follows: if X ==
0/1/2, dispatch-slot restrictions have no/highest/second-highest priority.
The default value of X is 1 for power4, and 0 for the other rs6000 targets.

ChangeLog entry
---------------

2003-09-09  Dorit Naishlos  <dorit@il.ibm.com>

      * sched-rgn.c (init_ready_list): add invocations to
      targetm.sched.adjust_priority.
      * haifa-sched.c (sched_max_insns_priority): new global
      variable. Defined here, used in config/rs6000/rs6000.c.
      * 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.


(We've had problems with line breaks in the past, so I'm sending the patch
both inlined and as an attachment)

thanks,
dorit

(See attached file: sched1_patch)

Index: gcc/gcc/haifa-sched.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/haifa-sched.c,v
retrieving revision 1.228
diff -c -3 -p -r1.228 haifa-sched.c
*** gcc/gcc/haifa-sched.c     19 Aug 2003 23:21:59 -0000    1.228
--- gcc/gcc/haifa-sched.c     7 Sep 2003 12:59:16 -0000
*************** static int max_issue (struct ready_list
*** 531,536 ****
--- 531,538 ----

  static rtx choose_ready (struct ready_list *);

+ int sched_max_insns_priority = 0;
+
  #endif /* INSN_SCHEDULING */

  /* Point to state used for the current scheduling pass.  */
*************** set_priorities (rtx head, rtx tail)
*** 2526,2531 ****
--- 2528,2534 ----
      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)
*************** set_priorities (rtx head, rtx tail)
*** 2533,2539 ****
--- 2536,2547 ----

        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;

    return n_insn;
  }
Index: gcc/gcc/sched-rgn.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/sched-rgn.c,v
retrieving revision 1.63
diff -c -3 -p -r1.63 sched-rgn.c
*** gcc/gcc/sched-rgn.c 19 Jul 2003 22:03:37 -0000    1.63
--- gcc/gcc/sched-rgn.c 7 Sep 2003 12:59:18 -0000
*************** init_ready_list (struct ready_list *read
*** 1756,1762 ****
    for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
      {
        if (INSN_DEP_COUNT (insn) == 0)
!     ready_add (ready, insn);
        target_n_insns++;
      }

--- 1756,1768 ----
    for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
      {
        if (INSN_DEP_COUNT (insn) == 0)
!         {
!           ready_add (ready, insn);
!
!           if (targetm.sched.adjust_priority)
!             INSN_PRIORITY (insn) =
!               (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
!         }
        target_n_insns++;
      }

*************** init_ready_list (struct ready_list *read
*** 1792,1798 ****
                  && check_live (insn, bb_src)
                  && is_exception_free (insn, bb_src, target_bb))))
            if (INSN_DEP_COUNT (insn) == 0)
!           ready_add (ready, insn);
        }
        }
  }
--- 1798,1810 ----
                  && check_live (insn, bb_src)
                  && is_exception_free (insn, bb_src, target_bb))))
            if (INSN_DEP_COUNT (insn) == 0)
!                 {
!                   ready_add (ready, insn);
!
!                   if (targetm.sched.adjust_priority)
!                     INSN_PRIORITY (insn) =
!                       (*targetm.sched.adjust_priority) (insn, INSN_PRIORITY (insn));
!                 }
        }
        }
  }
Index: gcc/gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.512
diff -c -3 -p -r1.512 rs6000.c
*** gcc/gcc/config/rs6000/rs6000.c  4 Sep 2003 03:17:58 -0000     1.512
--- gcc/gcc/config/rs6000/rs6000.c  7 Sep 2003 12:59:26 -0000
*************** struct rs6000_cpu_select rs6000_select[3
*** 80,85 ****
--- 80,91 ----
    { (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;
+ extern int sched_max_insns_priority;
+
  /* Size of long double */
  const char *rs6000_long_double_size_string;
  int rs6000_long_double_type_size;
*************** static int rs6000_get_some_local_dynamic
*** 322,327 ****
--- 328,335 ----
  static rtx rs6000_complex_function_value (enum machine_mode);
  static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree);

+ static bool is_dispatch_slot_restricted (rtx);
+
  /* Hash table stuff for keeping track of TOC entries.  */

  struct toc_hash_struct GTY(())
*************** rs6000_override_options (default_cpu)
*** 824,829 ****
--- 832,843 ----
        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.  */
*************** rs6000_adjust_cost (insn, link, dep_insn
*** 13353,13361 ****
    return cost;
  }

  /* 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
     define this macro if you do not need to adjust the scheduling
     priorities of insns.  */

--- 13367,13413 ----
    return cost;
  }

+ /* Return 1 if INSN can be scheduled only as the first insn
+    in a dispatch group. Retrun 0 otherwise. */
+
+ static bool
+ 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). 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.  */

*************** rs6000_adjust_priority (insn, priority)
*** 13393,13398 ****
--- 13445,13469 ----
        }
    }
  #endif
+
+   if (is_dispatch_slot_restricted (insn)
+       && reload_completed
+       && 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 sched_max_insns_priority;
+       else if (rs6000_sched_restricted_insns_priority == 2)
+         /* Increase priority on 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: gcc/gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.286
diff -c -3 -p -r1.286 rs6000.h
*** gcc/gcc/config/rs6000/rs6000.h  21 Jul 2003 20:18:52 -0000    1.286
--- gcc/gcc/config/rs6000/rs6000.h  7 Sep 2003 12:59:28 -0000
*************** extern enum processor_type rs6000_cpu;
*** 404,409 ****
--- 404,411 ----
     {"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                                      \
  }

*************** extern const char *rs6000_longcall_switc
*** 457,462 ****
--- 459,466 ----
  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.
*************** extern int rs6000_alignment_flags;
*** 474,479 ****
--- 478,486 ----
  #else
  #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

Attachment: sched1_patch
Description: Binary data


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]