From patchwork Sun Mar 17 15:42:18 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 228293 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 4FCEA2C007C for ; Mon, 18 Mar 2013 02:42:40 +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=1364139762; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Subject:Message-ID: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=qYbok02qQgB9ZZnummX1r/vu28A=; b=UbG6gwa1Z/pC23E JCZamEGwJjB5elhdhqGeG+GEo5NdqwKM4Q5rN3DP1YDF6CPsDF+os4ZbjrUSwae1 zByr2cgnhQNlfC78py/70zp3GPI3JM/rPiY8T0QgiY8C/jupBanEeLRWSC/rzHd0 UnWdqMTudYGqCb7vywqab6zPvUuU= 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:Subject:Message-ID:MIME-Version:Content-Type:Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=ZKeZEXmtI7PKAC9qfZmRnP5Nvf8QNWJZEtTJ8zUhy/winmEB5y9aR1Bi0t5gOH 4HB2CXyz4eLPjGsv8bKpTEj/zAEKwasvKB/LBPzYB1MXucb3Va+v2fJjl8+HZqJp uGRtfDwAkNp0KJXABhokWcSh9BgJWpabmNO8Bzg7QQUuI=; Received: (qmail 29166 invoked by alias); 17 Mar 2013 15:42:32 -0000 Received: (qmail 29155 invoked by uid 22791); 17 Mar 2013 15:42:30 -0000 X-SWARE-Spam-Status: No, hits=-3.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 17 Mar 2013 15:42:22 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 3EDA854111C; Sun, 17 Mar 2013 16:42:18 +0100 (CET) Date: Sun, 17 Mar 2013 16:42:18 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Fix ICE building Mozilla with LTO Message-ID: <20130317154218.GA18948@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) 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, current mainline (as well as release branch) dies by ICE in cgraph_mark_address_taken because we attempt to create reference to inline clone. This happens becuase of ltrans propagation for pretty special case from devirtualization missed by WPA but taken by constant propagation happening as part of clone creating. In this case we need to re-create symbol node for the virtual call that we fail t do so. It is the same case as in ipa_make_edge_direct_to_target where I added the necessary code. This patch is not aesthetically pleasing because I plan to solve the problem for 4.9 by moving cgraph clones out of symbol table hash, but it is not trivial to do so and I hope this form of patch is fine for release branch. Bootstrapped/regtested x86_64-linux, I will commit it to mainline. Does it seem OK for release branch? (it is technically a regression even if I do not have better testcase than Mozilla version that does not build with 4.7. It depends heavily on partitioning decisions making it hard to reduce). Honza * cgraph.h (cgraph_get_create_real_symbol_node): Declare. * cgraph.c (cgraph_get_create_real_symbol_node): New function. * cgrpahbuild.c: Use cgraph_get_create_real_symbol_node instead of cgraph_get_create_node. * ipa-prop.c (ipa_make_edge_direct_to_target): Likewise. Index: cgraph.h =================================================================== --- cgraph.h (revision 196601) +++ cgraph.h (working copy) @@ -575,6 +575,7 @@ struct cgraph_node * cgraph_create_node (tree); struct cgraph_node * cgraph_create_empty_node (void); struct cgraph_node * cgraph_get_create_node (tree); +struct cgraph_node * cgraph_get_create_real_symbol_node (tree); struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree); struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree); Index: cgraph.c =================================================================== --- cgraph.c (revision 196601) +++ cgraph.c (working copy) @@ -2595,4 +2597,47 @@ FOR_EACH_FUNCTION (node) verify_cgraph_node (node); } + +/* Create external decl node for DECL. + The difference i nbetween cgraph_get_create_node and + cgraph_get_create_real_symbol_node is that cgraph_get_create_node + may return inline clone, while cgraph_get_create_real_symbol_node + will create a new node in this case. + FIXME: This function should be removed once clones are put out of decl + hash. */ + +struct cgraph_node * +cgraph_get_create_real_symbol_node (tree decl) +{ + struct cgraph_node *first_clone = cgraph_get_node (decl); + struct cgraph_node *node; + /* create symbol table node. even if inline clone exists, we can not take + it as a target of non-inlined call. */ + node = cgraph_get_node (decl); + if (node && !node->global.inlined_to) + return node; + + node = cgraph_create_node (decl); + + /* ok, we previously inlined the function, then removed the offline copy and + now we want it back for external call. this can happen when devirtualizing + while inlining function called once that happens after extern inlined and + virtuals are already removed. in this case introduce the external node + and make it available for call. */ + if (first_clone) + { + first_clone->clone_of = node; + node->clones = first_clone; + symtab_prevail_in_asm_name_hash ((symtab_node) node); + symtab_insert_node_to_hashtable ((symtab_node) node); + if (dump_file) + fprintf (dump_file, "Introduced new external node " + "(%s/%i) and turned into root of the clone tree.\n", + xstrdup (cgraph_node_name (node)), node->uid); + } + else if (dump_file) + fprintf (dump_file, "Introduced new external node " + "(%s/%i).\n", xstrdup (cgraph_node_name (node)), node->uid); + return node; +} #include "gt-cgraph.h" Index: cgraphbuild.c =================================================================== --- cgraphbuild.c (revision 196601) +++ cgraphbuild.c (working copy) @@ -73,7 +73,7 @@ decl = get_base_var (*tp); if (TREE_CODE (decl) == FUNCTION_DECL) { - struct cgraph_node *node = cgraph_get_create_node (decl); + struct cgraph_node *node = cgraph_get_create_real_symbol_node (decl); if (!ctx->only_vars) cgraph_mark_address_taken_node (node); ipa_record_reference ((symtab_node)ctx->varpool_node, @@ -143,7 +143,7 @@ { struct cgraph_node *per_node; - per_node = cgraph_get_create_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl)); + per_node = cgraph_get_create_real_symbol_node (DECL_FUNCTION_PERSONALITY (node->symbol.decl)); ipa_record_reference ((symtab_node)node, (symtab_node)per_node, IPA_REF_ADDR, NULL); cgraph_mark_address_taken_node (per_node); } @@ -223,7 +223,7 @@ addr = get_base_address (addr); if (TREE_CODE (addr) == FUNCTION_DECL) { - struct cgraph_node *node = cgraph_get_create_node (addr); + struct cgraph_node *node = cgraph_get_create_real_symbol_node (addr); cgraph_mark_address_taken_node (node); ipa_record_reference ((symtab_node)data, (symtab_node)node, @@ -252,7 +252,7 @@ { /* ??? This can happen on platforms with descriptors when these are directly manipulated in the code. Pretend that it's an address. */ - struct cgraph_node *node = cgraph_get_create_node (t); + struct cgraph_node *node = cgraph_get_create_real_symbol_node (t); cgraph_mark_address_taken_node (node); ipa_record_reference ((symtab_node)data, (symtab_node)node, @@ -330,7 +330,7 @@ { tree fn = gimple_omp_parallel_child_fn (stmt); ipa_record_reference ((symtab_node)node, - (symtab_node)cgraph_get_create_node (fn), + (symtab_node)cgraph_get_create_real_symbol_node (fn), IPA_REF_ADDR, stmt); } if (gimple_code (stmt) == GIMPLE_OMP_TASK) @@ -338,12 +338,12 @@ tree fn = gimple_omp_task_child_fn (stmt); if (fn) ipa_record_reference ((symtab_node)node, - (symtab_node) cgraph_get_create_node (fn), + (symtab_node) cgraph_get_create_real_symbol_node (fn), IPA_REF_ADDR, stmt); fn = gimple_omp_task_copy_fn (stmt); if (fn) ipa_record_reference ((symtab_node)node, - (symtab_node)cgraph_get_create_node (fn), + (symtab_node)cgraph_get_create_real_symbol_node (fn), IPA_REF_ADDR, stmt); } } Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 196601) +++ ipa-prop.c (working copy) @@ -2117,7 +2117,6 @@ we may create the first reference to the object in the unit. */ if (!callee || callee->global.inlined_to) { - struct cgraph_node *first_clone = callee; /* We are better to ensure we can refer to it. In the case of static functions we are out of luck, since we already @@ -2133,31 +2132,7 @@ xstrdup (cgraph_node_name (ie->callee)), ie->callee->uid); return NULL; } - - /* Create symbol table node. Even if inline clone exists, we can not take - it as a target of non-inlined call. */ - callee = cgraph_create_node (target); - - /* OK, we previously inlined the function, then removed the offline copy and - now we want it back for external call. This can happen when devirtualizing - while inlining function called once that happens after extern inlined and - virtuals are already removed. In this case introduce the external node - and make it available for call. */ - if (first_clone) - { - first_clone->clone_of = callee; - callee->clones = first_clone; - symtab_prevail_in_asm_name_hash ((symtab_node)callee); - symtab_insert_node_to_hashtable ((symtab_node)callee); - if (dump_file) - fprintf (dump_file, "ipa-prop: Introduced new external node " - "(%s/%i) and turned into root of the clone tree.\n", - xstrdup (cgraph_node_name (callee)), callee->uid); - } - else if (dump_file) - fprintf (dump_file, "ipa-prop: Introduced new external node " - "(%s/%i).\n", - xstrdup (cgraph_node_name (callee)), callee->uid); + callee = cgraph_get_create_real_symbol_node (target); } ipa_check_create_node_params ();