revised alpha ra patch

Richard Henderson rth@twiddle.rth.home
Tue Oct 7 05:30:00 GMT 1997


This is a much better way to approach the problem than using
elimination to find a stack slot.  It even gets optimial code
for simple functions.

It does not work for the twisted way that the non-dwarf, 
no-sjlj-exceptions wants to use RETURN_ADDR_RTX, but that is
fine.  That method is on the way out, and sjlj-exceptions 
works in the meantime.


r~



Tue Oct  7 02:34:35 1997  Richard Henderson  <rth@cygnus.com>

	* alpha.c (alpha_return_addr_rtx): New variable.
	(alpha_save_machine_status, alpha_restore_machine_status, 
	 alpha_init_expanders, alpha_return_addr): New functions.
	(alpha_sa_size) [!VMS]: If alpha_return_addr_rtx is non-null,
	don't trust regs_ever_live, but look at leaf_function_p.
	* alpha.h (RETURN_ADDR_RTX): A real definition.
	(INIT_EXPANDERS): New define.


Index: config/alpha/alpha.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.c,v
retrieving revision 1.2
diff -u -p -r1.2 alpha.c
--- alpha.c	1997/09/15 22:28:34	1.2
+++ alpha.c	1997/10/07 09:33:55
@@ -37,20 +37,23 @@ Boston, MA 02111-1307, USA.  */
 #include "expr.h"
 #include "obstack.h"
 #include "tree.h"
+#include "except.h"
+#include "function.h"
+
+/* External data.  */
+extern char *version_string;
+extern int rtx_equal_function_value_matters;
 
 /* Specify which cpu to schedule for. */
 enum processor_type alpha_cpu;
 
 /* Specify how accurate floating-point traps need to be.  */
-
 enum alpha_trap_precision alpha_tp;
 
 /* Specify the floating-point rounding mode.  */
-
 enum alpha_fp_rounding_mode alpha_fprm;
 
 /* Specify which things cause traps.  */
-
 enum alpha_fp_trap_mode alpha_fptm;
 
 /* Strings decoded into the above options.  */
@@ -61,30 +64,25 @@ char *alpha_fptm_string;	/* -mfp-trap-mo
 
 /* Save information from a "cmpxx" operation until the branch or scc is
    emitted.  */
-
 rtx alpha_compare_op0, alpha_compare_op1;
 int alpha_compare_fp_p;
 
 /* Save the name of the current function as used by the assembler.  This
    is used by the epilogue.  */
-
 char *alpha_function_name;
 
 /* Non-zero if inside of a function, because the Alpha asm can't
    handle .files inside of functions.  */
-
 static int inside_function = FALSE;
 
 /* Non-zero if an instruction that may cause a trap is pending.  */
-
 static int trap_pending = 0;
 
 /* Nonzero if the current function needs gp.  */
-
 int alpha_function_needs_gp;
 
-extern char *version_string;
-extern int rtx_equal_function_value_matters;
+/* If non-null, this rtx holds the return address for the function.  */
+static rtx alpha_return_addr_rtx;
 
 /* Declarations of static functions.  */
 static void alpha_set_memflags_1  PROTO((rtx, int, int, int));
