From patchwork Tue Oct 9 13:12:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 190296 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 0C3F72C00AC for ; Wed, 10 Oct 2012 00:12:22 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1350393143; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=En/Yh2WnhL0VqzWdm6Oi aqKnRQY=; b=XHHPQaEPvQe3wlOJlRJqbkvSpUN9BqZ3VqGa6Ez7rtahPLnQ56Y3 YXoohJ+73OHAgpjd07PmfRjPBL0fqxCVSMucKjdbvHLKohtU1YA8FbxrpGnuqbfe ZWXiLQwIltMOC9Q1HHh0y3xU69bLQei6YrNPd8WScFn3h7x0Tqa5coE= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Cc:Subject:Message-ID:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=UkbTfT4RwGxejtXzicKMoZFTOcFrsIjSa9NHkGKx1iKrL9UpcX5XJMX0ex8J03 UvNFlGeoSZSnWYfRSrwwfNs1/TDSQs3KpQ3vL18+vd2ALw4dA6wXNY+20jTk3fbU YOk10Z0MboSMwhrudUZ2dqaIKFOC189oCk65E+AGW44pc=; Received: (qmail 3669 invoked by alias); 9 Oct 2012 13:12:11 -0000 Received: (qmail 3530 invoked by uid 22791); 9 Oct 2012 13:12:09 -0000 X-SWARE-Spam-Status: No, hits=-4.9 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 09 Oct 2012 13:12:02 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 116C7543508; Tue, 9 Oct 2012 15:12:00 +0200 (CEST) Date: Tue, 9 Oct 2012 15:12:00 +0200 From: Jan Hubicka To: Jan Hubicka Cc: gcc-patches@gcc.gnu.org Subject: Re: Fix my change to unroll_loop_constant_iterations Message-ID: <20121009131200.GA20979@kam.mff.cuni.cz> References: <20121009083115.GA32592@kam.mff.cuni.cz> <20121009093659.GA14364@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20121009093659.GA14364@kam.mff.cuni.cz> User-Agent: Mutt/1.5.20 (2009-06-14) 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, this is patch I comitted after checking, double checking and tripple checking. I tested the patch on x86_64-linux. Unfortunately -O3 -fpeel-loops -funroll-loops bootstrap still fails for me (-O3 bootstrap works), but it seems independent problem - i.e. it fails with the change reverted, too. I am looking into it now. I apologize for the breakage, I got completely sidetracked with the double_int changes since I sort of missed the point that double_int has not signed nor unsigned. The patch fixes existing bug in overflow while computing iterations + 1 in peeling decision. This exists on quite few releases and can trigger pointless peeling of loops that iterate HOST_WIDE_INT_MAX times. Honza * loop-unroll.c (unroll_loop_constant_iterations): Add update of loop->nb_iterations_upper_bound I missed in my previous commit; use TRUNC_DIV_EXPR instead of FLOOR_DIV_EXPR to divide iteration count. (decide_unroll_runtime_iterations): Avoid overflow. (unroll_loop_runtime_iterations): Use TRUNC_DIV_EXPR instead of FLOOR_DIV_EXPR to update iteration bounds. (decide_peel_simple): Avoid integer overflow when deciding on number of peelings. (decide_unroll_stupid): Likewise. Index: loop-unroll.c =================================================================== --- loop-unroll.c (revision 192240) +++ loop-unroll.c (working copy) @@ -740,6 +740,7 @@ unroll_loop_constant_iterations (struct apply_opt_in_copies (opt_info, exit_mod + 1, false, false); desc->niter -= exit_mod + 1; + loop->nb_iterations_upper_bound -= double_int::from_uhwi (exit_mod + 1); if (loop->any_estimate && double_int::from_uhwi (exit_mod + 1).ule (loop->nb_iterations_estimate)) @@ -795,14 +796,14 @@ unroll_loop_constant_iterations (struct desc->niter /= max_unroll + 1; loop->nb_iterations_upper_bound - = loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi (exit_mod + = loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi (max_unroll + 1), - FLOOR_DIV_EXPR); + TRUNC_DIV_EXPR); if (loop->any_estimate) loop->nb_iterations_estimate - = loop->nb_iterations_estimate.udiv (double_int::from_uhwi (exit_mod + = loop->nb_iterations_estimate.udiv (double_int::from_uhwi (max_unroll + 1), - FLOOR_DIV_EXPR); + TRUNC_DIV_EXPR); desc->niter_expr = GEN_INT (desc->niter); /* Remove the edges. */ @@ -876,11 +877,10 @@ decide_unroll_runtime_iterations (struct return; } - /* If we have profile feedback, check whether the loop rolls. */ + /* Check whether the loop rolls. */ if ((estimated_loop_iterations (loop, &iterations) || max_loop_iterations (loop, &iterations)) - && iterations.fits_shwi () - && iterations.to_shwi () <= 2 * nunroll) + && iterations.ult (double_int::from_shwi (2 * nunroll))) { if (dump_file) fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n"); @@ -1199,12 +1199,12 @@ unroll_loop_runtime_iterations (struct l loop->nb_iterations_upper_bound = loop->nb_iterations_upper_bound.udiv (double_int::from_uhwi (max_unroll + 1), - FLOOR_DIV_EXPR); + TRUNC_DIV_EXPR); if (loop->any_estimate) loop->nb_iterations_estimate = loop->nb_iterations_estimate.udiv (double_int::from_uhwi (max_unroll + 1), - FLOOR_DIV_EXPR); + TRUNC_DIV_EXPR); if (exit_at_end) { desc->niter_expr = @@ -1280,8 +1280,7 @@ decide_peel_simple (struct loop *loop, i /* If we have realistic estimate on number of iterations, use it. */ if (estimated_loop_iterations (loop, &iterations)) { - if (!iterations.fits_shwi () - || iterations.to_shwi () + 1 > npeel) + if (double_int::from_shwi (npeel).ule (iterations)) { if (dump_file) { @@ -1298,8 +1297,7 @@ decide_peel_simple (struct loop *loop, i /* If we have small enough bound on iterations, we can still peel (completely unroll). */ else if (max_loop_iterations (loop, &iterations) - && iterations.fits_shwi () - && iterations.to_shwi () + 1 <= npeel) + && iterations.ult (double_int::from_shwi (npeel))) npeel = iterations.to_shwi () + 1; else { @@ -1446,11 +1444,10 @@ decide_unroll_stupid (struct loop *loop, return; } - /* If we have profile feedback, check whether the loop rolls. */ + /* Check whether the loop rolls. */ if ((estimated_loop_iterations (loop, &iterations) || max_loop_iterations (loop, &iterations)) - && iterations.fits_shwi () - && iterations.to_shwi () <= 2 * nunroll) + && iterations.ult (double_int::from_shwi (2 * nunroll))) { if (dump_file) fprintf (dump_file, ";; Not unrolling loop, doesn't roll\n");