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)