From patchwork Thu Apr 7 17:30:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Monakov X-Patchwork-Id: 90214 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E1B1BB6F01 for ; Fri, 8 Apr 2011 03:30:40 +1000 (EST) Received: (qmail 20950 invoked by alias); 7 Apr 2011 17:30:38 -0000 Received: (qmail 20941 invoked by uid 22791); 7 Apr 2011 17:30:37 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_JMF_BL, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp.ispras.ru (HELO smtp.ispras.ru) (83.149.198.202) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 07 Apr 2011 17:30:34 +0000 Received: from ispserv.ispras.ru (ispserv.ispras.ru [83.149.198.72]) by smtp.ispras.ru (Postfix) with ESMTP id 9A7705D404A; Thu, 7 Apr 2011 21:30:03 +0400 (MSD) Received: from monoid.intra.ispras.ru (winnie.ispras.ru [83.149.198.236]) by ispserv.ispras.ru (Postfix) with ESMTP id 6A4EC3FC48; Thu, 7 Apr 2011 21:30:32 +0400 (MSD) Date: Thu, 7 Apr 2011 21:30:31 +0400 (MSD) From: Alexander Monakov To: gcc-patches@gcc.gnu.org cc: "Vladimir N. Makarov" Subject: [PATCH] sel-sched: Don't clone CALLs (PR48273) Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, Selective scheduler does not explicitly forbid creating bookkeeping copies of CALLs, but an assert in create_copy_of_insn_rtx does not expect a CALL. Since there's little benefit from aggressive scheduling of CALLs, it makes sense to restrict it so that CALLs cannot be duplicated. This patch makes CALLs non-clonable by adding an explicit check in additional to other non-clonable insns (ASMs, instructions that are a part of SCHED_GROUPs, etc.). We also need to forbid pipelining of loops that have no exit edges, since our check for whether a motion would create bookkeeping does not work in that case (it's one of the solutions; the other is to fixup remove_insns_that_need_bookkeeping function, but this one is simpler and faster). PR target/48273 * cfgloop.h (loop_has_exit_edges): New helper. * sel-sched-ir.c (init_global_and_expr_for_insn): Make CALLs non-clonable. (sel_setup_region_sched_flags): Don't pipeline loops that have no exit edges. testsuite: * g++.dg/opt/pr48273.C: New. diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index f7bb134..0ff44de 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -443,6 +443,14 @@ loop_outer (const struct loop *loop) return VEC_index (loop_p, loop->superloops, n - 1); } +/* Returns true if LOOP has at least one exit edge. */ + +static inline bool +loop_has_exit_edges (const struct loop *loop) +{ + return loop->exits->next->e != NULL; +} + /* Returns the list of loops in current_loops. */ static inline VEC (loop_p, gc) * diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 67484dd..95c1431 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -2905,6 +2905,7 @@ init_global_and_expr_for_insn (insn_t insn) if (CANT_MOVE (insn) || INSN_ASM_P (insn) || SCHED_GROUP_P (insn) + || CALL_P (insn) /* Exception handling insns are always unique. */ || (cfun->can_throw_non_call_exceptions && can_throw_internal (insn)) /* TRAP_IF though have an INSN code is control_flow_insn_p (). */ diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 0e8173b..fb1a026 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -6781,7 +6781,8 @@ sel_setup_region_sched_flags (void) bookkeeping_p = 1; pipelining_p = (bookkeeping_p && (flag_sel_sched_pipelining != 0) - && current_loop_nest != NULL); + && current_loop_nest != NULL + && loop_has_exit_edges (current_loop_nest)); max_insns_to_rename = PARAM_VALUE (PARAM_SELSCHED_INSNS_TO_RENAME); max_ws = MAX_WS; } diff --git a/gcc/testsuite/g++.dg/opt/pr48273.C b/gcc/testsuite/g++.dg/opt/pr48273.C new file mode 100644 index 0000000..4c5108b --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr48273.C @@ -0,0 +1,10 @@ +// { dg-do compile { target x86_64-*-* } } +// { dg-options "-fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -funroll-all-loops -march=core2" } + +void bar (); + +void foo () +{ + for (;;) + bar (); +}