From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27768 invoked by alias); 21 Dec 2012 13:11:13 -0000 Received: (qmail 27695 invoked by uid 22791); 21 Dec 2012 13:11:12 -0000 X-SWARE-Spam-Status: No, hits=-5.4 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 21 Dec 2012 13:11:05 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 34C3CA52C5; Fri, 21 Dec 2012 14:11:04 +0100 (CET) Date: Fri, 21 Dec 2012 13:11:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Cc: polacek@redhat.com, ebotcazou@adacore.com Subject: [PATCH] Fix PR52966 - do not bypass loop headers Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-12/txt/msg01315.txt.bz2 This patch widens the scope of the PR54838 fix (and reverts one of my earlier kludges). Like on the GIMPLE level threading an edge through a loop header is seldomly a good idea as it may create multiple-entry loops (not handled at all), create irreducible regions (not handled at all). In theory threading the latch is possible (see the hoops tree-ssa-threadupdate.c jumps through). But instead of replicating all this on RTL the easiest thing is to simply not thread through loop headers when loops are to be preserved. It again unleashes the full powers before earlier patches when loops are not preserved (there is at least one rtl-cprop pass after rtl loop opts). Bootstrap and regtest pending on x86_64-unknown-linux-gnu. I've committed the testcase already as I wasn't able to reproduce the issue (had a local patch to fix it ...). Thanks, Richard. 2012-12-21 Richard Biener PR rtl-optimization/52996 * cprop.c (bypass_block): When loops are to be preserved do not bypass loop headers. Revert earlier kludge to remove loops when doing that. Index: gcc/cprop.c =================================================================== *** gcc/cprop.c (revision 194658) --- gcc/cprop.c (working copy) *************** bypass_block (basic_block bb, rtx setcc, *** 1496,1502 **** rtx insn, note; edge e, edest; int change; ! int may_be_loop_header; unsigned removed_p; unsigned i; edge_iterator ei; --- 1496,1502 ---- rtx insn, note; edge e, edest; int change; ! int may_be_loop_header = false; unsigned removed_p; unsigned i; edge_iterator ei; *************** bypass_block (basic_block bb, rtx setcc, *** 1510,1536 **** if (note) find_used_regs (&XEXP (note, 0), NULL); - /* Determine whether there are more latch edges. Threading through - a loop header with more than one latch is delicate, see e.g. - tree-ssa-threadupdate.c:thread_through_loop_header. */ if (current_loops) { ! may_be_loop_header = bb == bb->loop_father->header; ! if (may_be_loop_header ! && bb->loop_father->latch == NULL) return 0; } else { - unsigned n_back_edges = 0; FOR_EACH_EDGE (e, ei, bb->preds) if (e->flags & EDGE_DFS_BACK) ! n_back_edges++; ! ! may_be_loop_header = n_back_edges > 0; ! ! if (n_back_edges > 1) ! return 0; } change = 0; --- 1510,1531 ---- if (note) find_used_regs (&XEXP (note, 0), NULL); if (current_loops) { ! /* If we are to preserve loop structure then do not bypass ! a loop header. This will either rotate the loop, create ! multiple entry loops or even irreducible regions. */ ! if (bb == bb->loop_father->header) return 0; } else { FOR_EACH_EDGE (e, ei, bb->preds) if (e->flags & EDGE_DFS_BACK) ! { ! may_be_loop_header = true; ! break; ! } } change = 0; *************** bypass_block (basic_block bb, rtx setcc, *** 1619,1635 **** && dest != old_dest && dest != EXIT_BLOCK_PTR) { - if (current_loops != NULL - && e->src->loop_father->latch == e->src) - { - /* ??? Now we are creating (or may create) a loop - with multiple entries. Simply mark it for - removal. Alternatively we could not do this - threading. */ - e->src->loop_father->header = NULL; - e->src->loop_father->latch = NULL; - } - redirect_edge_and_branch_force (e, dest); /* Copy the register setter to the redirected edge. --- 1614,1619 ----