[PATCH] insn priority adjustments in scheduler and rs6000 port

Dorit Naishlos DORIT@il.ibm.com
Tue Sep 30 10:20:00 GMT 2003


Hi Vlad,

>  Another things is that the patch is about improving
> the generated code.  Then we should have some benchmarks (the best
> ones are SPEC) proving that the patch improves the code.
>
Overall we've seen 0.3%/0.2% improvement in spec fp/int (only very few
benchmarks were degraded; maximum degradation was 1.2%, and maximum
improvement 3.2%). Combined with the second patch (scheduling of queued
insns) we've seen an overall 0.6% improvement in both spec int and fp
(maximum degradation 1%, maximum imoprovement 4.1%).

>   But in general the patch looks ok.  So if you fix all comments and
> give us some benchmarks, the patch could be committed in the mainline.
>
Attached is the revised patch, incorporating your comments.

>   As for the patch about scheduling of queued insns, it is more
> controversial.  The same comments are applicable to the patch.
> But I need to think more about the patch idea because it violates
> the scheduler design:
>
This is true, but it can be useful to allow this violation if a target
specifically requests that. For example, if data/resource delays do not
prevent the machine from filling up dispatch groups, the only way the
scheduler can (try to) stay in synch with the processor behavior is to
allow the same flexibility that the processor dispatcher has. This feature
can be useful in a multiple-issue out-of-order machine, where (a) it's
practically hopeless to predict the actual data/resource delays, however:
(b) there's a better chance to predict the actual grouping that will be
formed, and (c) correctly emulating the grouping can be very important.

One thing we can do in order to minimize the violation of scheduler
assumptions and maintain a more "correct" description of the delays between
dependent insns, is to record the number of cycles by which an INSN was
prematurely scheduled ("premature_issue"). This value will be used when
scheduling the INSN (in schedule_insn()) to adjust the delay of each insn
'next' that depends upon it:
INSN_TICK (next) =
     MAX (INSN_TICK (next), clock + cost + premature_issue);
                                         ^^^^^^^^^^^^^^^^^
The value "premature_issue" models the expected delay between the issue
cycle and the execute cycle; incorporating it this way is suitable for
targets that have issue queues.

What do you think?

thanks,
dorit

2003-09-29  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.


Index: haifa-sched.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/haifa-sched.c,v
retrieving revision 1.229
diff -c -3 -p -r1.229 haifa-sched.c
*** haifa-sched.c 15 Sep 2003 18:52:33 -0000    1.229
--- haifa-sched.c 29 Sep 2003 19:32:59 -0000
*************** set_priorities (rtx head, rtx tail)
*** 2517,2523 ****
  {
    rtx insn;
    int n_insn;
!
    rtx prev_head;

    prev_head = PREV_INSN (head);
--- 2517,2524 ----
  {
    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);
*************** set_priorities (rtx head, rtx tail)
*** 2526,2531 ****
--- 2527,2533 ----
      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 ****
--- 2535,2548 ----

        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: sched-ebb.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/sched-ebb.c,v
retrieving revision 1.30
diff -c -3 -p -r1.30 sched-ebb.c
*** sched-ebb.c   15 Jul 2003 13:02:20 -0000    1.30
--- sched-ebb.c   29 Sep 2003 19:32:59 -0000
*************** static struct sched_info ebb_sched_info
*** 204,210 ****

    NULL, NULL,
    NULL, NULL,
!   0, 1
  };

  /* It is possible that ebb scheduling eliminated some blocks.
--- 204,210 ----

    NULL, NULL,
    NULL, NULL,
!   0, 1, 0
  };

  /* It is possible that ebb scheduling eliminated some blocks.
Index: sched-int.h
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/sched-int.h,v
retrieving revision 1.28
diff -c -3 -p -r1.28 sched-int.h
*** sched-int.h   15 Jul 2003 13:02:20 -0000    1.28
--- sched-int.h   29 Sep 2003 19:32:59 -0000
*************** struct sched_info
*** 167,172 ****
--- 167,175 ----
       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: 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
*** sched-rgn.c   19 Jul 2003 22:03:37 -0000    1.63
--- sched-rgn.c   29 Sep 2003 19:33:00 -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));
!           }
        }
        }
  }
*************** static struct sched_info region_sched_in
*** 1982,1988 ****

    NULL, NULL,
    NULL, NULL,
!   0, 0
  };

  /* Determine if PAT sets a CLASS_LIKELY_SPILLED_P register.  */
--- 1994,2000 ----

    NULL, NULL,
    NULL, NULL,
!   0, 0, 0
  };

  /* Determine if PAT sets a CLASS_LIKELY_SPILLED_P register.  */
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.521
diff -c -3 -p -r1.521 rs6000.c
*** config/rs6000/rs6000.c    23 Sep 2003 21:37:31 -0000    1.521
--- config/rs6000/rs6000.c    29 Sep 2003 19:33:04 -0000
***************
*** 51,56 ****
--- 51,57 ----
  #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
*************** struct rs6000_cpu_select rs6000_select[3
*** 80,85 ****
--- 81,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;
+
  /* Size of long double */
  const char *rs6000_long_double_size_string;
  int rs6000_long_double_type_size;
*************** static int rs6000_use_dfa_pipeline_inter
*** 268,273 ****
--- 274,280 ----
  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);
*************** rs6000_override_options (const char *def
*** 820,825 ****
--- 827,838 ----
        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 (rtx insn, rtx link,
*** 13044,13052 ****
    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.  */

--- 13057,13106 ----
    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). 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 (rtx insn ATTRIBU
*** 13082,13087 ****
--- 13136,13160 ----
        }
    }
  #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: 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
*** config/rs6000/rs6000.h    21 Jul 2003 20:18:52 -0000    1.286
--- config/rs6000/rs6000.h    29 Sep 2003 19:33:04 -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
Index: doc/invoke.texi
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/doc/invoke.texi,v
retrieving revision 1.339
diff -c -3 -p -r1.339 invoke.texi
*** doc/invoke.texi     25 Sep 2003 01:25:52 -0000    1.339
--- doc/invoke.texi     29 Sep 2003 19:33:08 -0000
*************** in the following sections.
*** 431,436 ****
--- 431,437 ----
  -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
*************** On Darwin and Mac OS X systems, compile
*** 7525,7530 ****
--- 7526,7539 ----
  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




                                                                                                                                     
                      Vladimir Makarov                                                                                               
                      <vmakarov@redhat.        To:       Dorit Naishlos/Haifa/IBM@IBMIL                                              
                      com>                     cc:       gcc-patches@gcc.gnu.org                                                     
                      Sent by:                 Subject:  Re: [PATCH] insn priority adjustments in scheduler and rs6000 port          
                      vmakarov@toronto.                                                                                              
                      redhat.com                                                                                                     
                                                                                                                                     
                                                                                                                                     
                      26/09/2003 00:37                                                                                               
                                                                                                                                     




  Hi, Dorit.  I have some comments about the patch.  They are mostly
about coding style (absence comments for some global variables and
absence blanks before left parentheses in macro calls) and Changelog
entries (like absence periods at the end of sentences and usage of
lower case letters for the first word of sentences).  Please, read
GNU coding standards.  Also extern declarations should be in *.h files
(like sched_max_insns_priority should be sched-int.h or rtl.h).

  If you create new compiler options, they should be described in the
documentation.  Another things is that the patch is about improving
the generated code.  Then we should have some benchmarks (the best
ones are SPEC) proving that the patch improves the code.

  But in general the patch looks ok.  So if you fix all comments and
give us some benchmarks, the patch could be committed in the mainline.

  As for the patch about scheduling of queued insns, it is more
controversial.  The same comments are applicable to the patch.  But I
need to think more about the patch idea because it violates the
scheduler design:

1. insns are issued only from ready.
2. queue contains insns which can not be issued on the
   current cycle (because of the data or resource delay).

Vlad

> 2003-09-09  Dorit Naishlos  <dorit@il.ibm.com>
>
>       * sched-rgn.c (init_ready_list): add invocations to

                                         ^ it should be capital letter.
                                         The same below.

>       targetm.sched.adjust_priority.
>       * haifa-sched.c (sched_max_insns_priority): new global
>       variable. Defined here, used in config/rs6000/rs6000.c.

                 ^ additional blank.

>       * 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;

The global variable should have a comment.

> +
>   #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))

                                 ^ additional blank (the same
                                                     is in many places)

> +         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 */

                                                ^ period and additional
blank
                                                  (the same in many
places)

> + const char *rs6000_sched_restricted_insns_priority_str;
> + int rs6000_sched_restricted_insns_priority;
> + extern int sched_max_insns_priority;
        The extern variable should be in a .h file.
> +
>   /* 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. */

                                                                 ^
additional
                                                                   blank

> +         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}, \


In my opinion, it is better to use enumeration for the parameter
value.  Because it is not just a value but some encoding.


>      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
>





More information about the Gcc-patches mailing list