From patchwork Mon Dec 11 21:10:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 847227 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-468947-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="heKJnnb7"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3ywbGl4Fg8z9sxR for ; Tue, 12 Dec 2017 08:11:11 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=RnVJ6jJO/YbM8KA8g++EtNN15sxAL kNH+IBmLX6jCglxAex5gxH+wewnEuWcdJegieWpdos/rxzHRsHQN+vbZ0ypahMhy kDGAsv8FcL86ryujn7KoMy7JxOu1D+VREPOwvuI84hcnUcGpk76BBbdquZl8jlmj U0sc4RUPf57Ivw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=WF3KAxDws48GWNRR7UtyRwuP/8Q=; b=heK Jnnb7S4xiUXGJjKwd6fey9BdI7I8shpSeaj4DiVkgQleF7RQx+0fc+sOwLRHCRJb jUBg7ZMK7KTqS2OFRygL7FKgrQmwU4ktiRs4ZNQgnPXkaOLSkwYq2jZLTQlTILwj Ts7pJxSY8xBfFQRGiIqgTnaURIufVB6PeFXlC9BE= Received: (qmail 83780 invoked by alias); 11 Dec 2017 21:11:01 -0000 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 Received: (qmail 83762 invoked by uid 89); 11 Dec 2017 21:11:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.9 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 11 Dec 2017 21:10:58 +0000 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7912385540; Mon, 11 Dec 2017 21:10:57 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-116-34.ams2.redhat.com [10.36.116.34]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1DE736064B; Mon, 11 Dec 2017 21:10:56 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id vBBLAr5p001873; Mon, 11 Dec 2017 22:10:54 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id vBBLApmf001872; Mon, 11 Dec 2017 22:10:51 +0100 Date: Mon, 11 Dec 2017 22:10:51 +0100 From: Jakub Jelinek To: Richard Biener Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] Handle LOOP_DIST_ALIAS ifns in move_sese_region_to_fn (PR tree-optimization/83359) Message-ID: <20171211211051.GR2353@tucnak> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) X-IsSubscribed: yes Hi! Unlike LOOP_VECTORIZED ifns, LOOP_DIST_ALIAS is added by the ldist pass and needs to be maintained until the vectorizer, and parloops in between that. Earlier I've added code to update or drop orig_loop_num during move_sese_region_to_fn, but that is not sufficient. If we move the whole pair of loops with the associated LOOP_DIST_ALIAS call into the outlined loopfn, we need to update the first argument, as orig_loop_num is likely changing. If the whole triplet (two loops with orig_loop_num and LOOP_DIST_ALIAS with the same first argument) stays in parent function, we don't need to adjust it. In all other cases, this patch folds the LOOP_DIST_ALIAS ifn to the second argument, like the vectorizer does if it fails to vectorize it. Bootstrapped/regtested on x86_64-linux, i686-linux, powerpc64le-linux, bootstrapped on powerpc64-linux, regtest there pending. Ok for trunk? 2017-12-11 Jakub Jelinek PR tree-optimization/83359 * tree-cfg.h (fold_loop_internal_call): Declare. * tree-vectorizer.c (fold_loop_internal_call): Moved to ... * tree-cfg.c (fold_loop_internal_call): ... here. No longer static. (find_loop_dist_alias): New function. (move_sese_region_to_fn): If any dloop->orig_loop_num value is updated, also adjust any corresponding LOOP_DIST_ALIAS internal calls. * gcc.dg/graphite/pr83359.c: New test. Jakub --- gcc/tree-cfg.h.jj 2017-09-05 23:28:14.000000000 +0200 +++ gcc/tree-cfg.h 2017-12-11 12:35:24.284777550 +0100 @@ -77,6 +77,7 @@ extern void gather_blocks_in_sese_region vec *bbs_p); extern void verify_sese (basic_block, basic_block, vec *); extern bool gather_ssa_name_hash_map_from (tree const &, tree const &, void *); +extern void fold_loop_internal_call (gimple *, tree); extern basic_block move_sese_region_to_fn (struct function *, basic_block, basic_block, tree); extern void dump_function_to_file (tree, FILE *, dump_flags_t); --- gcc/tree-vectorizer.c.jj 2017-09-01 09:26:37.000000000 +0200 +++ gcc/tree-vectorizer.c 2017-12-11 12:33:41.436055580 +0100 @@ -464,27 +464,6 @@ vect_loop_vectorized_call (struct loop * return NULL; } -/* Fold loop internal call G like IFN_LOOP_VECTORIZED/IFN_LOOP_DIST_ALIAS - to VALUE and update any immediate uses of it's LHS. */ - -static void -fold_loop_internal_call (gimple *g, tree value) -{ - tree lhs = gimple_call_lhs (g); - use_operand_p use_p; - imm_use_iterator iter; - gimple *use_stmt; - gimple_stmt_iterator gsi = gsi_for_stmt (g); - - update_call_from_tree (&gsi, value); - FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs) - { - FOR_EACH_IMM_USE_ON_STMT (use_p, iter) - SET_USE (use_p, value); - update_stmt (use_stmt); - } -} - /* If LOOP has been versioned during loop distribution, return the gurading internal call. */ --- gcc/tree-cfg.c.jj 2017-12-07 18:05:30.000000000 +0100 +++ gcc/tree-cfg.c 2017-12-11 12:34:55.054140750 +0100 @@ -7337,6 +7337,47 @@ gather_ssa_name_hash_map_from (tree cons return true; } +/* Return LOOP_DIST_ALIAS call if present in BB. */ + +static gimple * +find_loop_dist_alias (basic_block bb) +{ + gimple *g = last_stmt (bb); + if (g == NULL || gimple_code (g) != GIMPLE_COND) + return NULL; + + gimple_stmt_iterator gsi = gsi_for_stmt (g); + gsi_prev (&gsi); + if (gsi_end_p (gsi)) + return NULL; + + g = gsi_stmt (gsi); + if (gimple_call_internal_p (g, IFN_LOOP_DIST_ALIAS)) + return g; + return NULL; +} + +/* Fold loop internal call G like IFN_LOOP_VECTORIZED/IFN_LOOP_DIST_ALIAS + to VALUE and update any immediate uses of it's LHS. */ + +void +fold_loop_internal_call (gimple *g, tree value) +{ + tree lhs = gimple_call_lhs (g); + use_operand_p use_p; + imm_use_iterator iter; + gimple *use_stmt; + gimple_stmt_iterator gsi = gsi_for_stmt (g); + + update_call_from_tree (&gsi, value); + FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs) + { + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, value); + update_stmt (use_stmt); + } +} + /* Move a single-entry, single-exit region delimited by ENTRY_BB and EXIT_BB to function DEST_CFUN. The whole region is replaced by a single basic block in the original CFG and the new basic block is @@ -7510,7 +7551,6 @@ move_sese_region_to_fn (struct function } } - /* Adjust the number of blocks in the tree root of the outlined part. */ get_loop (dest_cfun, 0)->num_nodes = bbs.length () + 2; @@ -7521,19 +7561,77 @@ move_sese_region_to_fn (struct function /* Fix up orig_loop_num. If the block referenced in it has been moved to dest_cfun, update orig_loop_num field, otherwise clear it. */ struct loop *dloop; + signed char *moved_orig_loop_num = NULL; FOR_EACH_LOOP_FN (dest_cfun, dloop, 0) if (dloop->orig_loop_num) { + if (moved_orig_loop_num == NULL) + moved_orig_loop_num + = XCNEWVEC (signed char, vec_safe_length (larray)); if ((*larray)[dloop->orig_loop_num] != NULL && get_loop (saved_cfun, dloop->orig_loop_num) == NULL) - dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num; + { + if (moved_orig_loop_num[dloop->orig_loop_num] >= 0 + && moved_orig_loop_num[dloop->orig_loop_num] < 2) + moved_orig_loop_num[dloop->orig_loop_num]++; + dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num; + } else - dloop->orig_loop_num = 0; + { + moved_orig_loop_num[dloop->orig_loop_num] = -1; + dloop->orig_loop_num = 0; + } } - ggc_free (larray); - pop_cfun (); + if (moved_orig_loop_num) + { + FOR_EACH_VEC_ELT (bbs, i, bb) + { + gimple *g = find_loop_dist_alias (bb); + if (g == NULL) + continue; + + int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0)); + gcc_assert (orig_loop_num + && (unsigned) orig_loop_num < vec_safe_length (larray)); + if (moved_orig_loop_num[orig_loop_num] == 2) + { + /* If we have moved both loops with this orig_loop_num into + dest_cfun and the LOOP_DIST_ALIAS call is being moved there + too, update the first argument. */ + gcc_assert ((*larray)[dloop->orig_loop_num] != NULL + && (get_loop (saved_cfun, dloop->orig_loop_num) + == NULL)); + tree t = build_int_cst (integer_type_node, + (*larray)[dloop->orig_loop_num]->num); + gimple_call_set_arg (g, 0, t); + update_stmt (g); + /* Make sure the following loop will not update it. */ + moved_orig_loop_num[orig_loop_num] = 0; + } + else + /* Otherwise at least one of the loops stayed in saved_cfun. + Remove the LOOP_DIST_ALIAS call. */ + fold_loop_internal_call (g, gimple_call_arg (g, 1)); + } + FOR_EACH_BB_FN (bb, saved_cfun) + { + gimple *g = find_loop_dist_alias (bb); + if (g == NULL) + continue; + int orig_loop_num = tree_to_shwi (gimple_call_arg (g, 0)); + gcc_assert (orig_loop_num + && (unsigned) orig_loop_num < vec_safe_length (larray)); + if (moved_orig_loop_num[orig_loop_num]) + /* LOOP_DIST_ALIAS call remained in saved_cfun, if at least one + of the corresponding loops was moved, remove it. */ + fold_loop_internal_call (g, gimple_call_arg (g, 1)); + } + XDELETEVEC (moved_orig_loop_num); + } + ggc_free (larray); + /* Move blocks from BBS into DEST_CFUN. */ gcc_assert (bbs.length () >= 2); after = dest_cfun->cfg->x_entry_block_ptr; --- gcc/testsuite/gcc.dg/graphite/pr83359.c.jj 2017-12-11 11:43:10.433737382 +0100 +++ gcc/testsuite/gcc.dg/graphite/pr83359.c 2017-12-11 11:43:01.000000000 +0100 @@ -0,0 +1,40 @@ +/* PR tree-optimization/83359 */ +/* { dg-do compile { target pthread } } */ +/* { dg-options "-O3 -floop-parallelize-all -ftree-parallelize-loops=2" } */ + +int a, b, c; + +void +foo (int x, int y) +{ + int *d = &a; + int *e = &x; + + for (a = 0; a < 1; ++a) + d = &x; + + while (b < 10) + { + for (b = 0; b < 1; ++b) + if (x == 0) + while (x < 1) + ++x; + else + while (x < 1) + { + d = &y; + ++x; + } + ++b; + } + + for (;;) + for (c = 0; c < 2; ++c) + { + if (*d != 0) + a = *e; + + e = &b; + y = 0; + } +}