@@ -95,6 +93,7 @@ static void add_long_const	PROTO((FILE *
 /* Compute the size of the save area in the stack.  */
 static void alpha_sa_mask	PROTO((unsigned long *imaskP,
 				       unsigned long *fmaskP));
+
 /* Strip type information.  */
 #define CURRENT_FUNCTION_ARGS_INFO  \
 (TARGET_OPEN_VMS ? current_function_args_info & 0xff \
@@ -1237,6 +1236,86 @@ alpha_adjust_cost (insn, link, dep_insn,
   return cost;
 }
 
+/* Functions to save and restore alpha_return_addr_rtx.  */
+
+struct machine_function
+{
+  rtx ra_rtx;
+};
+
+static void
+alpha_save_machine_status (p)
+     struct function *p;
+{
+  struct machine_function *machine =
+    (struct machine_function *) xmalloc (sizeof (struct machine_function));
+
+  p->machine = machine;
+  machine->ra_rtx = alpha_return_addr_rtx;
+}
+
+static void
+alpha_restore_machine_status (p)
+     struct function *p;
+{
+  struct machine_function *machine = p->machine;
+
+  alpha_return_addr_rtx = machine->ra_rtx;
+
+  free (machine);
+  p->machine = (struct machine_function *)0;
+}
+
+/* Do anything needed before RTL is emitted for each function.  */
+
+void
+alpha_init_expanders ()
+{
+  alpha_return_addr_rtx = NULL_RTX;
+
+  /* Arrange to save and restore machine status around nested functions.  */
+  save_machine_status = alpha_save_machine_status;
+  restore_machine_status = alpha_restore_machine_status;
+}
+
+/* Start the ball rolling with RETURN_ADDR_RTX.  */
+
+rtx
+alpha_return_addr (count, frame)
+     int count;
+     rtx frame;
+{
+  rtx init, first;
+
+  if (count != 0)
+    return const0_rtx;
+
+  if (alpha_return_addr_rtx)
+    return alpha_return_addr_rtx;
+
+  /* No rtx yet.  Invent one, and initialize it from $26 in the prologue.  */
+  alpha_return_addr_rtx = gen_reg_rtx (Pmode);
+  init = gen_rtx (SET, Pmode, alpha_return_addr_rtx, gen_rtx (REG, Pmode, 26));
+
+  /* We need to find the prologue, which is not exactly easy when multiple
+     sequences are started.  So we have to search up the stack to find the
+     first insn for the function.  */
+  if (sequence_stack)
+    {
+      struct sequence_stack *s;
+      for (s = sequence_stack; s->next; s = s->next)
+	continue;
+      first = s->first;
+    }
+  else
+    first = get_insns ();
+
+  emit_insn_after (init, first);
+
+  return alpha_return_addr_rtx;
+}
+
+
 /* Print an operand.  Recognize special options, documented below.  */
 
 void
@@ -1755,17 +1834,19 @@ alpha_sa_size ()
   int i;
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if (! fixed_regs[i] && ! call_used_regs[i] && regs_ever_live[i])
+    if (i != 26 && !fixed_regs[i] && !call_used_regs[i] && regs_ever_live[i])
       size++;
 
-  /* If some registers were saved but not reg 26, reg 26 must also
-     be saved, so leave space for it.  */
-  if (size != 0 && ! regs_ever_live[26])
+  /* If some registers were saved but not reg 26, reg 26 must also be
+     saved, so leave space for it.  */
+  if (size != 0
+      || (regs_ever_live[26]
+	  && (!alpha_return_addr_rtx || !leaf_function_p ())))
     size++;
 
   /* Our size must be even (multiple of 16 bytes).  */
   if (size & 1)
-    size ++;
+    size++;
 
   return size * 8;
 }
Index: config/alpha/alpha.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/config/alpha/alpha.h,v
retrieving revision 1.4
diff -u -p -r1.4 alpha.h
--- alpha.h	1997/09/29 06:18:28	1.4
+++ alpha.h	1997/10/07 09:34:11
@@ -1255,16 +1255,17 @@ __enable_execute_stack (addr)						\
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame.
    FRAMEADDR is the frame pointer of the COUNT frame, or the frame pointer of
-   the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME} is defined.
+   the COUNT-1 frame if RETURN_ADDR_IN_PREVIOUS_FRAME} is defined.  */
 
-   This definition for Alpha is broken, but is put in at the request of
-   Mike Stump.  */
+#define RETURN_ADDR_RTX  alpha_return_addr
+extern struct rtx_def *alpha_return_addr ();
+
+/* Initialize data used by insn expanders.  This is called from insn_emit,
+   once for every function before code is generated.  */
+
+#define INIT_EXPANDERS  alpha_init_expanders ()
+extern void alpha_init_expanders ();
 
-#define RETURN_ADDR_RTX(COUNT, FRAME)					\
-((COUNT == 0 && alpha_sa_size () == 0 && 0 /* not right. */)		\
- ? gen_rtx (REG, Pmode, 26)						\
- : gen_rtx (MEM, Pmode,							\
-	    memory_address (Pmode, FRAME)))
 
 /* Addressing modes, and classification of registers for them.  */
 



More information about the Gcc mailing list