This is the mail archive of the gcc-patches@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]

[PATCH, rtl]: Fix PR rtl-optimization/32450: Call to mcount clobbers registers


Hello!

As described in the PR, scheduler is free to move instructions above NOTE_INSN_PROLOGUE_END. However, this note also marks the place for the call to mcount() profiling function. As answered in glibc bugreport, mcount() saves only registers that are part of the call sequence.

In the testcase, CC producing insn is moved before NOTE_INSN_PROLOGUE_END, where CC receiver is left after the note. As mcount() clobbers flags, the flags are undefined after the call, and this leads to the failure.

Attached patch fixes this issue with a Big Hammer Approach. When profiling is on, "blockage" insn nails instructions down to where they should be, preventing them to escape past NOTE_INSN_PROLOGUE_END.

This is a regression from the point gcc started to emit RTL sequences for the prologue.

(BTW: It also changes one place that still used "gen_rtx_ASM_INPUT (VOIDmode, "")" for a scheduling barrier to gen_blockage().)

The patch was bootstrapped/regression tested on x86_64-pc-linux-gnu. OK for mainline and branches?

2007-07-05 Uros Bizjak <ubizjak@gmail.com>

PR rtl_optimization/32450
* function.c (thread_prologue_and_epilogue_insns): Emit blockage insn
to ensure that instructions are not moved into the prologue when
profiling is on. Remove unused prologue_end variable.
(expand_function_end): Emit blockage insn instead of ASM_INPUT rtx
as a scheduling barrier.


testsuite/ChangeLog:

2007-07-05 Uros Bizjak <ubizjak@gmail.com>

       PR rtl_optimization/32450
       * gcc.dg/pr32450.c: New runtime test.

Uros.

Index: gcc/testsuite/gcc.dg/pr32450.c
===================================================================
--- gcc/testsuite/gcc.dg/pr32450.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr32450.c	(revision 0)
@@ -0,0 +1,34 @@
+/* Contributed by Joost VandeVondele  <jv244@cam.ac.uk> */
+
+/* { dg-do run } */
+/* { dg-require-profiling "-pg" } */
+/* { dg-options "-O2 -pg" } */
+/* { dg-options "-O2 -pg -march=core2" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -pg -static" { target hppa*-*-hpux* } } */
+
+extern void abort (void);
+
+int stack_pointer;
+
+void
+__attribute__((noinline))
+mystop ()
+{
+  abort ();
+}
+
+void
+__attribute__((noinline))
+add ()
+{
+  if (stack_pointer + 1 > 10)
+    mystop ();
+
+  stack_pointer = stack_pointer + 1;
+}
+
+int main ()
+{
+  add ();
+  return stack_pointer - 1;
+}
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 126369)
+++ gcc/function.c	(working copy)
@@ -4515,11 +4515,10 @@ expand_function_end (void)
 
   /* @@@ This is a kludge.  We want to ensure that instructions that
      may trap are not moved into the epilogue by scheduling, because
-     we don't always emit unwind information for the epilogue.
-     However, not all machine descriptions define a blockage insn, so
-     emit an ASM_INPUT to act as one.  */
+     we don't always emit unwind information for the epilogue.  */
+
   if (! USING_SJLJ_EXCEPTIONS && flag_non_call_exceptions)
-    emit_insn (gen_rtx_ASM_INPUT (VOIDmode, ""));
+    emit_insn (gen_blockage ());
 
   /* If stack protection is enabled for this function, check the guard.  */
   if (cfun->stack_protect_guard)
@@ -5045,9 +5044,6 @@ thread_prologue_and_epilogue_insns (void
 #if defined (HAVE_sibcall_epilogue) || defined (HAVE_epilogue) || defined (HAVE_return) || defined (HAVE_prologue)
   rtx seq;
 #endif
-#ifdef HAVE_prologue
-  rtx prologue_end = NULL_RTX;
-#endif
 #if defined (HAVE_epilogue) || defined(HAVE_return)
   rtx epilogue_end = NULL_RTX;
 #endif
@@ -5067,7 +5063,14 @@ thread_prologue_and_epilogue_insns (void
 
       /* Retain a map of the prologue insns.  */
       record_insns (seq, &prologue);
-      prologue_end = emit_note (NOTE_INSN_PROLOGUE_END);
+      emit_note (NOTE_INSN_PROLOGUE_END);
+
+#ifndef PROFILE_BEFORE_PROLOGUE
+      /* Ensure that instructions are not moved into
+	 the prologue when profiling is on.  */
+      if (current_function_profile)
+	emit_insn (gen_blockage ());
+#endif
 
       seq = get_insns ();
       end_sequence ();

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