From patchwork Wed Nov 10 17:26:25 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Monakov X-Patchwork-Id: 70787 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 D77E0B7122 for ; Thu, 11 Nov 2010 21:07:37 +1100 (EST) Received: (qmail 22113 invoked by alias); 11 Nov 2010 10:07:35 -0000 Received: (qmail 22101 invoked by uid 22791); 11 Nov 2010 10:07:34 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL, BAYES_00, DATE_IN_PAST_12_24, FSL_RU_URL, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp.ispras.ru (HELO smtp.ispras.ru) (83.149.198.201) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 11 Nov 2010 10:07:28 +0000 Received: from ispserv.ispras.ru (ispserv.ispras.ru [83.149.198.72]) by smtp.ispras.ru (Postfix) with ESMTP id 719225D4102; Thu, 11 Nov 2010 13:03:47 +0300 (MSK) Received: from monoid.intra.ispras.ru (winnie.ispras.ru [83.149.198.236]) by ispserv.ispras.ru (Postfix) with ESMTP id 90FE23FD3E; Wed, 10 Nov 2010 20:26:25 +0300 (MSK) Date: Wed, 10 Nov 2010 20:26:25 +0300 (MSK) From: Alexander Monakov To: gcc-patches@gcc.gnu.org cc: "Vladimir N. Makarov" , Andrey Belevantsev Subject: [PR46204] sel-sched: delete empty BBs more carefully 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 Hello, When deleting an empty basic block, we redirect all incoming non-fallthrough edges to its successor. However, we must also take care of the incoming fallthrough edge if the preceding basic block ends with a conditional jump to the next instruction (otherwise, by deleting the empty basic block we can remove the label that the jump refers to). Fixed in maybe_tidy_empty_bb by trying to remove the jump or redirecting it to the successor of the empty block. The patch also removes recomputing of topological order in that function. We can not invalidate it by moving an edge destination along an existing edge. I have tried to add the corresponding assert, but it would be quite verbose, since the fallthrough edge may be a back edge, in which case it will look like we are invalidating toporder, even though we are legally creating a new back edge in the region, and will delete the old back edge soon (we can create multiple back edges that way, but we'd only care when pipelining, and we wouldn't have a fallthrough back edge then). Bootstrapped and regtested on ia64 with sel-sched enabled at -O2, also tested on x86-64 with sel-sched enabled for bootstrap. OK? 2010-11-10 Alexander Monakov PR rtl-optimization/46204 * sel-sched-ir.c (maybe_tidy_empty_bb): Remove second argument. Update all callers. Do not recompute topological order. Adjust fallthrough edges following a degenerate conditional jump. diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 141c935..e169276 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -3562,7 +3562,7 @@ sel_recompute_toporder (void) /* Tidy the possibly empty block BB. */ static bool -maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p) +maybe_tidy_empty_bb (basic_block bb) { basic_block succ_bb, pred_bb; edge e; @@ -3612,10 +3612,29 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p) if (!(e->flags & EDGE_FALLTHRU)) { - recompute_toporder_p |= sel_redirect_edge_and_branch (e, succ_bb); + /* We can not invalidate computed topological order by moving + the edge destination block (E->SUCC) along a fallthru edge. */ + sel_redirect_edge_and_branch (e, succ_bb); rescan_p = true; break; } + /* If the edge is fallthru, but PRED_BB ends in a conditional jump + to BB (so there is no non-fallthru edge from PRED_BB to BB), we + still have to adjust it. */ + else if (single_succ_p (pred_bb) && any_condjump_p (BB_END (pred_bb))) + { + /* If possible, try to remove the unneeded conditional jump. */ + if (INSN_SCHED_TIMES (BB_END (pred_bb)) == 0 + && !IN_CURRENT_FENCE_P (BB_END (pred_bb))) + { + if (!sel_remove_insn (BB_END (pred_bb), false, false)) + tidy_fallthru_edge (e); + } + else + sel_redirect_edge_and_branch (e, succ_bb); + rescan_p = true; + break; + } } } @@ -3631,9 +3650,6 @@ maybe_tidy_empty_bb (basic_block bb, bool recompute_toporder_p) remove_empty_bb (bb, true); } - if (recompute_toporder_p) - sel_recompute_toporder (); - #ifdef ENABLE_CHECKING verify_backedges (); #endif @@ -3651,7 +3667,7 @@ tidy_control_flow (basic_block xbb, bool full_tidying) insn_t first, last; /* First check whether XBB is empty. */ - changed = maybe_tidy_empty_bb (xbb, false); + changed = maybe_tidy_empty_bb (xbb); if (changed || !full_tidying) return changed; @@ -3715,8 +3731,8 @@ tidy_control_flow (basic_block xbb, bool full_tidying) that contained that jump, becomes empty too. In such case remove it too. */ if (sel_bb_empty_p (xbb->prev_bb)) - changed = maybe_tidy_empty_bb (xbb->prev_bb, recompute_toporder_p); - else if (recompute_toporder_p) + changed = maybe_tidy_empty_bb (xbb->prev_bb); + if (recompute_toporder_p) sel_recompute_toporder (); } return changed; @@ -3733,7 +3749,7 @@ purge_empty_blocks (void) { basic_block b = BASIC_BLOCK (BB_TO_BLOCK (i)); - if (maybe_tidy_empty_bb (b, false)) + if (maybe_tidy_empty_bb (b)) continue; i++;