diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 17a2edf1b0b..b36c3803491 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2007-07-06 Uros Bizjak + + 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. + 2007-07-06 Alexandre Oliva PR debug/23551 diff --git a/gcc/function.c b/gcc/function.c index a01bd9367bb..1477b6a3bd8 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4515,11 +4515,9 @@ 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 +5043,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 +5062,15 @@ 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. The call to the profiling routine can be + emitted within the live range of a call-clobbered register. */ + if (current_function_profile) + emit_insn (gen_blockage ()); +#endif seq = get_insns (); end_sequence (); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aa5d7ac772a..3772aff6f9c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-07-06 Uros Bizjak + + PR rtl_optimization/32450 + * gcc.dg/pr32450.c: New runtime test. + 2007-07-06 Uros Bizjak * g++.dg/ext/visibility/ms-compat-1.C: Change double underscore to diff --git a/gcc/testsuite/gcc.dg/pr32450.c b/gcc/testsuite/gcc.dg/pr32450.c new file mode 100644 index 00000000000..4a1842e9b84 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr32450.c @@ -0,0 +1,34 @@ +/* Contributed by Joost VandeVondele */ + +/* { dg-do run } */ +/* { dg-require-profiling "-pg" } */ +/* { dg-options "-O2 -pg" } */ +/* { dg-options "-O2 -pg -mtune=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; +}