From patchwork Fri Nov 7 18:41:51 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 408227 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 B329C1400DD for ; Sat, 8 Nov 2014 05:49:07 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=Lo9Itc8QQcZhiuyl vfzaobJorkimOpkkqG/MqXesWqWYgMd+ZZAJ5f9nuyYU/R3lAHaltF8PNHh7s/Mc STD3iTCuAVTKiUohZJ3dPJCobKgvPwJDR3o415OJHKAvK/rs31BzVeK94Z5rbwWd Flt82ryJcd6pzxyHcZZreWtz3qg= 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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=+9gPQvLfcawfM7uO/Eh4dn WweW8=; b=NaPrnMIqSLlvkdXVC+nANzMbOyJEUfT+vd4u6lXhRM/i2oCS60pkpO IjfW8xkGoe5RhxzcBuimKGxqxhVOZB0RZcKE53rSxpxSD+7DFAvo8gq7XbU86swo N6SUmAb1Y87U1e7Jt70Z1G1vlC6uACdBPcZKxjoUPoeC0/IgVtDiI= Received: (qmail 27611 invoked by alias); 7 Nov 2014 18:49:00 -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 27598 invoked by uid 89); 7 Nov 2014 18:48:59 -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 autolearn=ham version=3.3.2 X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Fri, 07 Nov 2014 18:48:57 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id E62F92B43DFD for ; Fri, 7 Nov 2014 19:48:52 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sbzOR2tY89Lz for ; Fri, 7 Nov 2014 19:48:52 +0100 (CET) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id BF79A2B43D00 for ; Fri, 7 Nov 2014 19:48:52 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix handling of inlining and nested functions in dwarf2out.c Date: Fri, 07 Nov 2014 19:41:51 +0100 Message-ID: <5734533.5QCkdLUcOB@polaris> User-Agent: KMail/4.7.2 (Linux/3.1.10-1.29-desktop; KDE/4.7.2; x86_64; ; ) MIME-Version: 1.0 Hi, the mix of inlining and nested functions is an interesting challenge on the debug info side because it generates cycles in the debug info: if a child calls its parent and the parent is inlined but not the child, you have the (non-abstract) instance of the child nested in the abstract instance of the parent and containing a concrete inline instance of the parent which points back to the abstract instance, as per the DWARF spec. This is what GCC has been generating for a while, although this caused GDB to crash until very recently (only GDB 7.7 and later versions are OK). Under very special circumstances[*], you can even have a cycle in the internal representation of dwarf2out.c leading to an ICE because the DIEs in the cycle have no ultimate parent. This happens if you have, in addition to the above setup, a grandparent which is both inlined in one of its callers and output as a standalone function: when gen_decl_die is invoked on the grandparent, the cgraph_function_possibly_inlined_p predicate is true so set_decl_origin_self is invoked on the grandparent; now set_decl_origin_self recurses down the entire nest of functions, so the child is also marked as originating from itself by the recursion. Later, when gen_decl_die is invoked on the child, the cgraph_function_possibly_inlined_p predicate is false for it so dwarf2out_abstract_function is not invoked before gen_subprogram_die, which results in a DIE with DW_AT_abstract_origin pointing to itself and without parent for the child. Moreover, when gen_subprogram_die is invoked on the concrete inline instance of the parent, this DIE is retrieved and /* Fixup die_parent for the abstract instance of a nested inline function. */ if (old_die && old_die->die_parent == NULL) add_child_die (context_die, old_die); attaches it to the context_die, creating the cycle since we are in the child. I think that the source of the problem is the discrepancy between the cgraph_function_possibly_inlined_p predicate, which doesn't consider the inlining status of the child as being related to that of its parents (which is explicitly allowed by the DWARF spec) and the set_decl_origin_self recursion, which runs down the entire nest. Hence the attached patchlet, which is sufficient to get rid of the cycle and, therefore, of the ICE. Bootstrapped and regtested on x86_64-suse-linux, OK for the mainline? 2014-11-07 Eric Botcazou * dwarf2out.c (set_block_origin_self): Skip nested functions. [*] There is an important factor coming into play, which is the order in which the functions are sent to dwarf2out.c. That's decided by the cgraph machinery and the ICE happens only when the grandparent is sent before the child. Now, while it's very easy to have this situation without inlining, it's very hard when the functions start being inlined because the cgraph machinery sends them after their callers. We have a large testcase of several big Ada units for which the combination of the various IPA transformations (inlining, cloning, etc) and the repeated topological sorts on the callgraph lead to the ICE, but any attempt at reducing makes it disappear. Index: dwarf2out.c =================================================================== --- dwarf2out.c (revision 217148) +++ dwarf2out.c (working copy) @@ -17919,8 +17919,11 @@ set_block_origin_self (tree stmt) for (local_decl = BLOCK_VARS (stmt); local_decl != NULL_TREE; local_decl = DECL_CHAIN (local_decl)) - if (! DECL_EXTERNAL (local_decl)) - set_decl_origin_self (local_decl); /* Potential recursion. */ + /* Do not recurse on nested functions since the inlining status + of parent and child can be different as per the DWARF spec. */ + if (TREE_CODE (local_decl) != FUNCTION_DECL + && !DECL_EXTERNAL (local_decl)) + set_decl_origin_self (local_decl); } {