From patchwork Wed Nov 24 17:28:37 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [PR46585] sel-sched: use an unrecognizable pattern for local NOPs Date: Wed, 24 Nov 2010 07:28:37 -0000 From: Alexander Monakov X-Patchwork-Id: 72923 Message-Id: To: gcc-patches@gcc.gnu.org Cc: "Vladimir N. Makarov" Hi, Selective scheduler uses NOPs as temporary placeholders for recently removed insns. It does not expect them to be present as "normal" insns, but that happens in the testcase with -O0 -fno-dce. Fortunately, we can just pick an unrecognizable pattern for a local NOP. The patch implements that. Bootstrapped and regtested on x86_64-linux, bootstrapped on ia64 with sel-sched at -O2 and regtest there is in progress. 2010-11-24 Alexander Monakov PR rtl-optimization/46585 * sel-sched-ir.c (return_regset_to_pool): Verify that RS is not NULL. (vinsn_init): Skip DF initialization for local NOPs. (vinsn_delete): Don't try to free regsets for local NOPs. (setup_nop_and_exit_insns): Change definition of nop_pattern. testsuite: * gcc.dg/pr46585.c: New. diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 71c02c4..e6e8d44 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -942,6 +942,7 @@ get_clear_regset_from_pool (void) void return_regset_to_pool (regset rs) { + gcc_assert (rs); regset_pool.diff--; if (regset_pool.n == regset_pool.s) @@ -1175,6 +1176,9 @@ vinsn_init (vinsn_t vi, insn_t insn, bool force_unique_p) VINSN_COUNT (vi) = 0; vi->cost = -1; + if (INSN_NOP_P (insn)) + return; + if (DF_INSN_UID_SAFE_GET (INSN_UID (insn)) != NULL) init_id_from_df (VINSN_ID (vi), insn, force_unique_p); else @@ -1256,9 +1260,12 @@ vinsn_delete (vinsn_t vi) { gcc_assert (VINSN_COUNT (vi) == 0); - return_regset_to_pool (VINSN_REG_SETS (vi)); - return_regset_to_pool (VINSN_REG_USES (vi)); - return_regset_to_pool (VINSN_REG_CLOBBERS (vi)); + if (!INSN_NOP_P (VINSN_INSN_RTX (vi))) + { + return_regset_to_pool (VINSN_REG_SETS (vi)); + return_regset_to_pool (VINSN_REG_USES (vi)); + return_regset_to_pool (VINSN_REG_CLOBBERS (vi)); + } free (vi); } @@ -5606,7 +5614,7 @@ setup_nop_and_exit_insns (void) gcc_assert (nop_pattern == NULL_RTX && exit_insn == NULL_RTX); - nop_pattern = gen_nop (); + nop_pattern = constm1_rtx; start_sequence (); emit_insn (nop_pattern); diff --git a/gcc/testsuite/gcc.dg/pr46585.c b/gcc/testsuite/gcc.dg/pr46585.c index e69de29..32befdf 100644 --- a/gcc/testsuite/gcc.dg/pr46585.c +++ b/gcc/testsuite/gcc.dg/pr46585.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target powerpc*-*-* ia64-*-* i?86-*-* x86_64-*-* } } */ +/* { dg-options "-fno-dce -fschedule-insns -fselective-scheduling" } */ +void +foo (void) +{ + switch (0) + { + default: + break; + } +}