On Tue, 8 May 2018, Jan Hubicka wrote:

> Hi,
> this patch adds the symtab support for LTO incremental linking. Most of the
> code path is same for both modes of incremental link except hat we want to
> produce LTO object file rather than compile down to assembly.
> 
> Only non-obvious changes are in ipa.c where I hit a bug where we stream in 
> initializers that are going to be eliminated form the symbol table for no
> good reasons.
> 
> Bootstrapped/regtested x86_64-linux with rest of the incremental link 
> patchset.
> 
> Honza
> 
>       * passes.c (ipa_write_summaries): Only modify statements if body
>       is in memory.
>       * cgraphunit.c (ipa_passes): Also produce intermeidate code when
>       incrementally linking.
>       (ipa_passes): Likewise.
>       * lto-cgraph.c (lto_output_node): When incrementally linking do not
>       pass down resolution info.
>       * common.opt (flag_incremental_link): Update info.
>       * gcc.c (plugin specs): Turn flinker-output=* to
>       -plugin-opt=-linker-output-known
>       * toplev.c (compile_file): Also cut compilation when doing incremental
>       link.
>       * flag-types. (enum lto_partition_model): Add
>       LTO_LINKER_OUTPUT_NOLTOREL.
>       (invoke.texi): Add -flinker-output docs.
>       * ipa.c (symbol_table::remove_unreachable_nodes): Handle LTO incremental
>       link same way as WPA; do not stream in dead initializers.
> 
>       * lang.opt (lto_linker_output): Add nolto-rel.
>       * lto-lang.c (lto_post_options): Handle LTO_LINKER_OUTPUT_REL
>       and LTO_LINKER_OUTPUT_NOLTOREL.
>       (lto_init): Generate lto when doing incremental link.
>       * lto.c (lto_precess_name): Add lto1-inclink.
> Index: cgraphunit.c
> ===================================================================
> --- cgraphunit.c      (revision 260042)
> +++ cgraphunit.c      (working copy)
> @@ -2452,8 +2452,10 @@
>    if (flag_generate_lto || flag_generate_offload)
>      targetm.asm_out.lto_start ();
>  
> -  if (!in_lto_p)
> +  if (!in_lto_p || flag_incremental_link == 2)

Can we have an enum for flag_incremental_link pretty please?

Can't we arrange flag_wpa to be set for this and or merge the
various flags into a more intelligent enum?

>      {
> +      if (!quiet_flag)
> +     fprintf (stderr, "Streaming LTO\n");
>        if (g->have_offload)
>       {
>         section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
> @@ -2472,7 +2474,9 @@
>    if (flag_generate_lto || flag_generate_offload)
>      targetm.asm_out.lto_end ();
>  
> -  if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
> +  if (!flag_ltrans
> +      && ((in_lto_p && flag_incremental_link != 2)
> +       || !flag_lto || flag_fat_lto_objects))
>      execute_ipa_pass_list (passes->all_regular_ipa_passes);
>    invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
>  
> @@ -2559,7 +2563,8 @@
>  
>    /* Do nothing else if any IPA pass found errors or if we are just 
> streaming LTO.  */
>    if (seen_error ()
> -      || (!in_lto_p && flag_lto && !flag_fat_lto_objects))
> +      || ((!in_lto_p || flag_incremental_link == 2)
> +       && flag_lto && !flag_fat_lto_objects))
>      {
>        timevar_pop (TV_CGRAPHOPT);
>        return;
> Index: common.opt
> ===================================================================
> --- common.opt        (revision 260042)
> +++ common.opt        (working copy)
> @@ -48,7 +48,8 @@
>  
>  ; This variable is set to non-0 only by LTO front-end.  1 indicates that
>  ; the output produced will be used for incrmeental linking (thus weak symbols
> -; can still be bound).
> +; can still be bound) and 2 indicates that the IL is going to be linked and
> +; and output to LTO object file.
>  Variable
>  int flag_incremental_link = 0
>  
> Index: flag-types.h
> ===================================================================
> --- flag-types.h      (revision 260042)
> +++ flag-types.h      (working copy)
> @@ -289,6 +289,7 @@
>  enum lto_linker_output {
>    LTO_LINKER_OUTPUT_UNKNOWN,
>    LTO_LINKER_OUTPUT_REL,
> +  LTO_LINKER_OUTPUT_NOLTOREL,
>    LTO_LINKER_OUTPUT_DYN,
>    LTO_LINKER_OUTPUT_PIE,
>    LTO_LINKER_OUTPUT_EXEC
> Index: gcc.c
> ===================================================================
> --- gcc.c     (revision 260042)
> +++ gcc.c     (working copy)
> @@ -961,6 +961,7 @@
>      -plugin %(linker_plugin_file) \
>      -plugin-opt=%(lto_wrapper) \
>      -plugin-opt=-fresolution=%u.res \
> +    %{flinker-output=*:-plugin-opt=-linker-output-known} \
>      
> %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
>      }" PLUGIN_COND_CLOSE
>  #else
> Index: ipa.c
> ===================================================================
> --- ipa.c     (revision 260042)
> +++ ipa.c     (working copy)
> @@ -130,9 +130,9 @@
>                    constant folding.  Keep references alive so partitioning
>                    knows about potential references.  */
>                 || (VAR_P (node->decl)
> -                   && flag_wpa
> -                   && ctor_for_folding (node->decl)
> -                      != error_mark_node))))
> +                   && (flag_wpa || flag_incremental_link == 2)
> +                   && dyn_cast <varpool_node *> (node)
> +                        ->ctor_useable_for_folding_p ()))))
>       {
>         /* Be sure that we will not optimize out alias target
>            body.  */
> @@ -622,7 +622,7 @@
>           fprintf (file, " %s", vnode->dump_name ());
>            vnext = next_variable (vnode);
>         /* Signal removal to the debug machinery.  */
> -       if (! flag_wpa)
> +       if (! flag_wpa || flag_incremental_link == 2)
>           {
>             vnode->definition = false;
>             (*debug_hooks->late_global_decl) (vnode->decl);
> @@ -640,8 +640,9 @@
>             changed = true;
>           }
>         /* Keep body if it may be useful for constant folding.  */
> -       if ((init = ctor_for_folding (vnode->decl)) == error_mark_node
> -           && !POINTER_BOUNDS_P (vnode->decl))
> +       if ((flag_wpa || flag_incremental_link == 2)
> +           || ((init = ctor_for_folding (vnode->decl)) == error_mark_node
> +               && !POINTER_BOUNDS_P (vnode->decl)))
>           vnode->remove_initializer ();
>         else
>           DECL_INITIAL (vnode->decl) = init;
> Index: lto/lang.opt
> ===================================================================
> --- lto/lang.opt      (revision 260042)
> +++ lto/lang.opt      (working copy)
> @@ -34,6 +34,9 @@
>  Enum(lto_linker_output) String(rel) Value(LTO_LINKER_OUTPUT_REL)
>  
>  EnumValue
> +Enum(lto_linker_output) String(nolto-rel) Value(LTO_LINKER_OUTPUT_NOLTOREL)
> +
> +EnumValue
>  Enum(lto_linker_output) String(dyn) Value(LTO_LINKER_OUTPUT_DYN)
>  
>  EnumValue
> Index: lto/lto-lang.c
> ===================================================================
> --- lto/lto-lang.c    (revision 260042)
> +++ lto/lto-lang.c    (working copy)
> @@ -879,7 +879,27 @@
>    switch (flag_lto_linker_output)
>      {
>      case LTO_LINKER_OUTPUT_REL: /* .o: incremental link producing LTO IL  */
> +      /* Configure compiler same way as normal frontend would do with -flto:
> +      this way we read the trees (declarations & types), symbol table,
> +      optimization summaries and link them. Subsequently we output new LTO
> +      file.  */
> +      flag_lto = "";
> +      flag_incremental_link = 2;
>        flag_whole_program = 0;
> +      flag_wpa = 0;
> +      flag_generate_lto = 1;
> +      /* It would be cool to produce .o file directly, but our current
> +      simple objects does not contain the lto symbol markers.  Go the slow
> +      way through the asm file.  */
> +      lang_hooks.lto.begin_section = lhd_begin_section;
> +      lang_hooks.lto.append_data = lhd_append_data;
> +      lang_hooks.lto.end_section = lhd_end_section;
> +      if (flag_ltrans)
> +     error ("-flinker-output=rel and -fltrans are mutually exclussive");
> +      break;
> +
> +    case LTO_LINKER_OUTPUT_NOLTOREL: /* .o: incremental link producing asm  
> */
> +      flag_whole_program = 0;
>        flag_incremental_link = 1;
>        break;
>  
> @@ -1269,7 +1289,7 @@
>    in_lto_p = true;
>  
>    /* We need to generate LTO if running in WPA mode.  */
> -  flag_generate_lto = (flag_wpa != NULL);
> +  flag_generate_lto = (flag_incremental_link == 2 || flag_wpa != NULL);
>  
>    /* Create the basic integer types.  */
>    build_common_tree_nodes (flag_signed_char);
> Index: lto/lto.c
> ===================================================================
> --- lto/lto.c (revision 260042)
> +++ lto/lto.c (working copy)
> @@ -3257,7 +3257,7 @@
>  lto_process_name (void)
>  {
>    if (flag_lto)
> -    setproctitle ("lto1-lto");
> +    setproctitle (flag_incremental_link == 2 ? "lto1-inclink" : "lto1-lto");
>    if (flag_wpa)
>      setproctitle ("lto1-wpa");
>    if (flag_ltrans)
> Index: lto-cgraph.c
> ===================================================================
> --- lto-cgraph.c      (revision 260042)
> +++ lto-cgraph.c      (working copy)
> @@ -540,7 +540,10 @@
>    bp_pack_value (&bp, node->thunk.thunk_p, 1);
>    bp_pack_value (&bp, node->parallelized_function, 1);
>    bp_pack_enum (&bp, ld_plugin_symbol_resolution,
> -             LDPR_NUM_KNOWN, node->resolution);
> +             LDPR_NUM_KNOWN,
> +             /* When doing incremental link, we will get new resolution
> +                info next time we process the file.  */
> +             flag_incremental_link ? LDPR_UNKNOWN : node->resolution);
>    bp_pack_value (&bp, node->instrumentation_clone, 1);
>    bp_pack_value (&bp, node->split_part, 1);
>    streamer_write_bitpack (&bp);
> Index: lto-streamer-out.c
> ===================================================================
> --- lto-streamer-out.c        (revision 260042)
> +++ lto-streamer-out.c        (working copy)
> @@ -2406,7 +2406,8 @@
>               }
>             decl_state = lto_new_out_decl_state ();
>             lto_push_out_decl_state (decl_state);
> -           if (gimple_has_body_p (node->decl) || !flag_wpa
> +           if (gimple_has_body_p (node->decl)
> +               || (!flag_wpa && flag_incremental_link != 2)
>                 /* Thunks have no body but they may be synthetized
>                    at WPA time.  */
>                 || DECL_ARGUMENTS (node->decl))
> @@ -2438,7 +2439,7 @@
>             decl_state = lto_new_out_decl_state ();
>             lto_push_out_decl_state (decl_state);
>             if (DECL_INITIAL (node->decl) != error_mark_node
> -               || !flag_wpa)
> +               || (!flag_wpa && flag_incremental_link != 2))
>               output_constructor (node);
>             else
>               copy_function_or_variable (node);
> Index: passes.c
> ===================================================================
> --- passes.c  (revision 260042)
> +++ passes.c  (working copy)
> @@ -2708,7 +2708,7 @@
>      {
>        struct cgraph_node *node = order[i];
>  
> -      if (node->has_gimple_body_p ())
> +      if (gimple_has_body_p (node->decl))
>       {
>         /* When streaming out references to statements as part of some IPA
>            pass summary, the statements need to have uids assigned and the
> Index: toplev.c
> ===================================================================
> --- toplev.c  (revision 260042)
> +++ toplev.c  (working copy)
> @@ -495,7 +495,8 @@
>  
>    /* Compilation unit is finalized.  When producing non-fat LTO object, we 
> are
>       basically finished.  */
> -  if (in_lto_p || !flag_lto || flag_fat_lto_objects)
> +  if ((in_lto_p && flag_incremental_link != 2)
> +      || !flag_lto || flag_fat_lto_objects)
>      {
>        /* File-scope initialization for AddressSanitizer.  */
>        if (flag_sanitize & SANITIZE_ADDRESS)
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to