This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

MIPS _mcount-based profiling doesn't work with -abicalls (2.95.3)


[I've CC'ed binutils in case any of you folks there have an opinion, since
 the things that's biting me really is assembler magic, in a sens...]

Folks:
	I've been doing some work to upgrade the NetBSD MIPS toolchain to
	2.95.3 and binutils 2.11.2, and other than some issues I need to
	take up with the binutils folks, most things works fine.

	However, I've found that executables built with profiling libraries
	(which were all rebuilt with the new toolchain) all die way before
	doing anything substantial -- somewhere in the startup code.

	I tracked the problem down to a bad interaction between the -abicalls
	option and the profiling prologue added to functions.

        Here's what happens:

                (1) A function that calls _mcount and uses .cprestore looks
                    like the following in macroized assembler:

                        .globl  function
                    function:
                        .cpload $25
                        addiu $sp, $sp, -40
                        .cprestore 36
                        ...
                        sw $gp, 36($sp)
                        ...
                        <load $t9 with address of _mcount>
                        jalr $t9            # _mcount
                        subu $sp, $sp, 8    # _mcount pops 2 works from stack


                (2) The assembler in turn expands the `jalr' bit into 

                        jalr    $t9         # _mcount
                        nop                     
                        lw      $gp, 36($sp)
                        subu    $sp, $sp, 8

                Note that due to the way the .cprestore places the load of 
                $gp after the jump (but before the cleanup of $sp), the code
                gets the wrong value of $gp.

	This is all because the FUNCTION_PROFILER macro includes some hand-
	scheduled MIPS assembly with the stack-adjustment put into the delay
	slot of the `jal'.

	I include here two patches for this problem.  The first is just a 
	simple re-schedule of the FUNCTION_PROFILER macro which does the
	stack adjust before the `jal' always.  This certainly works, and
	is the safer of the two solutions, but may cost some performance
	in the non-abicalls call where this is not needed.

	The second patch attempts to keep the hand-scheduled code for the
	non-abicalls case and produce the safer code for the abicalls case.

	I'd appreciate comments esp. on the second patch -- is this worth
	doing, or am I asking for some other case to screw me? 

Thanks!
--rafal

The `safe' patch:

Index: mips.h
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/mips/mips.h,v
retrieving revision 1.1.1.1
diff -b -u -b -u -r1.1.1.1 mips.h
--- mips.h	2000/07/26 00:18:38	1.1.1.1
+++ mips.h	2001/11/14 18:15:52
@@ -2610,13 +2610,14 @@
   fprintf (FILE, "\t.set\tnoat\n");					\
   fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n",	\
 	   reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]);	\
-  fprintf (FILE, "\tjal\t_mcount\n");					\
   fprintf (FILE,							\
 	   "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from  stack\n",	\
 	   TARGET_64BIT ? "dsubu" : "subu",				\
 	   reg_names[STACK_POINTER_REGNUM],				\
 	   reg_names[STACK_POINTER_REGNUM],				\
 	   Pmode == DImode ? 16 : 8);					\
+  fprintf (FILE, "\tjal\t_mcount\n");					\
+  fprintf (FILE, "\tnop\n");						\
   fprintf (FILE, "\t.set\treorder\n");					\
   fprintf (FILE, "\t.set\tat\n");					\
 }

The `less safe' patch:

Index: mips.h
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gcc/config/mips/mips.h,v
retrieving revision 1.1.1.1
diff -b -u -b -u -r1.1.1.1 mips.h
--- mips.h	2000/07/26 00:18:38	1.1.1.1
+++ mips.h	2001/11/14 18:21:57
@@ -2610,6 +2610,7 @@
   fprintf (FILE, "\t.set\tnoat\n");					\
   fprintf (FILE, "\tmove\t%s,%s\t\t# save current return address\n",	\
 	   reg_names[GP_REG_FIRST + 1], reg_names[GP_REG_FIRST + 31]);	\
+  if (!TARGET_ABICALLS)							\
   fprintf (FILE, "\tjal\t_mcount\n");					\
   fprintf (FILE,							\
 	   "\t%s\t%s,%s,%d\t\t# _mcount pops 2 words from  stack\n",	\
@@ -2617,6 +2618,10 @@
 	   reg_names[STACK_POINTER_REGNUM],				\
 	   reg_names[STACK_POINTER_REGNUM],				\
 	   Pmode == DImode ? 16 : 8);					\
+  if (TARGET_ABICALLS) {						\
+  	fprintf (FILE, "\tjal\t_mcount\n");				\
+  	fprintf (FILE, "\tnop\n");					\
+  }									\
   fprintf (FILE, "\t.set\treorder\n");					\
   fprintf (FILE, "\t.set\tat\n");					\
 }

----
Rafal Boni                                                   rafal@mediaone.net


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]