This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR59626, _FORTIFY_SOURCE wrappers and LTO
- From: Richard Biener <rguenther at suse dot de>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: gcc-patches at gcc dot gnu dot org, Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 4 Apr 2014 09:53:40 +0200 (CEST)
- Subject: Re: [PATCH] Fix PR59626, _FORTIFY_SOURCE wrappers and LTO
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LSU dot 2 dot 11 dot 1403241048220 dot 26135 at zhemvz dot fhfr dot qr> <20140404061826 dot GC16291 at kam dot mff dot cuni dot cz>
On Fri, 4 Apr 2014, Jan Hubicka wrote:
> Hi,
> here is an updated version of my earlier ipa.c change. It turns out that the
> problem was that I did not drop always_inline.
> In this version I just drop always_inline attribute on all functions whose body
> is removed. The patch will affect non-LTO compilation, too, but IMO only by
> making us to not inline&diagnose the cases where indirect call to always inline
> is turned direct in between early opts and inline. Does that seem acceptable?
> (I personally would preffer this over inventing yet another way to special case
> always_inline for LTO only; we never made any strong promises on always_inline
> and indirect calls)
I think it's fine if indirect calls to always-inline fns go to an
offline copy (or cause a link-time error if there is no offline copy).
I've always thought that taking the address of an always_inline fn
should get you the address of an "external" symbol (an inline "clone"
isn't addressable).
So the patch is fine with me.
Thanks,
Richard.
> Honza
>
> * lto-cgraph.c (input_overwrite_node): Check that partitioning
> flags are set only during streaming.
> * ipa.c (process_references, walk_polymorphic_call_targets,
> symtab_remove_unreachable_nodes): Drop bodies of always inline
> after early inlining.
> (symtab_remove_unreachable_nodes): Remove always_inline attribute.
>
> * gcc.dg/lto/pr59626_0.c: New testcase.
> * gcc.dg/lto/pr59626_1.c: New testcase.
> Index: lto-cgraph.c
> ===================================================================
> --- lto-cgraph.c (revision 209062)
> +++ lto-cgraph.c (working copy)
> @@ -1001,6 +1001,9 @@ input_overwrite_node (struct lto_file_de
> node->thunk.thunk_p = bp_unpack_value (bp, 1);
> node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution,
> LDPR_NUM_KNOWN);
> + gcc_assert (flag_ltrans
> + || (!node->in_other_partition
> + && !node->used_from_other_partition));
> }
>
> /* Return string alias is alias of. */
> @@ -1169,6 +1172,9 @@ input_varpool_node (struct lto_file_decl
> node->same_comdat_group = (symtab_node *) (intptr_t) ref;
> node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution,
> LDPR_NUM_KNOWN);
> + gcc_assert (flag_ltrans
> + || (!node->in_other_partition
> + && !node->used_from_other_partition));
>
> return node;
> }
> Index: ipa.c
> ===================================================================
> --- ipa.c (revision 209062)
> +++ ipa.c (working copy)
> @@ -139,7 +139,10 @@ process_references (struct ipa_ref_list
>
> if (node->definition && !node->in_other_partition
> && ((!DECL_EXTERNAL (node->decl) || node->alias)
> - || (before_inlining_p
> + || (((before_inlining_p
> + && (cgraph_state < CGRAPH_STATE_IPA_SSA
> + || !lookup_attribute ("always_inline",
> + DECL_ATTRIBUTES (node->decl)))))
> /* We use variable constructors during late complation for
> constant folding. Keep references alive so partitioning
> knows about potential references. */
> @@ -191,7 +194,10 @@ walk_polymorphic_call_targets (pointer_s
> /* Prior inlining, keep alive bodies of possible targets for
> devirtualization. */
> if (n->definition
> - && before_inlining_p)
> + && (before_inlining_p
> + && (cgraph_state < CGRAPH_STATE_IPA_SSA
> + || !lookup_attribute ("always_inline",
> + DECL_ATTRIBUTES (n->decl)))))
> pointer_set_insert (reachable, n);
>
> /* Even after inlining we want to keep the possible targets in the
> @@ -491,6 +497,12 @@ symtab_remove_unreachable_nodes (bool be
> node->alias = false;
> node->thunk.thunk_p = false;
> node->weakref = false;
> + /* After early inlining we drop always_inline attributes on
> + bodies of functions that are still referenced (have their
> + address taken). */
> + DECL_ATTRIBUTES (node->decl)
> + = remove_attribute ("always_inline",
> + DECL_ATTRIBUTES (node->decl));
> if (!node->in_other_partition)
> node->local.local = false;
> cgraph_node_remove_callees (node);
> Index: testsuite/gcc.dg/lto/pr59626_1.c
> ===================================================================
> --- testsuite/gcc.dg/lto/pr59626_1.c (revision 0)
> +++ testsuite/gcc.dg/lto/pr59626_1.c (revision 0)
> @@ -0,0 +1,4 @@
> +int bar (int (*fn)(const char *))
> +{
> + return fn ("0");
> +}
> Index: testsuite/gcc.dg/lto/pr59626_0.c
> ===================================================================
> --- testsuite/gcc.dg/lto/pr59626_0.c (revision 0)
> +++ testsuite/gcc.dg/lto/pr59626_0.c (revision 0)
> @@ -0,0 +1,15 @@
> +/* { dg-lto-do run } */
> +
> +int __atoi (const char *) __asm__("atoi");
> +extern inline __attribute__((always_inline,gnu_inline))
> +int atoi (const char *x)
> +{
> + return __atoi (x);
> +}
> +
> +int bar (int (*)(const char *));
> +
> +int main()
> +{
> + return bar (atoi);
> +}
>
>
--
Richard Biener <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer