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]

[PATCH/mips] Re: profiling using _mcount in gcc


On Fri, Oct 12, 2001 at 09:40:17PM +0530, Venkatesh Tanjore wrote:
> Hi
> 
> I am trying to do some profiling on a MIPS based embedded system using the
> gcc's -pg option using the Tornado 2.0 devlopment environment. I compile a
> file with the -pg option to profile all the functions inside that particular
> file. I have implemented a _mcount() fnction which the compiler will call...
> The strange thing is that the compiler generates two sets of assembly code
> for two sets of functions..
> 
> COnsider a function foo() which does not have calls to any other function
> except the compiler inserted _mcount() function call. 
> The assembly code looks something like this..
> 
> 8081c76c:  addiu        sp,sp,-8           
> 8081c770:  sw           s8,0(sp)           
> 8081c774:  move         s8,sp              
> 8081c778:  move         at,ra              
> 8081c77c:  jal          0x8080a408          # _mcount
> 8081c780:  addiu        sp,sp,-8           
> 8081c784:  sw           a0,8(s8)           
> 8081c788:  sw           a1,12(s8)          
> 
> Here the return address is not stored in the stack . Its only stored in the
> at register. But whicl ereturning from this function the return address is
> not obtained from the at register. Instaed it returns by just doing jr $ra.
> This results in a loop since the return address is ra is not the correct one
> when this function foo() has to return. 

The problem here is that _mcount() is not a normal function.  It does
not obey the calling conventions of a normal function.  It takes its
arguments in $at and $ra, and it is required to preserve $ra - and most
other registers, in fact, if I remember correctly.  The arguments have
not yet been saved.  You need to do this.

You'll also encounter problems with the stack push/pop done, if you are
on a PIC system where jal expands into a GP reference.

I am fairly sure I posted the necessary GCC patches before to make this
work for MIPS/Linux.  If not, they're attached.  You may need to make
similar changes.  You'll also need to be careful with saving/restoring
registers in _mcount.

MIPS maintainers, how do these look?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2001-10-12  Daniel Jacobowitz  <drow@mvista.com>

	* config/mips/mips.h (FUNCTION_PROFILER): Do not place stack
	adjust in jal's delay slot.
	* config/mips/linux.h: Undefine ASM_OUTPUT_REG_PUSH,
	ASM_OUTPUT_REG_POP.

diff -u gcc-3.0.orig/gcc/config/mips/mips.h gcc-3.0/gcc/config/mips/mips.h
--- gcc-3.0.orig/gcc/config/mips/mips.h	Thu Jun 14 13:42:18 2001
+++ gcc-3.0/gcc/config/mips/mips.h	Wed Aug 15 10:57:26 2001
@@ -2590,18 +2590,16 @@
 {									\
   if (TARGET_MIPS16)							\
     sorry ("mips16 function profiling");				\
-  fprintf (FILE, "\t.set\tnoreorder\n");				\
   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, "\t.set\treorder\n");					\
+  fprintf (FILE, "\tjal\t_mcount\n");					\
   fprintf (FILE, "\t.set\tat\n");					\
 }
 
diff -u gcc-3.0.1.orig/gcc/config/mips/linux.h gcc-3.0.1/gcc/config/mips/linux.h
--- gcc-3.0.1.orig/gcc/config/mips/linux.h	Mon Aug 20 10:33:49 2001
+++ gcc-3.0.1/gcc/config/mips/linux.h	Mon Aug 20 10:34:18 2001
@@ -257,3 +257,8 @@
 #undef ASM_OUTPUT_IDENT
 #define ASM_OUTPUT_IDENT(FILE, NAME) \
   fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME);
+
+/* The glibc _mcount stub will save $v0 for us.  Don't mess with saving
+   it.  */
+#undef ASM_OUTPUT_REG_PUSH
+#undef ASM_OUTPUT_REG_POP


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