This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: other/7114: ICE building strcoll.op from glibc-2.2.5
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: amodra at gcc dot gnu dot org
- Cc: gcc-prs at gcc dot gnu dot org,
- Date: 17 Jul 2002 04:16:00 -0000
- Subject: Re: other/7114: ICE building strcoll.op from glibc-2.2.5
- Reply-to: Alan Modra <amodra at bigpond dot net dot au>
The following reply was made to PR other/7114; it has been noted by GNATS.
From: Alan Modra <amodra@bigpond.net.au>
To: Geoff Keating <geoffk@redhat.com>, d.mueller@elsoft.ch,
gcc-gnats@gcc.gnu.org, gcc-patches@gcc.gnu.org, dje@watson.ibm.com
Cc:
Subject: Re: other/7114: ICE building strcoll.op from glibc-2.2.5
Date: Wed, 17 Jul 2002 13:42:00 +0930
PR target/5967, PR other/7114
* config/rs6000/r6000.c (first_reg_to_save): Remove bogus
adjustments to first_reg for profiling case.
(output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
Disable profiling for nested functions on ABI_V4, and for 64 bit
code on both ABI_V4 and ABI_AIX_NODESC. Save static chain reg
to sp + 12 on ABI_AIX_NODESC.
Rationale:
* config/rs6000/r6000.c (first_reg_to_save): Remove bogus
adjustments to first_reg for profiling case.
first_reg_to_save doesn't need to do anything special for any of these
registers as profiling is done via PROFILE_HOOK when ABI_AIX or
ABI_DARWIN. The normal register allocation code will set up
regs_ever_live for us. We're killing profiling on nested functions
when ABI_V4.
(output_function_profiler): Correct lr save slot for ABI_AIX_NODESC.
ABI_AIX_NODESC saves lr to sp + 8. This change is perhaps a little
contentious as existing mcount implementations may take into account
the current ABI breakage.
Disable profiling for nested functions on ABI_V4
See the comment below.
and for 64 bit code on both ABI_V4 and ABI_AIX_NODESC.
The instructions emitted here are 32 bit ones.
Save static chain reg to sp + 12 on ABI_AIX_NODESC.
We need to save it somewhere, or disable profiling of nested functions
for ABI_AIX_NODESC too.
bootstrapped (a slightly different patch) and regression tested
powerpc-linux. I'm re-running the bootstrap now. Built powerpc-linux
and powerpc64-linux glibc --enable-profile to test ABI_V4 and ABI_AIX
changes.
--
Alan Modra
IBM OzLabs - Linux Technology Centre
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.343
diff -u -p -r1.343 rs6000.c
--- rs6000.c 16 Jul 2002 02:16:41 -0000 1.343
+++ rs6000.c 17 Jul 2002 03:43:03 -0000
@@ -7357,53 +7357,6 @@ first_reg_to_save ()
|| (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
break;
- if (current_function_profile)
- {
- /* AIX must save/restore every register that contains a parameter
- before/after the .__mcount call plus an additional register
- for the static chain, if needed; use registers from 30 down to 22
- to do this. */
- if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
- {
- int last_parm_reg, profile_first_reg;
-
- /* Figure out last used parameter register. The proper thing
- to do is to walk incoming args of the function. A function
- might have live parameter registers even if it has no
- incoming args. */
- for (last_parm_reg = 10;
- last_parm_reg > 2 && ! regs_ever_live [last_parm_reg];
- last_parm_reg--)
- ;
-
- /* Calculate first reg for saving parameter registers
- and static chain.
- Skip reg 31 which may contain the frame pointer. */
- profile_first_reg = (33 - last_parm_reg
- - (current_function_needs_context ? 1 : 0));
-#if TARGET_MACHO
- /* Need to skip another reg to account for R31 being PICBASE
- (when flag_pic is set) or R30 being used as the frame
- pointer (when flag_pic is not set). */
- --profile_first_reg;
-#endif
- /* Do not save frame pointer if no parameters needs to be saved. */
- if (profile_first_reg == 31)
- profile_first_reg = 32;
-
- if (first_reg > profile_first_reg)
- first_reg = profile_first_reg;
- }
-
- /* SVR4 may need one register to preserve the static chain. */
- else if (current_function_needs_context)
- {
- /* Skip reg 31 which may contain the frame pointer. */
- if (first_reg > 30)
- first_reg = 30;
- }
- }
-
#if TARGET_MACHO
if (flag_pic && current_function_uses_pic_offset_table &&
(first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM))
@@ -10430,6 +10383,8 @@ output_function_profiler (file, labelno)
int labelno;
{
char buf[100];
+ int save_lr = 8;
+ int save_chain = 12;
ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno);
switch (DEFAULT_ABI)
@@ -10438,13 +10393,35 @@ output_function_profiler (file, labelno)
abort ();
case ABI_V4:
+ if (current_function_needs_context)
+ {
+ /* There's no safe way to save STATIC_CHAIN_REGNUM around
+ the mcount call. The ABI_V4 stack has no slot available,
+ and since we are PROFILE_BEFORE_PROLOGUE, we can't use a
+ call-saved register. Adjusting the stack to give us some
+ space might confuse special purpose mcount functions.
+ And finally, clobbering a callee saved register for the
+ purpose of saving the static chain when calling a nested
+ function is difficult to get right; You might be calling
+ a nested function via a function pointer. */
+ warning ("no profiling on nested functions for this ABI");
+ return;
+ }
+ save_lr = 4;
+ /* Fall through. */
+
case ABI_AIX_NODESC:
+ if (!TARGET_32BIT)
+ {
+ warning ("no profiling of 64-bit code for this ABI");
+ return;
+ }
fprintf (file, "\tmflr %s\n", reg_names[0]);
if (flag_pic == 1)
{
fputs ("\tbl _GLOBAL_OFFSET_TABLE_@local-4\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
asm_fprintf (file, "\tmflr %s\n", reg_names[12]);
asm_fprintf (file, "\t{l|lwz} %s,", reg_names[0]);
assemble_name (file, buf);
@@ -10452,8 +10429,8 @@ output_function_profiler (file, labelno)
}
else if (flag_pic > 1)
{
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
/* Now, we need to get the address of the label. */
fputs ("\tbl 1f\n\t.long ", file);
assemble_name (file, buf);
@@ -10469,20 +10446,25 @@ output_function_profiler (file, labelno)
asm_fprintf (file, "\t{liu|lis} %s,", reg_names[12]);
assemble_name (file, buf);
fputs ("@ha\n", file);
- asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
- reg_names[0], reg_names[1]);
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[0], save_lr, reg_names[1]);
asm_fprintf (file, "\t{cal|la} %s,", reg_names[0]);
assemble_name (file, buf);
asm_fprintf (file, "@l(%s)\n", reg_names[12]);
}
if (current_function_needs_context)
- asm_fprintf (file, "\tmr %s,%s\n",
- reg_names[30], reg_names[STATIC_CHAIN_REGNUM]);
- fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
- if (current_function_needs_context)
- asm_fprintf (file, "\tmr %s,%s\n",
- reg_names[STATIC_CHAIN_REGNUM], reg_names[30]);
+ {
+ asm_fprintf (file, "\t{st|stw} %s,%d(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM],
+ save_chain, reg_names[1]);
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
+ asm_fprintf (file, "\t{l|lwz} %s,%d(%s)\n",
+ reg_names[STATIC_CHAIN_REGNUM],
+ save_chain, reg_names[1]);
+ }
+ else
+ fprintf (file, "\tbl %s\n", RS6000_MCOUNT);
break;
case ABI_AIX: