From patchwork Wed Nov 15 07:05:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 838105 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-466811-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="lRyw5dlG"; dkim-atps=neutral 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 3ycFms4wRCz9sxR for ; Wed, 15 Nov 2017 18:07:08 +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; q=dns; s= default; b=xiHDh7ltpRRTw8qsVAMI3oxKgvZF9WQ+Uk+LDvqhfzDJtkUF9mMu0 IABWgtlR83VRH4fLj1MA8Dg+Krt11mxhZfiRdLX5sQp4U1CnNEzCyLpLyq9JXDvU q2kVbfLYoG6UhlhvCqmwNL/BVbdW7tm9U+QIasW6d0JkOoYeBqbcFo= 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; s= default; bh=LMPqI8jh1H9jV0zSbSLrQJ0y/zQ=; b=lRyw5dlGgWyMwN4Zfg9p qeBMbV+eF4Ow82EUnUfk+Sh/RSir+q+1sPdXhOQ/Fkep1oTviDdIE+Kw9g49ZXxE ruHcdcF+JJYLcIMoKUOqZJK/nQKhH7FsRp+1qfPTflT+eBidBjtD5CH29I301dQF TxIrdHK1EAMp1u829k50JNo= Received: (qmail 125579 invoked by alias); 15 Nov 2017 07:06:55 -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 125568 invoked by uid 89); 15 Nov 2017 07:06:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=H*o:Group, mistaken X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 15 Nov 2017 07:06:51 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 780A73680E for ; Wed, 15 Nov 2017 07:06:50 +0000 (UTC) Received: from freie.home (ovpn04.gateway.prod.ext.phx2.redhat.com [10.5.9.4]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9BCE499399 for ; Wed, 15 Nov 2017 07:06:49 +0000 (UTC) Received: from livre (livre.home [172.31.160.2]) by freie.home (8.15.2/8.15.2) with ESMTP id vAF75b1C017068; Wed, 15 Nov 2017 05:05:37 -0200 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Subject: [DWARF] mark partial fn versions and OMP frags as partial in dwarf2+ debug info Date: Wed, 15 Nov 2017 05:05:36 -0200 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) MIME-Version: 1.0 debug info: partial noentry functions: infra This is the first patch of a set that addresses two different but somewhat related issues. On the one hand, after partial inlining, the non-inlined function fragment is output in a way that debug info consumers can't distinguish from the entire function: debug info lists the entire function as abstract origin for the fragment, but nothing that indicates the fragment does not stand for the entire function. So, if a debugger is asked to set a breakpoint at the entry point of the function, it might very well set one at the entry point of the fragment, which is likely not where users expect to stop. On the other hand, OpenMP blocks are split out into artificial functions that do not indicate their executable code is part of another function. The artificial functions are nested within the original function, but that's hardly enough: ideally, debug info consumers should be able to tell that, if they stop within one of these functions, they're abstractly within the original function. This patch introduces a new DWARF attribute to indicate that a function is a partial copy of its abstract origin, specifically, that its entry point does not correspond to the entry point of the abstract origin. This attribute can then be used to mark the out-of-line portion of partial inlines, and OpenMP blocks split out into artificial functions. This patchset was regstrapped on x86_64-linux-gnu and i686-linux-gnu. Ok to install the first patch? (infrastructure) Ok to install the second patch? (function versioning) Ok to install the third patch? (OpenMP fragments) for include/ChangeLog * dwarf2.def (DW_AT_GNU_partial_noentry): New. for gcc/ChangeLog * tree-core.h (tree_function_decl): Drop unused tm_clone_flag. Add partial_copy_flag. * tree.h (DECL_FUNCTION_PARTIAL_COPY): New. * dwarf2out.c (checksum_attributes): Add at_partial_noentry. (collect_checksum_attributes): Set it. (die_checksum_ordered): Checksum it. (gen_subprogam_die): Keep the old die if it the partial copy flag matches the partial noentry attribute. Set the attribute as needed. --- gcc/dwarf2out.c | 11 ++++++++++- gcc/tree-core.h | 2 +- gcc/tree.h | 10 ++++++++++ include/dwarf2.def | 3 +++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 76a538f1ff97..db0bc12a1f46 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -6944,6 +6944,7 @@ struct checksum_attributes dw_attr_node *at_virtuality; dw_attr_node *at_visibility; dw_attr_node *at_vtable_elem_location; + dw_attr_node *at_partial_noentry; }; /* Collect the attributes that we will want to use for the checksum. */ @@ -7108,6 +7109,9 @@ collect_checksum_attributes (struct checksum_attributes *attrs, dw_die_ref die) case DW_AT_vtable_elem_location: attrs->at_vtable_elem_location = a; break; + case DW_AT_GNU_partial_noentry: + attrs->at_partial_noentry = a; + break; default: break; } @@ -7183,6 +7187,7 @@ die_checksum_ordered (dw_die_ref die, struct md5_ctx *ctx, int *mark) CHECKSUM_ATTR (attrs.at_type); CHECKSUM_ATTR (attrs.at_friend); CHECKSUM_ATTR (attrs.at_alignment); + CHECKSUM_ATTR (attrs.at_partial_noentry); /* Checksum the child DIEs. */ c = die->die_child; @@ -21933,7 +21938,9 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) if (old_die && old_die->die_parent == NULL) add_child_die (context_die, old_die); - if (old_die && get_AT_ref (old_die, DW_AT_abstract_origin)) + if (old_die && get_AT_ref (old_die, DW_AT_abstract_origin) + && (DECL_FUNCTION_PARTIAL_COPY (decl) + == get_AT_flag (old_die, DW_AT_GNU_partial_noentry))) { /* If we have a DW_AT_abstract_origin we have a working cached version. */ @@ -21943,6 +21950,8 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) { subr_die = new_die (DW_TAG_subprogram, context_die, decl); add_abstract_origin_attribute (subr_die, origin); + if (DECL_FUNCTION_PARTIAL_COPY (decl)) + add_AT_flag (subr_die, DW_AT_GNU_partial_noentry, true); /* This is where the actual code for a cloned function is. Let's emit linkage name attribute for it. This helps debuggers to e.g, set breakpoints into diff --git a/gcc/tree-core.h b/gcc/tree-core.h index f74f1453de6d..507016db23e9 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -1784,7 +1784,7 @@ struct GTY(()) tree_function_decl { unsigned pure_flag : 1; unsigned looping_const_or_pure_flag : 1; unsigned has_debug_args_flag : 1; - unsigned tm_clone_flag : 1; + unsigned partial_copy_flag : 1; unsigned versioned_function : 1; /* No bits left. */ }; diff --git a/gcc/tree.h b/gcc/tree.h index 39acffe52662..12c0b3835d9f 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3002,6 +3002,16 @@ extern vec **decl_debug_args_insert (tree); #define DECL_FUNCTION_VERSIONED(NODE)\ (FUNCTION_DECL_CHECK (NODE)->function_decl.versioned_function) +/* In FUNCTION_DECL, this is set if this function is only a partial + clone/version/copy of its DECL_ABSTRACT_ORIGIN. It should be used + for the non-inlined portion of a partial inline, for openmp blocks + turned into separate functions, and for any other cases in which we + clone only select parts of a function, presumably omitting its + entry point, that is presumed to remain in a separate, controlling + version of the function. */ +#define DECL_FUNCTION_PARTIAL_COPY(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.partial_copy_flag) + /* In FUNCTION_DECL, this is set if this function is a C++ constructor. Devirtualization machinery uses this knowledge for determing type of the object constructed. Also we assume that constructor address is not diff --git a/include/dwarf2.def b/include/dwarf2.def index 2a3b23fef873..f2dd9196b039 100644 --- a/include/dwarf2.def +++ b/include/dwarf2.def @@ -433,6 +433,9 @@ DW_AT (DW_AT_GNU_all_source_call_sites, 0x2118) DW_AT (DW_AT_GNU_macros, 0x2119) /* Attribute for C++ deleted special member functions (= delete;). */ DW_AT (DW_AT_GNU_deleted, 0x211a) +/* This flag indicates a partial copy of a function, whose entry point + does not correspond to that of the abstract origin. */ +DW_AT (DW_AT_GNU_partial_noentry, 0x211b) /* Extensions for Fission. See http://gcc.gnu.org/wiki/DebugFission. */ DW_AT (DW_AT_GNU_dwo_name, 0x2130) DW_AT (DW_AT_GNU_dwo_id, 0x2131) debug info: partial noentry functions: partial inlines When we version a function without copying all of its blocks, particularly when we omit or modify the entry point, mark the function as a partial copy. This should enable debug info consumers to avoid setting a breakpoint in the partial copy when the user requests a breakpoint at the function's entry point. An alternate entry point is specified when versioning a function only as we inline part of it; the non-inlined portion is what goes in the new version. Such partial copies used to refer back to the entire function as their abstract origin. Without the partial copy marker, debug info consumers would set a breakpoint for the function at the inlined entry point, and also at the partial copy's entry point, although the latter is not the actual entry point for the function. for gcc/ChangeLog * tree-inline.c (tree_function_versioning): Mark a version as a partial copy when an alternate entry point is given, and when versioning a partial copy. --- gcc/tree-inline.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index d4aa5bed7398..df0f8cabccc1 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -5829,6 +5829,9 @@ tree_function_versioning (tree old_decl, tree new_decl, old_version_node->used_as_abstract_origin = true; DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl); + DECL_FUNCTION_PARTIAL_COPY (new_decl) = new_entry + || DECL_FUNCTION_PARTIAL_COPY (old_decl); + /* Prepare the data structures for the tree copy. */ memset (&id, 0, sizeof (id)); debug info: partial noentry functions: omp split-out blocks We emit some OMP blocks as separate functions that are nested in, but not otherwise related with the function they were originally part of. This patch makes such newly-created artificial functions refer back to the original function as their abstract origin, but as partial copies, so that they're not mistaken as the whole function. This enables line numbers in the split-out block to still be recognized as part of the original function. It may, however, cause debug information consumers that do not support the partial copy attribute to mistake the nested functions as the whole function. for gcc/ChangeLog * omp-low.c (create_omp_child_function): Mark newly-created function as a partial copy of the original one. Mark the original function's cgraph node as used as abstract origin. --- gcc/omp-low.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 33e633cd627b..40166f9bfb3a 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -1633,6 +1633,10 @@ create_omp_child_function (omp_context *ctx, bool task_copy) = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl); DECL_FUNCTION_VERSIONED (decl) = DECL_FUNCTION_VERSIONED (current_function_decl); + DECL_FUNCTION_PARTIAL_COPY (decl) = 1; + DECL_ABSTRACT_ORIGIN (decl) = DECL_ORIGIN (current_function_decl); + if (DECL_ORIGIN (current_function_decl) == current_function_decl) + cgraph_node::get_create (current_function_decl)->used_as_abstract_origin = true; if (omp_maybe_offloaded_ctx (ctx)) {