From patchwork Wed Jan 19 22:10:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 79603 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 CACC2B70F9 for ; Thu, 20 Jan 2011 09:11:07 +1100 (EST) Received: (qmail 2755 invoked by alias); 19 Jan 2011 22:11:05 -0000 Received: (qmail 2744 invoked by uid 22791); 19 Jan 2011 22:11:04 -0000 X-SWARE-Spam-Status: No, hits=-5.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_TM, T_RP_MATCHES_RCVD, T_TVD_MIME_NO_HEADERS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 19 Jan 2011 22:10:58 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id p0JMAu3Z011381 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 19 Jan 2011 17:10:56 -0500 Received: from freie.oliva.athome.lsd.ic.unicamp.br (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p0JMAsWL001522 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 19 Jan 2011 17:10:55 -0500 Received: from livre.localdomain (livre-to-gw.oliva.athome.lsd.ic.unicamp.br [172.31.160.19]) by freie.oliva.athome.lsd.ic.unicamp.br (8.14.4/8.14.4) with ESMTP id p0JMAqgZ015131; Wed, 19 Jan 2011 20:10:53 -0200 Received: from livre.localdomain (aoliva@localhost [127.0.0.1]) by livre.localdomain (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id p0JMApni024431; Wed, 19 Jan 2011 20:10:52 -0200 Received: (from aoliva@localhost) by livre.localdomain (8.14.3/8.14.3/Submit) id p0JMAoj3024429; Wed, 19 Jan 2011 20:10:50 -0200 From: Alexandre Oliva To: Richard Guenther Cc: gcc-patches@gcc.gnu.org Subject: Re: [PR debug/46240] don't introduce debug bind stmts at merge edges References: Date: Wed, 19 Jan 2011 20:10:50 -0200 In-Reply-To: (Richard Guenther's message of "Mon, 17 Jan 2011 16:55:00 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 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 On Jan 17, 2011, Richard Guenther wrote: > Ok. I guess we are sure we never have an unused LHS and thus > no PHI node for the result? The unused result will have got a PHI node and a debug stmt at the confluence point at first, but I suppose the PHI node may be optimized away, but then I *think* we'd have removed the assignment from the call as well. Anyhow, good catch, better not take the risk at this point. > Thus, I'd be more happy when that asserts for phi_nodes would not be > there (I think we can also have non-cleaned up degenerate PHIs). Both asserts removed. Here's what I checked in. for gcc/ChangeLog from Alexandre Oliva PR debug/46240 * tree-into-ssa.c (maybe_register_def): Do not attempt to add debug bind stmt on merge edges. for gcc/testsuite/ChangeLog from Alexandre Oliva PR debug/46240 * g++.dg/debug/pr46240.cc: New. Index: gcc/tree-into-ssa.c =================================================================== --- gcc/tree-into-ssa.c.orig 2011-01-16 10:29:55.920942500 -0200 +++ gcc/tree-into-ssa.c 2011-01-19 20:05:53.727149469 -0200 @@ -1869,11 +1869,27 @@ maybe_register_def (def_operand_p def_p, gcc_assert (!ef); ef = e; } - gcc_assert (ef - && single_pred_p (ef->dest) - && !phi_nodes (ef->dest) - && ef->dest != EXIT_BLOCK_PTR); - gsi_insert_on_edge_immediate (ef, note); + /* If there are other predecessors to ef->dest, then + there must be PHI nodes for the modified + variable, and therefore there will be debug bind + stmts after the PHI nodes. The debug bind notes + we'd insert would force the creation of a new + block (diverging codegen) and be redundant with + the post-PHI bind stmts, so don't add them. + + As for the exit edge, there wouldn't be redundant + bind stmts, but there wouldn't be a PC to bind + them to either, so avoid diverging the CFG. */ + if (ef && single_pred_p (ef->dest) + && ef->dest != EXIT_BLOCK_PTR) + { + /* If there were PHI nodes in the node, we'd + have to make sure the value we're binding + doesn't need rewriting. But there shouldn't + be PHI nodes in a single-predecessor block, + so we just add the note. */ + gsi_insert_on_edge_immediate (ef, note); + } } else gsi_insert_after (&gsi, note, GSI_SAME_STMT); Index: gcc/testsuite/g++.dg/debug/pr46240.cc =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/g++.dg/debug/pr46240.cc 2011-01-19 20:03:25.675777762 -0200 @@ -0,0 +1,172 @@ +// { dg-do compile } +// { dg-options "-O3 -g" } + +template +T &max (T &a, T &b) +{ + if (a < b) return b; else return a; +} +int foo (double); +struct S +{ + struct T + { + int dims, count; + T (int, int) : dims (), count () {} + }; + T *rep; + S () {} + S (int r, int c) : rep (new T (r, c)) {} + ~S () { delete rep; } +}; +template +struct U +{ + static T epsilon () throw (); +}; +template +struct V +{ + struct W + { + T * data; + int count; + W (int n) : data (new T[n]), count () {} + }; + V::W *rep; + S dimensions; + int slice_len; + V (S s) : rep (new V ::W (get_size (s))) {} + int capacity () { return slice_len; } + int get_size (S); +}; +template +struct Z : public V +{ + Z () : V (S (0, 0)) {} + Z (int r, int c) : V (S (r, c)) {} +}; +template +struct A : public Z +{ + A () : Z () {} + A (int n, int m) : Z (n, m) {} +}; +template +struct B : public V +{ +}; +struct C : public A +{ + C () : A () {} + C (int r, int c) : A (r, c) {} +}; +struct D : public B +{ +}; +template +struct E +{ +}; +template +struct G : public E +{ +}; +struct H : public G +{ +}; +template +struct I +{ + R scl, sum; + void accum (R val) + { + R t = __builtin_fabs (val); + if (scl == t) + sum += 1; + } + operator R () { __builtin_sqrt (sum); return R (); } +}; +template +struct J +{ + template < class U > void accum (U val) {} + operator R () { return R (); } +}; +template +struct K +{ + R max; + template void accum (U val) + { + double z = __builtin_fabs (val); + max = ::max (max, z); + } + operator R () { return max; } +}; +template +struct L +{ + unsigned num; + template void accum (U) {} + operator R () { return num; } +}; +template +void bar (V &v, R &res, S acc) +{ + for (int i = 0; i < v.capacity (); i++) + acc.accum ((i)); + res = acc; +} +template +void bar (B &v, R) +{ + R res; + bar (v, res, I ()); +} +template +R bar (A &v, R p) +{ + R res; + if (p == 2) + bar (v, res, I ()); + else if (p == 1) + bar (v, res, J ()); + else if (p == sizeof (float) ? (p) : foo (p)) + { + if (p > 0) + bar (v, res, K ()); + } + else if (p == 0) + bar (v, res, L ()); + return res; +} +template +void +baz (CT m, R p, R tol, int maxiter, VectorT) +{ + VectorT y (0, 0), z (0, 1); + R q = 0; + R gamma = 0, gamma1 = 0; + gamma = bar (y, p); + (void) (bar (z, q) <= (gamma1 <= gamma)); +} +int a = 100; +template +void +test (CT m, R p, VectorT) +{ + VectorT x; + R sqrteps (U ::epsilon ()); + baz (m, p, sqrteps, a, x); +} +void +fn (D x, double p) +{ + bar (x, p); +} +void +fn (H x, double p) +{ + test (x, p, C ()); +}