From patchwork Thu Jun 11 09:06:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Biener X-Patchwork-Id: 483019 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 B3A5E1402AD for ; Thu, 11 Jun 2015 19:07:09 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Fw46JscQ; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=X3GJKyW+buZRh4mI 6IHO9R/OElGrIhG7BlMb6QgK/2vhPGHUtkSEPGxl0j/PLtpl6M0Hxgf5pTdUs8kY 5A25FxoVWyXyGIQX812b6FjIv9nTArmusl4+omPm6mKTmJh6QruiLZmd7Zwm6uvD 1hcqj4ezkKLx5cOBbdeSq/lRWFM= 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:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=b6chxloAkHoJkNsEi4gRE2 VQ8ZQ=; b=Fw46JscQzHTCzdT80iO2dOplfAy/e4ulGuf2JYZvmbaD7ZpT1eyrBR G38/2GcoknSe4XDNdnWVG8LyU8LPBqtiTro/3ykCzrf4QxllR3fqppyPNQ7hcBm8 TtUZwtaPHue88KEXqG7qN2Nh7aGf7kwZdfORxF/MH9IroUlnyqHEM= Received: (qmail 115070 invoked by alias); 11 Jun 2015 09:07:01 -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 115061 invoked by uid 89); 11 Jun 2015 09:07:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.9 required=5.0 tests=AWL, BAYES_50, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Thu, 11 Jun 2015 09:06:59 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id A287EABE8; Thu, 11 Jun 2015 09:06:55 +0000 (UTC) Date: Thu, 11 Jun 2015 11:06:55 +0200 (CEST) From: Richard Biener To: Pierre-Marie de Rodat cc: GCC Patches , Jakub Jelinek Subject: Re: [PATCH][PR debug/65549] Restore DW_AT_abstract_origin for cross-unit call sites In-Reply-To: <55784A03.2000208@adacore.com> Message-ID: References: <55775CDE.2060101@adacore.com> <55783717.8060505@adacore.com> <55784A03.2000208@adacore.com> User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 On Wed, 10 Jun 2015, Pierre-Marie de Rodat wrote: > On 06/10/2015 03:36 PM, Richard Biener wrote: > > Hmm, yes. It meant to break after the first ;) (without LTO > > there usually is only one TU decl, apart from Java I think). > > The hunk isn't in mainline because it was part of an experimental patch I > > did on the early-debug branch. > > Understood, thanks! > > > Yeah, that looks great! > > > > Of course I wonder about Java (builds multiple ones, one for each > > input file) and Go (no idea). I suppose Java would need to build > > another one where all the "defaults" go (or it doesn't have any > > such entities). > > Yeah, I'm not familiar with them neither... > > > In theory we could have changed dwarf2out_init to get a > > translation-unit-decl argument as well. But your patch looks like > > we don't have such at the point of dwarf2out_init in all frontends. > > > > Your patch is ok (and ok to backport) IMHO, though please give > > others the chance to chime in. > > Thank you very much. :-) I will soon become unavailable until July, so I think > I'll wait until then to commit anyway. FYI, I decided to backport the fix causing this regression to the 4.8 branch today, guarded with in_lto_p, thus eliminating the effect on non-LTO links. The adjusted patch looks like the following and I'll also adjust the 4.9 branch accordingly, leaving the GCC 5 branch with the original fix. Richard. 2015-06-11 Richard Biener Backport from mainline, guarded with in_lto_p 2015-06-02 Richard Biener PR debug/65549 * dwarf2out.c (lookup_context_die): New function. (resolve_addr): Avoid forcing a full DIE for the target of a DW_TAG_GNU_call_site during late compilation. Instead create a stub DIE without a type if we have a context DIE present. * g++.dg/lto/pr65549_0.C: New testcase. Index: gcc/testsuite/g++.dg/lto/pr65549_0.C =================================================================== *** gcc/testsuite/g++.dg/lto/pr65549_0.C (revision 0) --- gcc/testsuite/g++.dg/lto/pr65549_0.C (working copy) *************** *** 0 **** --- 1,144 ---- + // { dg-lto-do link } + // { dg-lto-options { { -std=gnu++14 -flto -g } { -std=gnu++14 -flto -g -O2 -fno-inline -flto-partition=max } } } + // { dg-extra-ld-options "-r -nostdlib" } + + namespace std { + inline namespace __cxx11 {} + template struct integral_constant { + static constexpr _Tp value = 0; + }; + template struct __and_; + struct is_member_object_pointer : integral_constant {}; + template + struct is_member_function_pointer : integral_constant {}; + template struct remove_reference { typedef int type; }; + template class C; + template struct __result_of_impl; + template + struct __result_of_impl { + typedef decltype(0) type; + }; + template + struct C<_Functor(_ArgTypes...)> + : __result_of_impl::type>::value, + _Functor> {}; + template using result_of_t = typename C<_Tp>::type; + template void forward(); + template _Tp move(_Tp) {} + namespace __cxx11 { + class basic_string typedef string; + } + template struct allocator_traits { typedef decltype(0) pointer; }; + } + struct F : std::allocator_traits {}; + namespace std { + namespace __cxx11 { + class basic_string { + public: + struct _Alloc_hider : F { + _Alloc_hider(pointer); + } _M_dataplus; + basic_string(int) : _M_dataplus(0) {} + ~basic_string(); + }; + } + template class function; + template class _Base_manager { + protected: + static _Functor *_M_get_pointer(int) {} + }; + template class _Function_handler; + template + class _Function_handler<_Res(_ArgTypes...), _Functor> + : _Base_manager<_Functor> { + public: + static _Res _M_invoke(const int &) { + (*_Base_manager<_Functor>::_M_get_pointer(0))(); + } + }; + template using __check_func_return_type = int; + template + class function<_Res(_ArgTypes...)> { + template using _Invoke = decltype(0); + template + using _Callable = __and_<__check_func_return_type<_Invoke<_Functor>, _Res>>; + template using _Requires = int; + + public: + template , void>> + function(_Functor); + using _Invoker_type = _Res (*)(const int &); + _Invoker_type _M_invoker; + }; + template + template + function<_Res(_ArgTypes...)>::function(_Functor) { + _M_invoker = _Function_handler<_Res(), _Functor>::_M_invoke; + } + class unique_ptr { + public: + ~unique_ptr(); + }; + template _Tp make_unique(_Args... __args) { + _Tp(__args...); + } + } + class A { + public: + template T as(); + }; + class variables_map { + public: + A operator[](std::basic_string); + }; + class B { + public: + variables_map configuration(); + void run(int, int, std::function); + }; + class H; + struct G { + enum {} _state; + }; + class D { + G _local_state; + std::unique_ptr _task; + template void schedule(Func func) { + struct task_with_state { + task_with_state(Func func) : _func(func) {} + Func _func; + } tws = std::make_unique(std::move(func)); + } + friend H; + }; + template using futurize_t = H; + class H { + D *_promise; + template void schedule(Func func) { + G __trans_tmp_1; + struct task_with_ready_state { + task_with_ready_state(Func, G); + }; + std::make_unique(std::move(func), __trans_tmp_1); + _promise->schedule(std::move(func)); + } + template void then(Func func, Param) { + using P = D; + P pr; + schedule([ pr = std::move(pr), func, param = std::forward ]{}); + } + + public: + template futurize_t> then(Func) { + then(0, [] {}); + } + } clients; + main() { + B app; + app.run(0, 0, [&] { + auto config = app.configuration()[0].as(); + clients.then([] {}); + }); + } Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 224363) +++ gcc/dwarf2out.c (working copy) @@ -19697,6 +19697,28 @@ is_naming_typedef_decl (const_tree decl) != TYPE_NAME (TREE_TYPE (decl)))); } +/* Looks up the DIE for a context. */ + +static inline dw_die_ref +lookup_context_die (tree context) +{ + if (context) + { + /* Find die that represents this context. */ + if (TYPE_P (context)) + { + context = TYPE_MAIN_VARIANT (context); + dw_die_ref ctx = lookup_type_die (context); + if (!ctx) + return NULL; + return strip_naming_typedef (context, ctx); + } + else + return lookup_decl_die (context); + } + return comp_unit_die (); +} + /* Returns the DIE for a context. */ static inline dw_die_ref @@ -22751,8 +22773,25 @@ resolve_addr (dw_die_ref die) && DECL_EXTERNAL (tdecl) && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE) { - force_decl_die (tdecl); - tdie = lookup_decl_die (tdecl); + dw_die_ref cdie; + if (!in_lto_p) + { + force_decl_die (tdecl); + tdie = lookup_decl_die (tdecl); + } + else if ((cdie = lookup_context_die (DECL_CONTEXT (tdecl)))) + { + /* Creating a full DIE for tdecl is overly expensive and + at this point even wrong when in the LTO phase + as it can end up generating new type DIEs we didn't + output and thus optimize_external_refs will crash. */ + tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE); + add_AT_flag (tdie, DW_AT_external, 1); + add_AT_flag (tdie, DW_AT_declaration, 1); + add_linkage_attr (tdie, tdecl); + add_name_and_src_coords_attributes (tdie, tdecl); + equate_decl_number_to_die (tdecl, tdie); + } } if (tdie) {