From: Richard Henderson Date: Fri, 12 Aug 2011 21:00:00 +0000 (-0700) Subject: re PR rtl-optimization/49994 (ICE: in maybe_record_trace_start, at dwarf2cfi.c:2234... X-Git-Tag: releases/gcc-4.7.0~4468 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7b4ef66246ab45928f337bde3d509a28352ebfb1;p=thirdparty%2Fgcc.git re PR rtl-optimization/49994 (ICE: in maybe_record_trace_start, at dwarf2cfi.c:2234 with -fsched2-use-superblocks) PR rtl-opt/49994 * sched-init.h (struct deps_desc): Add sched_before_next_jump. * sched-deps.c (init_deps): Clear it. (deps_analyze_insn): Consume it. (sched_analyze_insn): Fill it. From-SVN: r177721 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 91d3f180fcce..3aa3a5d7a386 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-08-12 Richard Henderson + + PR rtl-opt/49994 + * sched-init.h (struct deps_desc): Add sched_before_next_jump. + * sched-deps.c (init_deps): Clear it. + (deps_analyze_insn): Consume it. + (sched_analyze_insn): Fill it. + 2011-08-12 Ramana Radhakrishnan PR target/48328 diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 2961ccab2f46..ed592c8278a2 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -2696,6 +2696,18 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn) add_dependence_list (insn, deps->last_function_call_may_noreturn, 1, REG_DEP_ANTI); + /* We must avoid creating a situation in which two successors of the + current block have different unwind info after scheduling. If at any + point the two paths re-join this leads to incorrect unwind info. */ + /* ??? There are certain situations involving a forced frame pointer in + which, with extra effort, we could fix up the unwind info at a later + CFG join. However, it seems better to notice these cases earlier + during prologue generation and avoid marking the frame pointer setup + as frame-related at all. */ + if (RTX_FRAME_RELATED_P (insn)) + deps->sched_before_next_jump + = alloc_INSN_LIST (insn, deps->sched_before_next_jump); + if (code == COND_EXEC) { sched_analyze_2 (deps, COND_EXEC_TEST (x), insn); @@ -3302,12 +3314,11 @@ deps_analyze_insn (struct deps_desc *deps, rtx insn) if (NONDEBUG_INSN_P (insn)) sched_get_condition_with_rev (insn, NULL); - if (NONJUMP_INSN_P (insn) || DEBUG_INSN_P (insn) || JUMP_P (insn)) + if (JUMP_P (insn)) { /* Make each JUMP_INSN (but not a speculative check) a scheduling barrier for memory references. */ if (!deps->readonly - && JUMP_P (insn) && !(sel_sched_p () && sel_insn_is_speculation_check (insn))) { @@ -3326,6 +3337,15 @@ deps_analyze_insn (struct deps_desc *deps, rtx insn) } } + /* For each insn which shouldn't cross a jump, add a dependence. */ + add_dependence_list_and_free (deps, insn, + &deps->sched_before_next_jump, 1, + REG_DEP_ANTI); + + sched_analyze_insn (deps, PATTERN (insn), insn); + } + else if (NONJUMP_INSN_P (insn) || DEBUG_INSN_P (insn)) + { sched_analyze_insn (deps, PATTERN (insn), insn); } else if (CALL_P (insn)) @@ -3571,6 +3591,7 @@ init_deps (struct deps_desc *deps, bool lazy_reg_last) deps->last_function_call = 0; deps->last_function_call_may_noreturn = 0; deps->sched_before_next_call = 0; + deps->sched_before_next_jump = 0; deps->in_post_call_group_p = not_post_call; deps->last_debug_insn = 0; deps->last_reg_pending_barrier = NOT_A_BARRIER; diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 1e5c71e4e714..6797397b9bba 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -496,6 +496,9 @@ struct deps_desc scheduling is done. */ rtx sched_before_next_call; + /* Similarly, a list of insns which should not cross a branch. */ + rtx sched_before_next_jump; + /* Used to keep post-call pseudo/hard reg movements together with the call. */ enum post_call_group in_post_call_group_p; diff --git a/gcc/testsuite/gcc.dg/pr49994-1.c b/gcc/testsuite/gcc.dg/pr49994-1.c new file mode 100644 index 000000000000..902466110a57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr49994-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -fsched2-use-superblocks -g" } */ + +void x (int a) +{ + __label__ xlab; + void y (int b) + { + switch (b) + { + case 1: + goto xlab; + case 2: + goto xlab; + } + } + y (a); +xlab:; +} diff --git a/gcc/testsuite/gcc.dg/pr49994-2.c b/gcc/testsuite/gcc.dg/pr49994-2.c new file mode 100644 index 000000000000..92764fe61566 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr49994-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fno-omit-frame-pointer -fschedule-insns2 -fsched2-use-superblocks -g" } */ + +int +bar (int i) +{ + while (i) + if (i) + return i; +} + +void +foo () +{ + bar (0); +} diff --git a/gcc/testsuite/gcc.dg/pr49994-3.c b/gcc/testsuite/gcc.dg/pr49994-3.c new file mode 100644 index 000000000000..874db966653c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr49994-3.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fsched2-use-superblocks -g" } */ + +void * +foo (int offset) +{ + switch (offset) + { + case 0: + return __builtin_return_address (0); + case 1: + return __builtin_return_address (1); + case 2: + return __builtin_return_address (2); + case 3: + return __builtin_return_address (3); + case 4: + return __builtin_return_address (4); + } + return 0; +}