[gnu.gcc.bug] ENHANCEMENT for GCC 1.30 - faster prologue/epilogue code for NS32K's

rfg@nsc.nsc.com (Ron Guilmette) (10/27/88)

ENHANCEMENT for GCC 1.30  --  Faster function prologue/epilogue code for ns32k

If you are using GCC on a National 32000 series system (e.g. Sequent, Encore),
you may want to look at this.

It seems that, quite unexpectedly, it is (much?) faster to do a whole series
of pushes and pops that it is to use the 32000's enter & leave (and maybe also
save & restore) instructions.  This seems to be true EVEN if you have to
push & pop a whole complement (i.e. 5) of non-temporary general registers
(i.e. r3-r7) for a given function prologue & epilogue.  Don't ask me why
this is true, but I checked it on a '532 and on a '332 and its faster on both.
Could somebody please check it on a Sequent-Balance (i.e. an '032 based system).

Anyway, the following patches to tm-ns32k.h cause the faster prologue/epilogue
code to be used, but only if you use the -fomit-frame-pointer flag.  It should
be easy to change my changes to get them to do pushes & pops even when the
-fomit-frame-pointer is not used, but why bother.  If you don't care how fast
you code runs, then you probably won't use -fomit-frame-pointer.  If you do
care then you probably always will.

diff -rc2 1.30/tm-ns32k.h 1.30-gnx/tm-ns32k.h
*** 1.30/tm-ns32k.h	Sat Oct  8 10:09:40 1988
--- 1.30-gnx/tm-ns32k.h	Wed Oct 26 12:19:15 1988
***************
*** 447,452
  #define FUNCTION_PROLOGUE(FILE, SIZE)     \
  { register int regno;						\
!   register int nregs;						\
!   char used_regs_buf[32], *bufp = used_regs_buf;		\
    int used_fregs_buf[8], *fbufp = used_fregs_buf;		\
    extern char call_used_regs[];					\

--- 447,451 -----
  #define FUNCTION_PROLOGUE(FILE, SIZE)     \
  { register int regno;						\
!   int used_regs_buf[8], *bufp = used_regs_buf;			\
    int used_fregs_buf[8], *fbufp = used_fregs_buf;		\
    extern char call_used_regs[];					\
***************
*** 452,456
    extern char call_used_regs[];					\
    MAIN_FUNCTION_PROLOGUE;					\
!   for (regno = 0, nregs = 0; regno < 8; regno++)		\
      if (regs_ever_live[regno] && !call_used_regs[regno]) {	\
         nregs += 1;						\

--- 451,455 -----
    extern char call_used_regs[];					\
    MAIN_FUNCTION_PROLOGUE;					\
!   for (regno = 0; regno < 8; regno++)				\
      if (regs_ever_live[regno] && !call_used_regs[regno]) {	\
         *bufp++ = regno;						\
***************
*** 454,459
    for (regno = 0, nregs = 0; regno < 8; regno++)		\
      if (regs_ever_live[regno] && !call_used_regs[regno]) {	\
!        nregs += 1;						\
!        *bufp++ = 'r'; *bufp++ = regno+'0'; *bufp++ = ',';	\
      }								\
    for (; regno < 16; regno++)					\

--- 453,457 -----
    for (regno = 0; regno < 8; regno++)				\
      if (regs_ever_live[regno] && !call_used_regs[regno]) {	\
!        *bufp++ = regno;						\
      }								\
    *bufp = -1;							\
***************
*** 457,460
         *bufp++ = 'r'; *bufp++ = regno+'0'; *bufp++ = ',';	\
      }								\
    for (; regno < 16; regno++)					\
      if (regs_ever_live[regno] && !call_used_regs[regno]) {	\

--- 455,459 -----
         *bufp++ = regno;						\
      }								\
+   *bufp = -1;							\
    for (; regno < 16; regno++)					\
      if (regs_ever_live[regno] && !call_used_regs[regno]) {	\
***************
*** 461,471
         *fbufp++ = regno;					\
      }								\
-   if (bufp > used_regs_buf) --bufp;				\
-   *bufp = '\0';							\
-   if (frame_pointer_needed)					\
-     fprintf (FILE, "\tenter [%s],%d\n", used_regs_buf,SIZE);	\
-   else if (nregs == 1)						\
-     fprintf (FILE, "\tmovd %s,tos\n", used_regs_buf);		\
-   else if (nregs) fprintf (FILE, "\tsave [%s]\n", used_regs_buf); \
    *fbufp = -1;							\
    fbufp = used_fregs_buf;					\

--- 460,463 -----
         *fbufp++ = regno;					\
      }								\
    *fbufp = -1;							\
    bufp = used_regs_buf;						\
***************
*** 469,472
    else if (nregs) fprintf (FILE, "\tsave [%s]\n", used_regs_buf); \
    *fbufp = -1;							\
    fbufp = used_fregs_buf;					\
    while (*fbufp >= 0)						\

--- 461,477 -----
      }								\
    *fbufp = -1;							\
+   bufp = used_regs_buf;						\
+   if (frame_pointer_needed) {					\
+     fprintf (FILE, "\tenter [");				\
+     while (*bufp >= 0) {					\
+       fprintf (FILE, "r%d", *bufp++);				\
+       if (*bufp >= 0)						\
+ 	fputc (',', FILE);					\
+     }								\
+     fprintf (FILE, "],%d\n", SIZE);				\
+   } else {							\
+     while (*bufp >= 0)						\
+       fprintf (FILE, "\tmovd r%d,tos\n", *bufp++);		\
+   }								\
    fbufp = used_fregs_buf;					\
    while (*fbufp >= 0)						\
***************
*** 511,516
    extern int current_function_args_size;			\
    register int regno;						\
!   register int nregs;						\
!   char used_regs_buf[32], *bufp = used_regs_buf;		\
    int used_fregs_buf[8], *fbufp = used_fregs_buf;		\
    extern char call_used_regs[];					\

--- 516,520 -----
    extern int current_function_args_size;			\
    register int regno;						\
!   int used_regs_buf[8], *bufp = used_regs_buf;			\
    int used_fregs_buf[8], *fbufp = used_fregs_buf;		\
    extern char call_used_regs[];					\
***************
*** 530,534
        else fprintf (FILE, "\tmovf tos,f%d\n", *fbufp-- - 8);	\
      }								\
!   for (regno = 0, nregs = 0; regno < 8; regno++)		\
      if (regs_ever_live[regno] && ! call_used_regs[regno]) {	\
          nregs++;						\

--- 534,538 -----
        else fprintf (FILE, "\tmovf tos,f%d\n", *fbufp-- - 8);	\
      }								\
!   for (regno = 0; regno < 8; regno++)				\
      if (regs_ever_live[regno] && ! call_used_regs[regno]) {	\
         *bufp++ = regno;						\
***************
*** 532,537
    for (regno = 0, nregs = 0; regno < 8; regno++)		\
      if (regs_ever_live[regno] && ! call_used_regs[regno]) {	\
!         nregs++;						\
!        *bufp++ = 'r'; *bufp++ = regno+'0'; *bufp++ = ',';	\
      }								\
    if (bufp > used_regs_buf) --bufp;				\

--- 536,540 -----
    for (regno = 0; regno < 8; regno++)				\
      if (regs_ever_live[regno] && ! call_used_regs[regno]) {	\
!        *bufp++ = regno;						\
      }								\
    if (frame_pointer_needed) {					\
***************
*** 535,546
         *bufp++ = 'r'; *bufp++ = regno+'0'; *bufp++ = ',';	\
      }								\
!   if (bufp > used_regs_buf) --bufp;				\
!   *bufp = '\0';							\
!   if (frame_pointer_needed)					\
!     fprintf (FILE, "\texit [%s]\n", used_regs_buf);		\
!   else if (nregs == 1)						\
!     fprintf (FILE, "\tmovd tos,%s\n", used_regs_buf);		\
!   else if (nregs)						\
!     fprintf (FILE, "\trestore [%s]\n", used_regs_buf);		\
    if (current_function_pops_args && current_function_args_size)	\
      fprintf (FILE, "\tret %d\n", current_function_args_size);	\

--- 538,553 -----
         *bufp++ = regno;						\
      }								\
!   if (frame_pointer_needed) {					\
!     fprintf (FILE, "\texit [");					\
!     while (bufp > used_regs_buf) {				\
!       fprintf (FILE, "r%d", *--bufp);				\
!       if (bufp > used_regs_buf)					\
! 	fputc (',', FILE);					\
!     }								\
!     fprintf (FILE, "]\n");					\
!   } else {							\
!     while (bufp > used_regs_buf)				\
!       fprintf (FILE, "\tmovd tos,r%d\n", *--bufp);		\
!   }								\
    if (current_function_pops_args && current_function_args_size)	\
      fprintf (FILE, "\tret %d\n", current_function_args_size);	\