From patchwork Wed Jan 16 10:01:27 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 212467 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 6A24F2C0094 for ; Wed, 16 Jan 2013 21:01:49 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1358935310; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Cc:Subject:Message-ID:Mail-Followup-To:MIME-Version: Content-Type:Content-Disposition:User-Agent:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=f/UfDydhGnaQoT6bk/2MpOKU1HA=; b=Ncpz5jEVn9E8fmRKIU/p644POkzveGDxGgQurz49Rc7VW5L5c5Zw8lgKe/362F bregdJoZ5JzOwSxL8HGr4FJ8rWNyeGshNfiZx6ARCVWEBiME5m7nGRzRP7Tmv5fi CKApvebg6jp9o9EtEoVaEvJGw6iK1V/yjRRtciV4VWWd4= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Cc:Subject:Message-ID:Mail-Followup-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=Tj2WxQpPin79LPKvLPENzkzPhf6YaQYyKvT599fIA2a9tMwPMRVLogqLp/UwDV yEnZDUl/eT2hMxE3ZqInivtqm4sCmI9QFlEndg7Vahklu2dBzyDMjmulv8k5glWr vIIr/0ZTCVd5GP7N+TV5Kpa+0t4IZfI2MiJUz1EXFFBiA=; Received: (qmail 25936 invoked by alias); 16 Jan 2013 10:01:41 -0000 Received: (qmail 25921 invoked by uid 22791); 16 Jan 2013 10:01:39 -0000 X-SWARE-Spam-Status: No, hits=-5.4 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI 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; Wed, 16 Jan 2013 10:01:29 +0000 Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 06F06A4E0C; Wed, 16 Jan 2013 11:01:28 +0100 (CET) Date: Wed, 16 Jan 2013 11:01:27 +0100 From: Martin Jambor To: GCC Patches Cc: Jan Hubicka Subject: [PATCH, PR 55264] Do not remove as unreachable any virtual methods before inlining Message-ID: <20130116100127.GA21071@virgil.suse> Mail-Followup-To: GCC Patches , Jan Hubicka MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 Hi, PR 55264 is caused by cgraph machinery thinking it knows all calls to a virtual method when that is actually not true. As discussed with Honza, prior to inlining, we should not assume some virtual functions (namely those that are neither DECL_COMDAT nor DECL_EXTERNAL) are not reachable. DECL_EXTERNAL however still affects the cgraph_node->local.local flag and so in order to avoid some LTO failures, I had to adjust IPA-CP to consider such virtual functions non-local so that verification of lattice propagation does not complain. I'm a bit puzzled by the value of the flag in this situation but at least it does not seem to cause any other problems. Below is a trunk patch to do all this. It does not apply to released versions which also suffer from the same problem so I'll prepare a special version(s) for them once this gets approved. Bootstrapped and tested on x86_64-linux. OK for trunk? Thanks, Martin 2013-01-15 Martin Jambor PR tree-optimizations/55264 * ipa-inline-transform.c (can_remove_node_now_p_1): Never return true for virtual methods. * ipa.c (symtab_remove_unreachable_nodes): Never return true for virtual methods before inlining is over. * ipa-cp.c (initialize_node_lattices): Also consider all virtual methods non-local. testsuite/ * g++.dg/ipa/pr55264.C: New test. Index: src/gcc/ipa-inline-transform.c =================================================================== --- src.orig/gcc/ipa-inline-transform.c +++ src/gcc/ipa-inline-transform.c @@ -92,9 +92,7 @@ can_remove_node_now_p_1 (struct cgraph_n those only after all devirtualizable virtual calls are processed. Lacking may edges in callgraph we just preserve them post inlining. */ - && (!DECL_VIRTUAL_P (node->symbol.decl) - || (!DECL_COMDAT (node->symbol.decl) - && !DECL_EXTERNAL (node->symbol.decl))) + && !DECL_VIRTUAL_P (node->symbol.decl) /* During early inlining some unanalyzed cgraph nodes might be in the callgraph and they might reffer the function in question. */ && !cgraph_new_nodes); Index: src/gcc/ipa.c =================================================================== --- src.orig/gcc/ipa.c +++ src/gcc/ipa.c @@ -241,8 +241,7 @@ symtab_remove_unreachable_nodes (bool be && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node) /* Keep around virtual functions for possible devirtualization. */ || (before_inlining_p - && DECL_VIRTUAL_P (node->symbol.decl) - && (DECL_COMDAT (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl))))) + && DECL_VIRTUAL_P (node->symbol.decl)))) { gcc_assert (!node->global.inlined_to); pointer_set_insert (reachable, node); Index: src/gcc/testsuite/g++.dg/ipa/pr55264.C =================================================================== --- /dev/null +++ src/gcc/testsuite/g++.dg/ipa/pr55264.C @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-early-inlining -fno-weak" } */ + +struct S +{ + S(); + virtual inline void foo () + { + foo(); + } +}; + +void +B () +{ + S().foo (); +} Index: src/gcc/ipa-cp.c =================================================================== --- src.orig/gcc/ipa-cp.c +++ src/gcc/ipa-cp.c @@ -699,7 +699,8 @@ initialize_node_lattices (struct cgraph_ int i; gcc_checking_assert (cgraph_function_with_gimple_body_p (node)); - if (!node->local.local) + if (!node->local.local + || DECL_VIRTUAL_P (node->symbol.decl)) { /* When cloning is allowed, we can assume that externally visible functions are not called. We will compensate this by cloning