This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH/mips] Re: profiling using _mcount in gcc
- To: Venkatesh Tanjore <VenkateshT at ishoni dot com>
- Subject: [PATCH/mips] Re: profiling using _mcount in gcc
- From: Daniel Jacobowitz <drow at mvista dot com>
- Date: Fri, 12 Oct 2001 14:48:18 -0400
- Cc: "'gcc at gcc dot gnu dot org'" <gcc at gcc dot gnu dot org>, gcc-patches at gcc dot gnu dot org
- References: <AEBCF149D99ED5118F1C0002A519EA300EFAB9@leonoid.in.ishoni.com>
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