From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 59287 invoked by alias); 10 Jul 2018 13:09:34 -0000 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 Received: (qmail 59277 invoked by uid 89); 10 Jul 2018 13:09:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.2 spammy=father, fathers, blow, our X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 10 Jul 2018 13:09:32 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 52DB8AD1B for ; Tue, 10 Jul 2018 13:09:30 +0000 (UTC) Date: Tue, 10 Jul 2018 13:09:00 -0000 From: Richard Biener To: gcc-patches@gcc.gnu.org Subject: [PATCH] Do less (redudant) constant propagation during unrolling Message-ID: User-Agent: Alpine 2.20 (LSU 67 2015-01-07) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-SW-Source: 2018-07/txt/msg00490.txt.bz2 The following avoids constant propagating both on a loop and its children. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. I'm going to remove the checking code I added before committing (and I will of course re-test). Richard. 2018-07-10 Richard Biener * tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely_1): Rework father_bb setting in a way to avoid propagating constants multiple times on a loop body. diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index c951f17f9ba..4f6080b339f 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -1378,20 +1378,53 @@ tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer, enum unroll_level ul; unsigned num = number_of_loops (cfun); + gcc_assert (bitmap_empty_p (father_bbs)); + /* Process inner loops first. Don't walk loops added by the recursive calls because SSA form is not up-to-date. They can be handled in the next iteration. */ + bitmap child_father_bbs = NULL; for (inner = loop->inner; inner != NULL; inner = inner->next) if ((unsigned) inner->num < num) - changed |= tree_unroll_loops_completely_1 (may_increase_size, - unroll_outer, father_bbs, - inner); + { + if (!child_father_bbs) + child_father_bbs = BITMAP_ALLOC (NULL); + if (tree_unroll_loops_completely_1 (may_increase_size, unroll_outer, + child_father_bbs, inner)) + { + bitmap_ior_into (father_bbs, child_father_bbs); + bitmap_clear (child_father_bbs); + changed = true; + } + } + if (child_father_bbs) + BITMAP_FREE (child_father_bbs); /* If we changed an inner loop we cannot process outer loops in this iteration because SSA form is not up-to-date. Continue with siblings of outer loops instead. */ if (changed) - return true; + { + /* If we are recorded as father clear all other fathers that + are necessarily covered already to avoid redundant work. */ + if (bitmap_bit_p (father_bbs, loop->header->index)) + { + if (flag_checking) + { + bitmap_iterator bi; + unsigned i; + EXECUTE_IF_SET_IN_BITMAP (father_bbs, 0, i, bi) + { + loop_p floop = BASIC_BLOCK_FOR_FN (cfun, i)->loop_father; + gcc_assert (floop == loop + || flow_loop_nested_p (loop, floop)); + } + } + bitmap_clear (father_bbs); + bitmap_set_bit (father_bbs, loop->header->index); + } + return true; + } /* Don't unroll #pragma omp simd loops until the vectorizer attempts to vectorize those. */ @@ -1421,7 +1454,23 @@ tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer, computations; otherwise, the size might blow up before the iteration is complete and the IR eventually cleaned up. */ if (loop_outer (loop_father)) - bitmap_set_bit (father_bbs, loop_father->header->index); + { + /* Once we process our father we will have processed + the fathers of our children as well, so avoid doing + redundant work and clear fathers we've gathered sofar. */ + if (flag_checking) + { + bitmap_iterator bi; + unsigned i; + EXECUTE_IF_SET_IN_BITMAP (father_bbs, 0, i, bi) + { + loop_p floop = BASIC_BLOCK_FOR_FN (cfun, i)->loop_father; + gcc_assert (flow_loop_nested_p (loop_father, floop)); + } + } + bitmap_clear (father_bbs); + bitmap_set_bit (father_bbs, loop_father->header->index); + } return true; }