From: Jan Hubicka <hubicka@ucw.cz>
To: Jan Hubicka <hubicka@ucw.cz>
Cc: "H.J. Lu" <hjl.tools@gmail.com>,
Richard Biener <rguenther@suse.de>,
GCC Patches <gcc-patches@gcc.gnu.org>,
Andi Kleen <ak@linux.intel.com>,
Cary Coutant <ccoutant@google.com>,
Ian Lance Taylor <iant@google.com>
Subject: Re: [RFC] Getting LTO incremental linking work
Date: Wed, 25 Nov 2015 23:56:00 -0000 [thread overview]
Message-ID: <20151125234631.GG20593@kam.mff.cuni.cz> (raw)
In-Reply-To: <20151125230758.GF20593@kam.mff.cuni.cz>
Hi,
here is the patch that implement incremental LTO linking. I will wait few days
for feedback. gcc -r now does LTO IL linking only. To force codegen, one can
use -Wl,-rnolto which I found no right place to document. We may want -rnolto
flag uspported by GCC driver, so the testsuite can be updated to use -rnolto
whenever it uses -r currently and it won't fail on unrecognized option with
non-GNU linkers. I got lost in gcc.c and I do not know where -rdynamic is parsed
(I suppose at the same spot I can do -rnolto and turn it into -r -Wl,-rnolto on
plugin enabled setups and -r on others)
There are still few bugs to track. Most notably WPA will produce hidden symbols
with non-obstructated names which may conflict with later static linking. I will
look into that separately and also try to find more testcases.
* lto-streamer-out.c: Also copy sections when
flag_incremental_link == 2
* flag-types.h (lto_partition_model): Add LTO_LINKER_OUTPUT_NOLTOREL.
* common.opt (flag_incremental_link): Update docs.
* passes.c (ipa_write_summaries): Only renumber statements when
the body is really in memory.
* lto-wrapper.c (run_gcc): Parse -flinker-output and turn into
non-WPA mode at -flinker-output=rel.
* lang.opt (lto_linker_output): New value noltorel.
* lto-lang.c (lto_post_options): Handle LTO_LINKER_OUTPUT_REL
and LTO_LINKER_OUTPUT_NOLTOREL.
(lto_init): We also generate LTO during incremental_link.
* toplev.c (compile_file): Cut compilation when doing incremental
link.
* cgraphunit.c (ipa_passes): Support incremental link.
(symbol_table::compile): Likewise.
* lto-cgraph.c (lto_output_node): Do not propagate resolution info
when linking incrmentally.
* lto-plugin.c: Document flags; add new flag -rnolto
(non_claimed_files, rnolto): New statics.
(all_symbols_read_handler): Decide on rel model.
(claim_file_handler): Count non_claimed_files
(process_option): Process rnolto.
Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c (revision 230915)
+++ gcc/lto-streamer-out.c (working copy)
@@ -2286,13 +2286,16 @@ lto_output (void)
}
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)
/* Thunks have no body but they may be synthetized
at WPA time. */
|| DECL_ARGUMENTS (node->decl))
output_function (node);
else
- copy_function_or_variable (node);
+ {
+ gcc_checking_assert (flag_wpa || flag_incremental_link == 2);
+ copy_function_or_variable (node);
+ }
gcc_assert (lto_get_out_decl_state () == decl_state);
lto_pop_out_decl_state ();
lto_record_function_out_decl_state (node->decl, decl_state);
@@ -2318,7 +2321,7 @@ lto_output (void)
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: gcc/flag-types.h
===================================================================
--- gcc/flag-types.h (revision 230915)
+++ gcc/flag-types.h (working copy)
@@ -269,6 +269,7 @@ enum lto_partition_model {
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/common.opt
===================================================================
--- gcc/common.opt (revision 230915)
+++ gcc/common.opt (working copy)
@@ -48,7 +48,8 @@ bool in_lto_p = false
; 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: gcc/passes.c
===================================================================
--- gcc/passes.c (revision 230915)
+++ gcc/passes.c (working copy)
@@ -2530,7 +2530,7 @@ ipa_write_summaries (void)
{
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: gcc/lto-wrapper.c
===================================================================
--- gcc/lto-wrapper.c (revision 230915)
+++ gcc/lto-wrapper.c (working copy)
@@ -953,9 +953,15 @@ run_gcc (unsigned argc, char *argv[])
file_offset = (off_t) loffset;
}
fd = open (filename, O_RDONLY | O_BINARY);
+ /* Linker plugin passes -fresolution and -flinker-output options. */
if (fd == -1)
{
lto_argv[lto_argc++] = argv[i];
+ if (strcmp (argv[i], "-flinker-output=rel") == 0)
+ {
+ no_partition = true;
+ lto_mode = LTO_MODE_LTO;
+ }
continue;
}
Index: gcc/lto/lang.opt
===================================================================
--- gcc/lto/lang.opt (revision 230915)
+++ gcc/lto/lang.opt (working copy)
@@ -34,6 +34,9 @@ EnumValue
Enum(lto_linker_output) String(rel) Value(LTO_LINKER_OUTPUT_REL)
EnumValue
+Enum(lto_linker_output) String(noltorel) Value(LTO_LINKER_OUTPUT_NOLTOREL)
+
+EnumValue
Enum(lto_linker_output) String(dyn) Value(LTO_LINKER_OUTPUT_DYN)
EnumValue
Index: gcc/lto/lto-lang.c
===================================================================
--- gcc/lto/lto-lang.c (revision 230915)
+++ gcc/lto/lto-lang.c (working copy)
@@ -823,6 +823,26 @@ lto_post_options (const char **pfilename
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;
@@ -1243,7 +1263,7 @@ lto_init (void)
int i;
/* 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, flag_short_double);
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c (revision 230915)
+++ gcc/toplev.c (working copy)
@@ -504,7 +504,8 @@ compile_file (void)
/* 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)
Index: gcc/cgraphunit.c
===================================================================
--- gcc/cgraphunit.c (revision 230915)
+++ gcc/cgraphunit.c (working copy)
@@ -2270,8 +2270,10 @@ ipa_passes (void)
if (flag_generate_lto || flag_generate_offload)
targetm.asm_out.lto_start ();
- if (!in_lto_p)
+ if (!in_lto_p || flag_incremental_link == 2)
{
+ if (!quiet_flag)
+ fprintf (stderr, "Streaming LTO\n");
if (g->have_offload)
{
section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
@@ -2290,7 +2292,9 @@ ipa_passes (void)
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);
@@ -2381,7 +2385,8 @@ symbol_table::compile (void)
/* 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: gcc/lto-cgraph.c
===================================================================
--- gcc/lto-cgraph.c (revision 230915)
+++ gcc/lto-cgraph.c (working copy)
@@ -534,7 +534,10 @@ lto_output_node (struct lto_simple_outpu
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-plugin/lto-plugin.c
===================================================================
--- lto-plugin/lto-plugin.c (revision 230915)
+++ lto-plugin/lto-plugin.c (working copy)
@@ -27,10 +27,13 @@ along with this program; see the file CO
More information at http://gcc.gnu.org/wiki/whopr/driver.
This plugin should be passed the lto-wrapper options and will forward them.
- It also has 2 options of its own:
+ It also has options at his own:
-debug: Print the command line used to run lto-wrapper.
-nop: Instead of running lto-wrapper, pass the original to the plugin. This
- only works if the input files are hybrid. */
+ only works if the input files are hybrid.
+ -rnolto: When doing incremental linking, turn the result into actual binary
+ -sym-style={none,win32,underscore|uscore}
+ -pass-through */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -151,6 +154,7 @@ static ld_plugin_add_symbols add_symbols
static struct plugin_file_info *claimed_files = NULL;
static unsigned int num_claimed_files = 0;
+static unsigned int non_claimed_files = 0;
static struct plugin_file_info *offload_files = NULL;
static unsigned int num_offload_files = 0;
@@ -169,6 +173,7 @@ static char nop;
static char *resolution_file = NULL;
static enum ld_plugin_output_file_type linker_output;
static int linker_output_set;
+static int rnolto;
/* The version of gold being used, or -1 if not gold. The number is
MAJOR * 100 + MINOR. */
@@ -655,7 +660,17 @@ all_symbols_read_handler (void)
switch (linker_output)
{
case LDPO_REL:
- linker_output_str = "-flinker-output=rel";
+ if (non_claimed_files)
+ {
+ rnolto = 1;
+ message (LDPL_WARNING, "incremental linking of LTO and non-LTO "
+ "objects will produce final assembly for LTO objects and "
+ "bypass whole program optimization");
+ }
+ if (rnolto)
+ linker_output_str = "-flinker-output=nonltorel";
+ else
+ linker_output_str = "-flinker-output=rel";
break;
case LDPO_DYN:
linker_output_str = "-flinker-output=dyn";
@@ -1008,6 +1023,8 @@ claim_file_handler (const struct ld_plug
num_claimed_files * sizeof (struct plugin_file_info));
claimed_files[num_claimed_files - 1] = lto_file;
}
+ else
+ non_claimed_files++;
if (obj.found == 0 && obj.offload == 1)
{
@@ -1037,6 +1054,8 @@ claim_file_handler (const struct ld_plug
static void
process_option (const char *option)
{
+ if (strcmp (option, "-rnolto") == 0)
+ rnolto = 1;
if (strcmp (option, "-debug") == 0)
debug = 1;
else if (strcmp (option, "-nop") == 0)
next prev parent reply other threads:[~2015-11-25 23:46 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-25 9:04 Jan Hubicka
2015-11-25 11:19 ` Richard Biener
2015-11-25 15:45 ` H.J. Lu
2015-11-25 19:21 ` Jan Hubicka
2015-11-25 23:09 ` Jan Hubicka
2015-11-25 23:56 ` Jan Hubicka [this message]
2015-11-28 10:35 ` Tom de Vries
2015-11-28 12:03 ` Tom de Vries
2015-11-28 16:05 ` Ilya Verbin
2015-11-28 17:41 ` Tom de Vries
2015-11-29 21:15 ` Jan Hubicka
2015-11-25 18:54 ` Jan Hubicka
2015-11-26 10:15 ` Richard Biener
2015-11-26 20:30 ` Jan Hubicka
2015-11-25 23:59 ` Andi Kleen
2015-11-26 0:24 ` Andi Kleen
2015-11-26 0:54 ` Jan Hubicka
2015-11-26 1:55 ` Andi Kleen
2015-11-26 2:02 ` Jan Hubicka
2015-11-26 2:12 ` Andi Kleen
2015-11-26 6:33 ` Jan Hubicka
2015-11-26 10:33 ` Richard Biener
2016-03-16 17:33 ` H.J. Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151125234631.GG20593@kam.mff.cuni.cz \
--to=hubicka@ucw.cz \
--cc=ak@linux.intel.com \
--cc=ccoutant@google.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=hjl.tools@gmail.com \
--cc=iant@google.com \
--cc=rguenther@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).