From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13040 invoked by alias); 11 Oct 2010 13:56:09 -0000 Received: (qmail 13032 invoked by uid 22791); 11 Oct 2010 13:56:09 -0000 X-SWARE-Spam-Status: No, hits=-3.3 required=5.0 tests=AWL,BAYES_00,TW_FN,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 11 Oct 2010 13:56:04 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id DD15C87D82; Mon, 11 Oct 2010 15:56:01 +0200 (CEST) Date: Mon, 11 Oct 2010 14:00:00 -0000 From: Richard Guenther To: Martin Jambor Cc: GCC Patches , Jan Hubicka Subject: Re: [PATCH, PR 45699] Devirtualize to thunks In-Reply-To: <20101011133014.GA12977@virgil.arch.suse.de> Message-ID: References: <20101011133014.GA12977@virgil.arch.suse.de> User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 X-SW-Source: 2010-10/txt/msg00900.txt.bz2 On Mon, 11 Oct 2010, Martin Jambor wrote: > Hi, > > folding of OBJ_TYPE_REFs just takes the function declaration in BINFOs > and puts into the call statement. Unfortunately BINFOs do not put the > declaration of the proper thunk there and so we might ending up not > adjusting the this pointer like in the testcase below. On the other > hand, BINFOs do contain the deltas and so the folding code can look up > the right thunk in the call graph if need be. This is what the patch > below does. > > Bootstrapped and tested on x86_64-linux without any issues. OK for > trunk? Ok. Thanks, Richard. > Thanks, > > Martin > > > 2010-10-08 Martin Jambor > > PR middle-end/45699 > * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Choose among > thunks. > > * testsuite/g++.dg/torture/pr45699.C: New test. > * testsuite/g++.dg/otr-fold-1.C: Adjusted. > * testsuite/g++.dg/otr-fold-1.C: Likewise. > > > Index: icln/gcc/gimple-fold.c > =================================================================== > --- icln.orig/gcc/gimple-fold.c > +++ icln/gcc/gimple-fold.c > @@ -1463,7 +1463,7 @@ tree > gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo) > { > HOST_WIDE_INT i; > - tree v, fndecl; > + tree v, fndecl, delta; > > v = BINFO_VIRTUALS (known_binfo); > i = 0; > @@ -1475,6 +1475,25 @@ gimple_fold_obj_type_ref_known_binfo (HO > } > > fndecl = TREE_VALUE (v); > + delta = TREE_PURPOSE (v); > + gcc_assert (host_integerp (delta, 0)); > + > + if (integer_nonzerop (delta)) > + { > + struct cgraph_node *node = cgraph_get_node (fndecl); > + HOST_WIDE_INT off = tree_low_cst (delta, 0); > + > + if (!node) > + return NULL; > + for (node = node->same_body; node; node = node->next) > + if (node->thunk.thunk_p && off == node->thunk.fixed_offset) > + break; > + if (node) > + fndecl = node->decl; > + else > + return NULL; > + } > + > /* When cgraph node is missing and function is not public, we cannot > devirtualize. This can happen in WHOPR when the actual method > ends up in other partition, because we found devirtualization > Index: icln/gcc/testsuite/g++.dg/otr-fold-1.C > =================================================================== > --- icln.orig/gcc/testsuite/g++.dg/otr-fold-1.C > +++ icln/gcc/testsuite/g++.dg/otr-fold-1.C > @@ -72,5 +72,5 @@ int main (int argc, char *argv[]) > return 0; > } > > -/* { dg-final { scan-tree-dump "= B::foo" "optimized" } } */ > +/* { dg-final { scan-tree-dump "= B::.*foo" "optimized" } } */ > /* { dg-final { cleanup-tree-dump "optimized" } } */ > Index: icln/gcc/testsuite/g++.dg/otr-fold-2.C > =================================================================== > --- icln.orig/gcc/testsuite/g++.dg/otr-fold-2.C > +++ icln/gcc/testsuite/g++.dg/otr-fold-2.C > @@ -84,5 +84,5 @@ int main (int argc, char *argv[]) > return 0; > } > > -/* { dg-final { scan-tree-dump "= B::foo" "optimized" } } */ > +/* { dg-final { scan-tree-dump "= B::.*foo" "optimized" } } */ > /* { dg-final { cleanup-tree-dump "optimized" } } */ > Index: icln/gcc/testsuite/g++.dg/torture/pr45699.C > =================================================================== > --- /dev/null > +++ icln/gcc/testsuite/g++.dg/torture/pr45699.C > @@ -0,0 +1,61 @@ > +// { dg-do run } > + > +extern "C" void abort (); > + > +class A > +{ > +public: > + virtual void foo () {abort();} > +}; > + > +class B : public A > +{ > +public: > + int z; > + virtual void foo () {abort();} > +}; > + > +class C : public A > +{ > +public: > + void *a[32]; > + unsigned long b; > + long c[32]; > + > + virtual void foo () {abort();} > +}; > + > +class D : public C, public B > +{ > +public: > + D () : C(), B() > + { > + int i; > + for (i = 0; i < 32; i++) > + { > + a[i] = (void *) 0; > + c[i] = 0; > + } > + b = 0xaaaa; > + } > + > + virtual void foo (); > +}; > + > +void D::foo() > +{ > + if (b != 0xaaaa) > + abort(); > +} > + > +static inline void bar (B &b) > +{ > + b.foo (); > +} > + > +int main() > +{ > + D d; > + bar (d); > + return 0; > +} > > -- Richard Guenther Novell / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex