This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PIC_OFFSET_TABLE_SAVE_RTX in large stack frame
- To: John David Anglin <dave at hiauly1 dot hia dot nrc dot ca>
- Subject: Re: PIC_OFFSET_TABLE_SAVE_RTX in large stack frame
- From: Alan Modra <alan at linuxcare dot com dot au>
- Date: Wed, 31 Jan 2001 16:14:00 +1100 (EST)
- cc: Richard Henderson <rth at redhat dot com>, Jeffrey A Law <law at redhat dot com>, gcc-patches at gcc dot gnu dot org
On Wed, 31 Jan 2001, Alan Modra wrote:
> On Sat, 27 Jan 2001, John David Anglin wrote:
>
> > > Don't give up so easy. It _is_ possible to insert a move
> > > at the beginning of the function. See alpha_return_address:
> > >
> > > push_topmost_sequence ();
> > > emit_insn_after (init, get_insns ());
> > > pop_topmost_sequence ();
> >
> > Here is a revised patch using the above approach. Bootstrapped and
> > checked under hpux 10.20 with no regressions. I will post full test
> > results later. The PIC testing is rather limited however.
>
> This trick doesn't seem to work for inline functions.
OK, what's happening is that expand_inline_function doesn't copy
instructions associated with parameter finagling when inlining. Since we
were putting our pic offset table reg save at the beginning of the
function, the move instruction was being lumped in with parameter insns.
Here's a fix that cures the testcase I posted. Currently bootstrapping.
I'll post an "Oh no!" if the bootstrap fails.
* config/pa/pa.c (hppa_init_pic_save): Emit the pic offset table
reg save after last_parm_insn.
* config/pa/pa.c (hppa_init_pic_save): New function.
* config/pa/pa.h (hppa_init_pic_save): Declare.
* config/pa/pa.md (call, call_value, sibcall, sibcall_value): Use
the above instead of duplicated code.
Alan Modra
--
Linuxcare. Support for the Revolution.
diff -urp -xCVS -x*~ egcs/gcc/config/pa/pa.c newegcs/gcc/config/pa/pa.c
--- egcs/gcc/config/pa/pa.c Wed Jan 31 15:01:18 2001
+++ newegcs/gcc/config/pa/pa.c Wed Jan 31 15:04:02 2001
@@ -3371,6 +3371,21 @@ hppa_expand_epilogue ()
- actual_fsize);
}
+/* Set up a callee saved register for the pic offset table register. */
+void hppa_init_pic_save ()
+{
+ rtx insn, picreg;
+
+ picreg = gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM);
+ PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
+ insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX, picreg);
+
+ /* Emit the insn at the beginning of the function after the prologue. */
+ push_topmost_sequence ();
+ emit_insn_after (insn, last_parm_insn ? last_parm_insn : get_insns ());
+ pop_topmost_sequence ();
+}
+
/* Fetch the return address for the frame COUNT steps up from
the current frame, after the prologue. FRAMEADDR is the
frame pointer of the COUNT frame.
diff -urp -xCVS -x*~ egcs/gcc/config/pa/pa.h newegcs/gcc/config/pa/pa.h
--- egcs/gcc/config/pa/pa.h Wed Jan 31 15:01:19 2001
+++ newegcs/gcc/config/pa/pa.h Wed Jan 31 15:02:38 2001
@@ -503,6 +503,7 @@ extern int target_flags;
/* Register into which we save the PIC_OFFSET_TABLE_REGNUM so that it
can be restored across function calls. */
#define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx)
+extern void hppa_init_pic_save PARAMS ((void));
#define DEFAULT_PCC_STRUCT_RETURN 0
diff -urp -xCVS -x*~ egcs/gcc/config/pa/pa.md newegcs/gcc/config/pa/pa.md
--- egcs/gcc/config/pa/pa.md Wed Jan 31 15:01:19 2001
+++ newegcs/gcc/config/pa/pa.md Wed Jan 31 15:09:12 2001
@@ -5738,18 +5738,7 @@
GEN_INT (64)));
if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
- {
- rtx insn;
-
- PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
- insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
-
- /* Emit the insn at the beginning of the function after the prologue. */
- push_topmost_sequence ();
- emit_insn_after (insn, get_insns ());
- pop_topmost_sequence ();
- }
+ hppa_init_pic_save ();
/* Use two different patterns for calls to explicitly named functions
and calls through function pointers. This is necessary as these two
@@ -5922,18 +5911,7 @@
GEN_INT (64)));
if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
- {
- rtx insn;
-
- PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
- insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
-
- /* Emit the insn at the beginning of the function after the prologue. */
- push_topmost_sequence ();
- emit_insn_after (insn, get_insns ());
- pop_topmost_sequence ();
- }
+ hppa_init_pic_save ();
/* Use two different patterns for calls to explicitly named functions
and calls through function pointers. This is necessary as these two
@@ -6132,18 +6110,7 @@
op = XEXP (operands[0], 0);
if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
- {
- rtx insn;
-
- PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
- insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
-
- /* Emit the insn at the beginning of the function after the prologue. */
- push_topmost_sequence ();
- emit_insn_after (insn, get_insns ());
- pop_topmost_sequence ();
- }
+ hppa_init_pic_save ();
/* We do not allow indirect sibling calls. */
call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
@@ -6201,18 +6168,7 @@
op = XEXP (operands[1], 0);
if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
- {
- rtx insn;
-
- PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
- insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
- gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
-
- /* Emit the insn at the beginning of the function after the prologue. */
- push_topmost_sequence ();
- emit_insn_after (insn, get_insns ());
- pop_topmost_sequence ();
- }
+ hppa_init_pic_save ();
/* We do not allow indirect sibling calls. */
call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],