From patchwork Sun Jan 10 15:48:32 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom de Vries X-Patchwork-Id: 565479 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 74D0D1402B4 for ; Mon, 11 Jan 2016 02:48:57 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=tjCdb5Bo; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=qsY+g84ggNJMPERAzWrqztztsxp7OhELFohKP7w5g0MZLzOMhN hbvND7DHVYUiwEaqRf1crgyXO5Ak7S/wS19s4iXRF2OD+JzmF8mCwgbFB7F0pztO hMyX1GMNMhC2Ag7d37Ibvm3MPE2vLRcTGsOrj2Zt2JD4dXHZmkQ+omy7g= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=Ts0744yORRvpWrBfLmdiQrM4Kwo=; b=tjCdb5Bo4SDwz4TRBLqu Cv4E/7tYB64920E1mqeJNrNSkMfhLkhprwviRAR/Ma8eR0P9urNqcVzWZyP+/5ye 1pjZxbpvsqTldjBccbzpMKGTfxSwZGRaPxDc9Q2di9qaHRmP/tC2rXEb5zL2Pyl+ Bh37ZqZkjvTCfgNf1ySj79M= Received: (qmail 92248 invoked by alias); 10 Jan 2016 15:48:49 -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 92236 invoked by uid 89); 10 Jan 2016 15:48:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=sk:conflic, UD:stdbool.h, stdboolh, stdbool.h X-HELO: fencepost.gnu.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (208.118.235.10) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sun, 10 Jan 2016 15:48:47 +0000 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48676) by fencepost.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1aIIEX-0006hE-G1 for gcc-patches@gnu.org; Sun, 10 Jan 2016 10:48:45 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aIIES-0004fw-1n for gcc-patches@gnu.org; Sun, 10 Jan 2016 10:48:45 -0500 Received: from relay1.mentorg.com ([192.94.38.131]:59283) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aIIER-0004fq-Pa for gcc-patches@gnu.org; Sun, 10 Jan 2016 10:48:39 -0500 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=SVR-IES-FEM-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1aIIEP-0004BP-6a from Tom_deVries@mentor.com ; Sun, 10 Jan 2016 07:48:37 -0800 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.3.224.2; Sun, 10 Jan 2016 15:48:35 +0000 To: Richard Biener CC: "gcc-patches@gnu.org" From: Tom de Vries Subject: [Committed, PR69062] Don't parallelize loops containing phis with addr_exprs Message-ID: <56927D50.7040701@mentor.com> Date: Sun, 10 Jan 2016 16:48:32 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.4.0 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 192.94.38.131 Hi, when compiling the testcase in the patch (reduced from ira-color.c) with -O2 -ftree-parallelize-loops=2, we run into an ICE: ... prephitmp_39 = PHI <_40(16), &conflicting_regs(7)> ira-color.c:69:8: internal compiler error: verify_gimple failed ... The variable conflicting_regs is a local array in the original function, and it's the job of eliminate_local_variables to rewrite '&conflicting_regs' into a thread function argument relative expression. However, eliminate_local_variables iterates over the statements of a block but ignored the PHIs. The patch fixes the problem conservatively by bailing out of parallelizing loops with a phi with an address expression in a phi argument. Bootstrapped and reg-tested on x86_64. Committed to trunk. Thanks, - Tom Don't parallelize loops containing phis with addr_exprs 2016-01-07 Tom de Vries PR tree-optimization/69062 * tree-parloops.c (loop_has_phi_with_address_arg): New function. (parallelize_loops): Don't paralelize loop that has phi with address arg. * gcc.dg/autopar/pr69062.c: New test. --- gcc/testsuite/gcc.dg/autopar/pr69062.c | 89 ++++++++++++++++++++++++++++++++++ gcc/tree-parloops.c | 34 +++++++++++++ 2 files changed, 123 insertions(+) diff --git a/gcc/testsuite/gcc.dg/autopar/pr69062.c b/gcc/testsuite/gcc.dg/autopar/pr69062.c new file mode 100644 index 0000000..e039349 --- /dev/null +++ b/gcc/testsuite/gcc.dg/autopar/pr69062.c @@ -0,0 +1,89 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2" } */ + +#include + +typedef unsigned long HARD_REG_ELT_TYPE; +typedef HARD_REG_ELT_TYPE HARD_REG_SET[1]; +struct target_ira +{ + HARD_REG_SET x_ira_prohibited_class_mode_regs[1][1]; +}; +extern struct target_ira *this_target_ira; +static inline bool +ira_object_conflict_iter_cond () +{ +} + +static inline bool +check_hard_reg_p (int num_objects, int hard_regno, + HARD_REG_SET * conflict_regs, HARD_REG_SET profitable_regs) +{ + int j, nwords, nregs; + if ((! ! + (((this_target_ira-> + x_ira_prohibited_class_mode_regs)[0][0])[(hard_regno) / + ((unsigned) (8 * 8))] & + (((HARD_REG_ELT_TYPE) (1)) << + ((hard_regno) % ((unsigned) (8 * 8))))))) + return false; + nwords = num_objects; + for (j = 0; j < nregs; j++) + { + int k; + int set_to_test_start = 0, set_to_test_end = nwords; + if (nregs == nwords) + { + if (0) + set_to_test_start = nwords - j - 1; + else + set_to_test_start = j; + } + for (k = set_to_test_start; k < set_to_test_end; k++) + if ((! ! + ((conflict_regs[k])[(hard_regno + j) / ((unsigned) (8 * 8))] & + (((HARD_REG_ELT_TYPE) (1)) << + ((hard_regno + j) % ((unsigned) (8 * 8))))))) + break; + if (k != set_to_test_end) + break; + } + return j == nregs; +} + +void +improve_allocation (void) +{ + int j, k, n, hregno, conflict_hregno, base_cost, class_size, word, nwords; + int check, spill_cost, min_cost, nregs, conflict_nregs, r, best; + int costs[81]; + HARD_REG_SET conflicting_regs[2], profitable_hard_regs; + int a; + for (;;) + { + nwords = a; + for (word = 0; word < nwords; word++) + { + for (; ira_object_conflict_iter_cond ();) + { + for (r = conflict_hregno; + r < conflict_hregno + conflict_nregs; r++) + if (check_hard_reg_p + (a, r, conflicting_regs, profitable_hard_regs)) + costs[r] += spill_cost; + } + if (check_hard_reg_p + (a, hregno, conflicting_regs, profitable_hard_regs) + && min_cost > costs[hregno]) + { + best = hregno; + } + for (; ira_object_conflict_iter_cond ();) + { + if (best + nregs <= conflict_hregno + || conflict_hregno + conflict_nregs <= best) + continue; + } + } + } +} diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 394aba8..5bd9c06 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -2640,6 +2640,37 @@ try_create_reduction_list (loop_p loop, return true; } +/* Return true if LOOP contains phis with ADDR_EXPR in args. */ + +static bool +loop_has_phi_with_address_arg (struct loop *loop) +{ + basic_block *bbs = get_loop_body (loop); + bool res = false; + + unsigned i, j; + gphi_iterator gsi; + for (i = 0; i < loop->num_nodes; i++) + for (gsi = gsi_start_phis (bbs[i]); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gphi *phi = gsi.phi (); + for (j = 0; j < gimple_phi_num_args (phi); j++) + { + tree arg = gimple_phi_arg_def (phi, j); + if (TREE_CODE (arg) == ADDR_EXPR) + { + /* This should be handled by eliminate_local_variables, but that + function currently ignores phis. */ + res = true; + goto end; + } + } + } + end: + free (bbs); + return res; +} + /* Detect parallel loops and generate parallel code using libgomp primitives. Returns true if some loop was parallelized, false otherwise. */ @@ -2734,6 +2765,9 @@ parallelize_loops (void) if (!try_create_reduction_list (loop, &reduction_list)) continue; + if (loop_has_phi_with_address_arg (loop)) + continue; + if (!flag_loop_parallelize_all && !loop_parallel_p (loop, &parloop_obstack)) continue;