> Hey.
> 
> During partial linking we ipa_prop_write_jump_functions twice from 2 IPA
> pass (fnsummary and cp). That produces 2 compressed blocks in an ELF section
> and then zstd complains as sections size does not correspond to the compressed
> stream.
> 
> I'm adding both sanity check changes and the fix in ipa-prop.c.
> I guess Martin and Honza can explain it in more detail?
> 
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> 
> Ready to be installed?
> Thanks,
> Martin
> 
> gcc/ChangeLog:
> 
>       PR lto/97508
>       * langhooks.c (lhd_begin_section): Call get_section with
>       not_existing = true.
>       * output.h (get_section): Add new argument.
>       * varasm.c (get_section): Fail when NOT_EXISTING is true
>       and a section already exists.
>       * ipa-prop.c (ipa_prop_write_jump_functions): Do not stream
>       twice.

I think the streaming should happen only from ipa-fnsummary.
Oriignally ipa-prop was ipa-cp only, then indirect inlining was added,
but these days we have specialized analysis pass and thus ipa-prop
should be intergrated to it.

Honza
> ---
>  gcc/ipa-prop.c  |  9 +++++++++
>  gcc/langhooks.c |  2 +-
>  gcc/output.h    |  3 ++-
>  gcc/varasm.c    | 12 ++++++++++--
>  4 files changed, 22 insertions(+), 4 deletions(-)
> 
> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
> index a848f1db95e..d43fd2eee4f 100644
> --- a/gcc/ipa-prop.c
> +++ b/gcc/ipa-prop.c
> @@ -5067,6 +5067,13 @@ ipa_prop_write_jump_functions (void)
>    lto_symtab_encoder_iterator lsei;
>    lto_symtab_encoder_t encoder;
> +  /* The function can be called from 2 IPA_PASSES: "fnsummary" and "cp"
> +     which happens in partial linking (-r).  Prevent double streaming
> +     as reported in PR97508.  */
> +  static bool already_stremed = false;
> +  if (already_stremed)
> +    return;
> +
>    if (!ipa_node_params_sum || !ipa_edge_args_sum)
>      return;
> @@ -5096,6 +5103,8 @@ ipa_prop_write_jump_functions (void)
>    streamer_write_char_stream (ob->main_stream, 0);
>    produce_asm (ob, NULL);
>    destroy_output_block (ob);
> +
> +  already_stremed = true;
>  }
>  /* Read section in file FILE_DATA of length LEN with data DATA.  */
> diff --git a/gcc/langhooks.c b/gcc/langhooks.c
> index 8819a8859d4..d82f54251fd 100644
> --- a/gcc/langhooks.c
> +++ b/gcc/langhooks.c
> @@ -790,7 +790,7 @@ lhd_begin_section (const char *name)
>      saved_section = text_section;
>    /* Create a new section and switch to it.  */
> -  section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL);
> +  section = get_section (name, SECTION_DEBUG | SECTION_EXCLUDE, NULL, true);
>    switch_to_section (section);
>  }
> diff --git a/gcc/output.h b/gcc/output.h
> index eb253c50329..2f2f1697fd8 100644
> --- a/gcc/output.h
> +++ b/gcc/output.h
> @@ -523,7 +523,8 @@ extern GTY(()) bool in_cold_section_p;
>  extern section *get_unnamed_section (unsigned int, void (*) (const void *),
>                                    const void *);
> -extern section *get_section (const char *, unsigned int, tree);
> +extern section *get_section (const char *, unsigned int, tree,
> +                          bool not_existing = false);
>  extern section *get_named_section (tree, const char *, int);
>  extern section *get_variable_section (tree, bool);
>  extern void place_block_symbol (rtx);
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index ea0b59cf44a..207c9b077d1 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -277,10 +277,12 @@ get_noswitch_section (unsigned int flags, 
> noswitch_section_callback callback)
>  }
>  /* Return the named section structure associated with NAME.  Create
> -   a new section with the given fields if no such structure exists.  */
> +   a new section with the given fields if no such structure exists.
> +   When NOT_EXISTING, then fail if the section already exists.  */
>  section *
> -get_section (const char *name, unsigned int flags, tree decl)
> +get_section (const char *name, unsigned int flags, tree decl,
> +          bool not_existing)
>  {
>    section *sect, **slot;
> @@ -297,6 +299,12 @@ get_section (const char *name, unsigned int flags, tree 
> decl)
>      }
>    else
>      {
> +      if (not_existing)
> +     {
> +       error ("Section already exists: %qs", name);
> +       gcc_unreachable ();
> +     }
> +
>        sect = *slot;
>        /* It is fine if one of the sections has SECTION_NOTYPE as long as
>           the other has none of the contrary flags (see the logic at the end
> -- 
> 2.28.0
> 

Reply via email to