Oust HPPA PIC_OFFSET_TABLE_REGNUM_SAVED

Alan Modra alan@linuxcare.com.au
Tue, 16 Jan 2001 20:28:12 +1100 (EST)


On Mon, 15 Jan 2001, Richard Henderson wrote:

> On Tue, Jan 16, 2001 at 12:20:19PM +1100, Alan Modra wrote:
> > 	* config/pa/pa.c (pa_init_machine_status, pa_free_machine_status,
> > 	pa_init_expanders): New functions.
> 
> You need a mark_machine_status function.  It is also much better
> to set the global variables once in override_options than for
> every function in init_expanders.

OK, here we go.

gcc/ChangeLog
	* config/pa/pa.h (PIC_OFFSET_TABLE_REGNUM_SAVED): Remove.
	(machine_function): Define.
	(PIC_OFFSET_TABLE_SAVE_RTX) : Define.
	* config/pa/pa.c (pa_init_machine_status, pa_mark_machine_status,
	pa_free_machine_status): New functions.
	(override_options): Set {init,mark,free}_machine_status to above.
	(hppa_expand_prologue): Use PIC_OFFSET_TABLE_SAVE_RTX instead of
	PIC_OFFSET_TABLE_REGNUM_SAVED.
	* config/pa/pa.md: Use PIC_OFFSET_TABLE_SAVE_RTX instead of
	PIC_OFFSET_TABLE_REGNUM_SAVED throughout.
	* config/pa/pa32-regs.h (CONDITIONAL_REGISTER_USAGE): Remove
	references to PIC_OFFSET_TABLE_REGNUM_SAVED.
	* config/pa/pa64-regs.h (CONDITIONAL_REGISTER_USAGE): Likewise.

Alan Modra
-- 
Linuxcare.  Support for the Revolution.

diff -urp -xCVS egcs/gcc/config/pa/pa.c newegcs/gcc/config/pa/pa.c
--- egcs/gcc/config/pa/pa.c	Thu Jan  4 15:22:58 2001
+++ newegcs/gcc/config/pa/pa.c	Tue Jan 16 18:12:37 2001
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for HPPA.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
    Free Software Foundation, Inc.
    Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
 
@@ -43,6 +43,9 @@ Boston, MA 02111-1307, USA.  */
 #include "recog.h"
 #include "tm_p.h"
 
+static void pa_init_machine_status PARAMS ((struct function *));
+static void pa_mark_machine_status PARAMS ((struct function *));
+static void pa_free_machine_status PARAMS ((struct function *));
 static void pa_combine_instructions			PARAMS ((rtx));
 static int pa_can_combine_p	PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));
 static int forward_branch_p				PARAMS ((rtx));
@@ -186,6 +189,43 @@ override_options ()
 
   /* Register global variables with the garbage collector.  */
   pa_add_gc_roots ();
+
+  /* Arrange to save and restore machine status around nested functions.  */
+  init_machine_status = pa_init_machine_status;
+  mark_machine_status = pa_mark_machine_status;
+  free_machine_status = pa_free_machine_status;
+}
+
+/* Functions to initialize pic_offset_table_save_rtx.
+   These will be called, via pointer variables,
+   from push_function_context and pop_function_context.  */
+
+static void
+pa_init_machine_status (p)
+     struct function *p;
+{
+  p->machine = (machine_function *) xmalloc (sizeof (machine_function));
+
+  p->machine->pic_offset_table_save_rtx = gen_reg_rtx (Pmode);
+}
+
+static void
+pa_mark_machine_status (p)
+     struct function *p;
+{
+  if (p->machine)
+    ggc_mark_rtx (p->machine->pic_offset_table_save_rtx);
+}
+
+static void
+pa_free_machine_status (p)
+     struct function *p;
+{
+  if (p->machine == NULL)
+    return;
+
+  free (p->machine);
+  p->machine = NULL;
 }
 
 
@@ -2653,7 +2693,7 @@ remove_useless_addtr_insns (insns, check
 
 }
 
-/* You may have trouble believing this, but this is the HP-PA stack
+/* You may have trouble believing this, but this is the 32 bit HP-PA stack
    layout.  Wow.
 
    Offset		Contents
@@ -3153,19 +3193,17 @@ hppa_expand_prologue()
      made incorrect assumptions about using global variables to hold
      per-function rtl code generated in the backend.
 
-     So instead, we copy the PIC register into a reserved callee saved
-     register in the prologue.  Then after each call we reload the PIC
-     register from the callee saved register.  We also reload the PIC
-     register from the callee saved register in the epilogue ensure the
-     PIC register is valid at function exit.
-
-     This may (depending on the exact characteristics of the function)
-     even be more efficient. 
-
-     Avoid this if the callee saved register wasn't used (these are
-     leaf functions).  */
-  if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM_SAVED])
-    emit_move_insn (gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED),
+     So instead, we copy the PIC register into a callee saved register
+     in the prologue.  Then after each call we reload the PIC register
+     from the callee saved register.
+
+     Avoid doing this if the register isn't used (eg. leaf functions)
+     as it's an error to delete an instruction from the prologue.  */
+
+  if (flag_pic
+      && (GET_CODE (PIC_OFFSET_TABLE_SAVE_RTX) != REG
+	  || HARD_REGISTER_P (PIC_OFFSET_TABLE_SAVE_RTX)))
+    emit_move_insn (PIC_OFFSET_TABLE_SAVE_RTX,
 		    gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
 }
 
diff -urp -xCVS egcs/gcc/config/pa/pa.h newegcs/gcc/config/pa/pa.h
--- egcs/gcc/config/pa/pa.h	Thu Jan  4 15:22:58 2001
+++ newegcs/gcc/config/pa/pa.h	Tue Jan 16 18:02:14 2001
@@ -70,6 +70,14 @@ enum architecture_type
   ARCHITECTURE_20
 };
 
+struct rtx_def;
+/* A C structure for machine-specific, per-function data.
+   This is added to the cfun structure.  */
+typedef struct machine_function
+{
+  struct rtx_def *pic_offset_table_save_rtx;
+} machine_function;
+
 /* For -march= option.  */
 extern const char *pa_arch_string;
 extern enum architecture_type pa_arch;
@@ -493,8 +501,8 @@ extern int target_flags;
 #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1
 
 /* Register into which we save the PIC_OFFEST_TABLE_REGNUM so that it
-   can be restore across function calls.  */
-#define PIC_OFFSET_TABLE_REGNUM_SAVED 4
+   can be restored across function calls.  */
+#define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx)
 
 #define DEFAULT_PCC_STRUCT_RETURN 0
 
diff -urp -xCVS egcs/gcc/config/pa/pa.md newegcs/gcc/config/pa/pa.md
--- egcs/gcc/config/pa/pa.md	Mon Jan  8 22:47:00 2001
+++ newegcs/gcc/config/pa/pa.md	Tue Jan 16 10:45:58 2001
@@ -5735,18 +5735,12 @@
   if (flag_pic)
     {
       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
-	       gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
       if (TARGET_64BIT)
 	use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
 
       /* After each call we must restore the PIC register, even if it
-	 doesn't appear to be used.
-
-         This will set regs_ever_live for the callee saved register we
-	 stored the PIC register in.  */
-      emit_move_insn (pic_offset_table_rtx,
-		      gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+	 doesn't appear to be used.  */
+      emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
     }
   DONE;
 }")
@@ -5915,18 +5909,12 @@
   if (flag_pic)
     {
       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
-	       gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
       if (TARGET_64BIT)
 	use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), arg_pointer_rtx);
 
       /* After each call we must restore the PIC register, even if it
-	 doesn't appear to be used.
-
-         This will set regs_ever_live for the callee saved register we
-	 stored the PIC register in.  */
-      emit_move_insn (pic_offset_table_rtx,
-		      gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+	 doesn't appear to be used.  */
+      emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
     }
   DONE;
 }")
@@ -6096,16 +6084,10 @@
   if (flag_pic)
     {
       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
-	       gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
 
       /* After each call we must restore the PIC register, even if it
-	 doesn't appear to be used.
-
-         This will set regs_ever_live for the callee saved register we
-	 stored the PIC register in.  */
-      emit_move_insn (pic_offset_table_rtx,
-		      gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+	 doesn't appear to be used.  */
+      emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
     }
   DONE;
 }")
@@ -6158,16 +6140,10 @@
   if (flag_pic)
     {
       use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-      use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn),
-	       gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
 
       /* After each call we must restore the PIC register, even if it
-	 doesn't appear to be used.
-
-         This will set regs_ever_live for the callee saved register we
-	 stored the PIC register in.  */
-      emit_move_insn (pic_offset_table_rtx,
-		      gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM_SAVED));
+	 doesn't appear to be used.  */
+      emit_move_insn (pic_offset_table_rtx, PIC_OFFSET_TABLE_SAVE_RTX);
     }
   DONE;
 }")
diff -urp -xCVS egcs/gcc/config/pa/pa32-regs.h newegcs/gcc/config/pa/pa32-regs.h
--- egcs/gcc/config/pa/pa32-regs.h	Thu Jan 11 16:10:48 2001
+++ newegcs/gcc/config/pa/pa32-regs.h	Mon Jan 15 18:22:39 2001
@@ -110,11 +110,7 @@
 	fixed_regs[i] = call_used_regs[i] = 1; 	\
     }						\
   if (flag_pic)					\
-    {						\
-      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;	\
-      fixed_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
-      call_used_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
-    }						\
+    fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;	\
 }
 
 /* Allocate the call used registers first.  This should minimize
diff -urp -xCVS egcs/gcc/config/pa/pa64-regs.h newegcs/gcc/config/pa/pa64-regs.h
--- egcs/gcc/config/pa/pa64-regs.h	Thu Jan 11 16:10:48 2001
+++ newegcs/gcc/config/pa/pa64-regs.h	Mon Jan 15 18:22:40 2001
@@ -109,11 +109,7 @@ Boston, MA 02111-1307, USA.  */
 	fixed_regs[i] = call_used_regs[i] = 1; 	\
     }						\
   if (flag_pic)					\
-    {						\
-      fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;	\
-      fixed_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
-      call_used_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
-    }						\
+    fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;	\
 }
 
 /* Allocate the call used registers first.  This should minimize