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); \