Commit 1ff9ed6f by Jan Hubicka Committed by Jan Hubicka

re PR lto/67548 (LTO drops weak binding with "ld -r")


	PR lto/67548
	* lto-plugin.c (linker_output, linker_output_set): New statics.
	(all_symbols_read_handler): Add -flinker-output option.
	(onload): Record linker_output info.

	* ipa-visibility.c (cgraph_externally_visible_p,
	varpool_node::externally_visible_p): When doing incremental linking,
	hidden symbols may be still used later.
	(update_visibility_by_resolution_info): Do not drop weak during
	incremental link.
	(function_and_variable_visibility): Fix formating.
	* flag-types.h (lto_linker_output): Declare.
	* common.opt 9flag_incremental_link): New flag.

	* lto-lang.c (lto_post_options): Process flag_lto_linker_output.
	* lang.opt (lto_linker_output): New enum.
	(flinker_output): New flag.

From-SVN: r230915
parent c9d82fb0
2015-11-25 Jan Hubicka <jh@suse.cz>
* ipa-visibility.c (cgraph_externally_visible_p,
varpool_node::externally_visible_p): When doing incremental linking,
hidden symbols may be still used later.
(update_visibility_by_resolution_info): Do not drop weak during
incremental link.
(function_and_variable_visibility): Fix formating.
* flag-types.h (lto_linker_output): Declare.
* common.opt 9flag_incremental_link): New flag.
2015-11-25 Michael Meissner <meissner@linux.vnet.ibm.com> 2015-11-25 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/constraints.md (wb constraint): New constraint for * config/rs6000/constraints.md (wb constraint): New constraint for
...@@ -46,6 +46,12 @@ int optimize_fast ...@@ -46,6 +46,12 @@ int optimize_fast
Variable Variable
bool in_lto_p = false 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).
Variable
int flag_incremental_link = 0
; 0 means straightforward implementation of complex divide acceptable. ; 0 means straightforward implementation of complex divide acceptable.
; 1 means wide ranges of inputs must work for complex divide. ; 1 means wide ranges of inputs must work for complex divide.
; 2 means C99-like requirements for complex multiply and divide. ; 2 means C99-like requirements for complex multiply and divide.
......
...@@ -265,6 +265,14 @@ enum lto_partition_model { ...@@ -265,6 +265,14 @@ enum lto_partition_model {
LTO_PARTITION_MAX = 4 LTO_PARTITION_MAX = 4
}; };
/* flag_lto_linker_output initialization values. */
enum lto_linker_output {
LTO_LINKER_OUTPUT_UNKNOWN,
LTO_LINKER_OUTPUT_REL,
LTO_LINKER_OUTPUT_DYN,
LTO_LINKER_OUTPUT_PIE,
LTO_LINKER_OUTPUT_EXEC
};
/* gfortran -finit-real= values. */ /* gfortran -finit-real= values. */
......
...@@ -217,13 +217,13 @@ cgraph_externally_visible_p (struct cgraph_node *node, ...@@ -217,13 +217,13 @@ cgraph_externally_visible_p (struct cgraph_node *node,
This improves code quality and we know we will duplicate them at most twice This improves code quality and we know we will duplicate them at most twice
(in the case that we are not using plugin and link with object file (in the case that we are not using plugin and link with object file
implementing same COMDAT) */ implementing same COMDAT) */
if ((in_lto_p || whole_program) if (((in_lto_p || whole_program) && !flag_incremental_link)
&& DECL_COMDAT (node->decl) && DECL_COMDAT (node->decl)
&& comdat_can_be_unshared_p (node)) && comdat_can_be_unshared_p (node))
return false; return false;
/* When doing link time optimizations, hidden symbols become local. */ /* When doing link time optimizations, hidden symbols become local. */
if (in_lto_p if ((in_lto_p && !flag_incremental_link)
&& (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
|| DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL) || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object /* Be sure that node is defined in IR file, not in other object
...@@ -293,13 +293,13 @@ varpool_node::externally_visible_p (void) ...@@ -293,13 +293,13 @@ varpool_node::externally_visible_p (void)
so this does not enable more optimization, but referring static var so this does not enable more optimization, but referring static var
is faster for dynamic linking. Also this match logic hidding vtables is faster for dynamic linking. Also this match logic hidding vtables
from LTO symbol tables. */ from LTO symbol tables. */
if ((in_lto_p || flag_whole_program) if (((in_lto_p || flag_whole_program) && !flag_incremental_link)
&& DECL_COMDAT (decl) && DECL_COMDAT (decl)
&& comdat_can_be_unshared_p (this)) && comdat_can_be_unshared_p (this))
return false; return false;
/* When doing link time optimizations, hidden symbols become local. */ /* When doing link time optimizations, hidden symbols become local. */
if (in_lto_p if (in_lto_p && !flag_incremental_link
&& (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
|| DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL) || DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object /* Be sure that node is defined in IR file, not in other object
...@@ -405,17 +405,36 @@ update_visibility_by_resolution_info (symtab_node * node) ...@@ -405,17 +405,36 @@ update_visibility_by_resolution_info (symtab_node * node)
for (symtab_node *next = node->same_comdat_group; for (symtab_node *next = node->same_comdat_group;
next != node; next = next->same_comdat_group) next != node; next = next->same_comdat_group)
{ {
next->set_comdat_group (NULL); /* During incremental linking we need to keep symbol weak for future
DECL_WEAK (next->decl) = false; linking. We can still drop definition if we know non-LTO world
prevails. */
if (!flag_incremental_link)
{
DECL_WEAK (next->decl) = false;
next->set_comdat_group (NULL);
}
if (next->externally_visible if (next->externally_visible
&& !define) && !define)
DECL_EXTERNAL (next->decl) = true; {
DECL_EXTERNAL (next->decl) = true;
next->set_comdat_group (NULL);
}
} }
node->set_comdat_group (NULL);
DECL_WEAK (node->decl) = false; /* During incremental linking we need to keep symbol weak for future
linking. We can still drop definition if we know non-LTO world prevails. */
if (!flag_incremental_link)
{
DECL_WEAK (node->decl) = false;
node->set_comdat_group (NULL);
node->dissolve_same_comdat_group_list ();
}
if (!define) if (!define)
DECL_EXTERNAL (node->decl) = true; {
node->dissolve_same_comdat_group_list (); DECL_EXTERNAL (node->decl) = true;
node->set_comdat_group (NULL);
node->dissolve_same_comdat_group_list ();
}
} }
/* Decide on visibility of all symbols. */ /* Decide on visibility of all symbols. */
...@@ -639,8 +658,9 @@ function_and_variable_visibility (bool whole_program) ...@@ -639,8 +658,9 @@ function_and_variable_visibility (bool whole_program)
{ {
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl)); gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl));
vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY
|| vnode->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) || vnode->resolution
&& TREE_PUBLIC (vnode->decl)); == LDPR_PREVAILING_DEF_IRONLY_EXP)
&& TREE_PUBLIC (vnode->decl));
if (vnode->same_comdat_group && TREE_PUBLIC (vnode->decl)) if (vnode->same_comdat_group && TREE_PUBLIC (vnode->decl))
{ {
symtab_node *next = vnode; symtab_node *next = vnode;
......
2015-11-25 Jan Hubicka <jh@suse.cz>
* lto-lang.c (lto_post_options): Process flag_lto_linker_output.
* lang.opt (lto_linker_output): New enum.
(flinker_output): New flag.
2015-11-24 Jan Hubicka <hubicka@ucw.cz> 2015-11-24 Jan Hubicka <hubicka@ucw.cz>
* lto-symtab.c: Include alias.h * lto-symtab.c: Include alias.h
......
...@@ -24,6 +24,29 @@ ...@@ -24,6 +24,29 @@
Language Language
LTO LTO
Enum
Name(lto_linker_output) Type(enum lto_linker_output) UnknownError(unknown linker output %qs)
EnumValue
Enum(lto_linker_output) String(unknown) Value(LTO_LINKER_OUTPUT_UNKNOWN)
EnumValue
Enum(lto_linker_output) String(rel) Value(LTO_LINKER_OUTPUT_REL)
EnumValue
Enum(lto_linker_output) String(dyn) Value(LTO_LINKER_OUTPUT_DYN)
EnumValue
Enum(lto_linker_output) String(pie) Value(LTO_LINKER_OUTPUT_PIE)
EnumValue
Enum(lto_linker_output) String(exec) Value(LTO_LINKER_OUTPUT_EXEC)
flinker-output=
LTO Report Driver Joined RejectNegative Enum(lto_linker_output) Var(flag_lto_linker_output) Init(LTO_LINKER_OUTPUT_UNKNOWN)
Set linker output type (used internally during LTO optimization)
fltrans fltrans
LTO Report Var(flag_ltrans) LTO Report Var(flag_ltrans)
Run the link-time optimizer in local transformation (LTRANS) mode. Run the link-time optimizer in local transformation (LTRANS) mode.
......
...@@ -819,6 +819,35 @@ lto_post_options (const char **pfilename ATTRIBUTE_UNUSED) ...@@ -819,6 +819,35 @@ lto_post_options (const char **pfilename ATTRIBUTE_UNUSED)
if (flag_wpa) if (flag_wpa)
flag_generate_lto = 1; flag_generate_lto = 1;
/* Initialize the codegen flags according to the output type. */
switch (flag_lto_linker_output)
{
case LTO_LINKER_OUTPUT_REL: /* .o: incremental link producing LTO IL */
flag_whole_program = 0;
flag_incremental_link = 1;
break;
case LTO_LINKER_OUTPUT_DYN: /* .so: PID library */
/* On some targets, like i386 it makes sense to build PIC library wihout
-fpic for performance reasons. So no need to adjust flags. */
break;
case LTO_LINKER_OUTPUT_PIE: /* PIE binary */
/* If -fPIC or -fPIE was used at compile time, be sure that
flag_pie is 2. */
flag_pie = MAX (flag_pie, flag_pic);
flag_pic = 0;
break;
case LTO_LINKER_OUTPUT_EXEC: /* Normal executable */
flag_pic = 0;
flag_pie = 0;
break;
case LTO_LINKER_OUTPUT_UNKNOWN:
break;
}
/* Excess precision other than "fast" requires front-end /* Excess precision other than "fast" requires front-end
support. */ support. */
flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
......
2015-11-25 Jan Hubicka <jh@suse.cz>
PR lto/67548
* lto-plugin.c (linker_output, linker_output_set): New statics.
(all_symbols_read_handler): Add -flinker-output option.
(onload): Record linker_output info.
2015-07-02 Uros Bizjak <ubizjak@gmail.com> 2015-07-02 Uros Bizjak <ubizjak@gmail.com>
* configure.ac: Add AC_USE_SYSTEM_EXTENSIONS. * configure.ac: Add AC_USE_SYSTEM_EXTENSIONS.
......
...@@ -167,6 +167,8 @@ static unsigned int num_pass_through_items; ...@@ -167,6 +167,8 @@ static unsigned int num_pass_through_items;
static char debug; static char debug;
static char nop; static char nop;
static char *resolution_file = NULL; static char *resolution_file = NULL;
static enum ld_plugin_output_file_type linker_output;
static int linker_output_set;
/* The version of gold being used, or -1 if not gold. The number is /* The version of gold being used, or -1 if not gold. The number is
MAJOR * 100 + MINOR. */ MAJOR * 100 + MINOR. */
...@@ -624,8 +626,9 @@ all_symbols_read_handler (void) ...@@ -624,8 +626,9 @@ all_symbols_read_handler (void)
{ {
unsigned i; unsigned i;
unsigned num_lto_args unsigned num_lto_args
= num_claimed_files + num_offload_files + lto_wrapper_num_args + 1; = num_claimed_files + num_offload_files + lto_wrapper_num_args + 2;
char **lto_argv; char **lto_argv;
const char *linker_output_str;
const char **lto_arg_ptr; const char **lto_arg_ptr;
if (num_claimed_files + num_offload_files == 0) if (num_claimed_files + num_offload_files == 0)
return LDPS_OK; return LDPS_OK;
...@@ -648,6 +651,26 @@ all_symbols_read_handler (void) ...@@ -648,6 +651,26 @@ all_symbols_read_handler (void)
for (i = 0; i < lto_wrapper_num_args; i++) for (i = 0; i < lto_wrapper_num_args; i++)
*lto_arg_ptr++ = lto_wrapper_argv[i]; *lto_arg_ptr++ = lto_wrapper_argv[i];
assert (linker_output_set);
switch (linker_output)
{
case LDPO_REL:
linker_output_str = "-flinker-output=rel";
break;
case LDPO_DYN:
linker_output_str = "-flinker-output=dyn";
break;
case LDPO_PIE:
linker_output_str = "-flinker-output=pie";
break;
case LDPO_EXEC:
linker_output_str = "-flinker-output=exec";
break;
default:
message (LDPL_FATAL, "unsupported linker output %i", linker_output);
break;
}
*lto_arg_ptr++ = xstrdup (linker_output_str);
for (i = 0; i < num_claimed_files; i++) for (i = 0; i < num_claimed_files; i++)
{ {
struct plugin_file_info *info = &claimed_files[i]; struct plugin_file_info *info = &claimed_files[i];
...@@ -1100,6 +1123,10 @@ onload (struct ld_plugin_tv *tv) ...@@ -1100,6 +1123,10 @@ onload (struct ld_plugin_tv *tv)
case LDPT_GOLD_VERSION: case LDPT_GOLD_VERSION:
gold_version = p->tv_u.tv_val; gold_version = p->tv_u.tv_val;
break; break;
case LDPT_LINKER_OUTPUT:
linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
linker_output_set = 1;
break;
default: default:
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment