Enable math functions linking with static library for LTO

In LTO mode, if static library and dynamic library contains same
function and both libraries are passed as arguments, linker will link
the function in dynamic library no matter the sequence.  This patch
will output LTO symbol node as UNDEF if BUILT_IN_NORMAL function FNDECL
is a math function, then the function in static library will be linked
first if its sequence is ahead of the dynamic library.

gcc/ChangeLog

2019-08-14  Xiong Hu Luo  <luoxhu@linux.ibm.com>

	PR lto/91287
	* builtins.c (builtin_with_linkage_p): New function.
	* builtins.h (builtin_with_linkage_p): New function.
	* symtab.c (write_symbol): Remove redundant assert.
	* lto-streamer-out.c (symtab_node::output_to_lto_symbol_table_p):
	Remove FIXME and use builtin_with_linkage_p.

From-SVN: r274411
This commit is contained in:
Xiong Hu Luo 2019-08-14 02:18:33 +00:00 committed by Xiong Hu Luo
parent 37987c39eb
commit 5747e0c0e1
5 changed files with 109 additions and 10 deletions

View File

@ -1,3 +1,12 @@
2019-08-14 Xiong Hu Luo <luoxhu@linux.ibm.com>
PR lto/91287
* builtins.c (builtin_with_linkage_p): New function.
* builtins.h (builtin_with_linkage_p): New function.
* symtab.c (write_symbol): Remove redundant assert.
* lto-streamer-out.c (symtab_node::output_to_lto_symbol_table_p):
Remove FIXME and use builtin_with_linkage_p.
2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/91421

View File

@ -11244,3 +11244,90 @@ target_char_cst_p (tree t, char *p)
*p = (char)tree_to_uhwi (t);
return true;
}
/* Return true if the builtin DECL is implemented in a standard library.
Otherwise returns false which doesn't guarantee it is not (thus the list of
handled builtins below may be incomplete). */
bool
builtin_with_linkage_p (tree decl)
{
if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
switch (DECL_FUNCTION_CODE (decl))
{
CASE_FLT_FN (BUILT_IN_ACOS):
CASE_FLT_FN (BUILT_IN_ACOSH):
CASE_FLT_FN (BUILT_IN_ASIN):
CASE_FLT_FN (BUILT_IN_ASINH):
CASE_FLT_FN (BUILT_IN_ATAN):
CASE_FLT_FN (BUILT_IN_ATANH):
CASE_FLT_FN (BUILT_IN_ATAN2):
CASE_FLT_FN (BUILT_IN_CBRT):
CASE_FLT_FN (BUILT_IN_CEIL):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
CASE_FLT_FN (BUILT_IN_COPYSIGN):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
CASE_FLT_FN (BUILT_IN_COS):
CASE_FLT_FN (BUILT_IN_COSH):
CASE_FLT_FN (BUILT_IN_ERF):
CASE_FLT_FN (BUILT_IN_ERFC):
CASE_FLT_FN (BUILT_IN_EXP):
CASE_FLT_FN (BUILT_IN_EXP2):
CASE_FLT_FN (BUILT_IN_EXPM1):
CASE_FLT_FN (BUILT_IN_FABS):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
CASE_FLT_FN (BUILT_IN_FDIM):
CASE_FLT_FN (BUILT_IN_FLOOR):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
CASE_FLT_FN (BUILT_IN_FMA):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
CASE_FLT_FN (BUILT_IN_FMAX):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX):
CASE_FLT_FN (BUILT_IN_FMIN):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN):
CASE_FLT_FN (BUILT_IN_FMOD):
CASE_FLT_FN (BUILT_IN_FREXP):
CASE_FLT_FN (BUILT_IN_HYPOT):
CASE_FLT_FN (BUILT_IN_ILOGB):
CASE_FLT_FN (BUILT_IN_LDEXP):
CASE_FLT_FN (BUILT_IN_LGAMMA):
CASE_FLT_FN (BUILT_IN_LLRINT):
CASE_FLT_FN (BUILT_IN_LLROUND):
CASE_FLT_FN (BUILT_IN_LOG):
CASE_FLT_FN (BUILT_IN_LOG10):
CASE_FLT_FN (BUILT_IN_LOG1P):
CASE_FLT_FN (BUILT_IN_LOG2):
CASE_FLT_FN (BUILT_IN_LOGB):
CASE_FLT_FN (BUILT_IN_LRINT):
CASE_FLT_FN (BUILT_IN_LROUND):
CASE_FLT_FN (BUILT_IN_MODF):
CASE_FLT_FN (BUILT_IN_NAN):
CASE_FLT_FN (BUILT_IN_NEARBYINT):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT):
CASE_FLT_FN (BUILT_IN_NEXTAFTER):
CASE_FLT_FN (BUILT_IN_NEXTTOWARD):
CASE_FLT_FN (BUILT_IN_POW):
CASE_FLT_FN (BUILT_IN_REMAINDER):
CASE_FLT_FN (BUILT_IN_REMQUO):
CASE_FLT_FN (BUILT_IN_RINT):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
CASE_FLT_FN (BUILT_IN_ROUND):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
CASE_FLT_FN (BUILT_IN_SCALBLN):
CASE_FLT_FN (BUILT_IN_SCALBN):
CASE_FLT_FN (BUILT_IN_SIN):
CASE_FLT_FN (BUILT_IN_SINH):
CASE_FLT_FN (BUILT_IN_SINCOS):
CASE_FLT_FN (BUILT_IN_SQRT):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
CASE_FLT_FN (BUILT_IN_TAN):
CASE_FLT_FN (BUILT_IN_TANH):
CASE_FLT_FN (BUILT_IN_TGAMMA):
CASE_FLT_FN (BUILT_IN_TRUNC):
CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
return true;
default:
break;
}
return false;
}

View File

@ -150,5 +150,6 @@ extern internal_fn replacement_internal_fn (gcall *);
extern void warn_string_no_nul (location_t, const char *, tree, tree);
extern tree unterminated_array (tree, tree * = NULL, bool * = NULL);
extern bool builtin_with_linkage_p (tree);
#endif /* GCC_BUILTINS_H */

View File

@ -2642,12 +2642,6 @@ write_symbol (struct streamer_tree_cache_d *cache,
const char *comdat;
unsigned char c;
gcc_checking_assert (TREE_PUBLIC (t)
&& (TREE_CODE (t) != FUNCTION_DECL
|| !fndecl_built_in_p (t))
&& !DECL_ABSTRACT_P (t)
&& (!VAR_P (t) || !DECL_HARD_REGISTER (t)));
gcc_assert (VAR_OR_FUNCTION_DECL_P (t));
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));

View File

@ -2375,10 +2375,18 @@ symtab_node::output_to_lto_symbol_table_p (void)
first place. */
if (VAR_P (decl) && DECL_HARD_REGISTER (decl))
return false;
/* FIXME: Builtins corresponding to real functions probably should have
symbol table entries. */
if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl))
return false;
if (TREE_CODE (decl) == FUNCTION_DECL && !definition
&& fndecl_built_in_p (decl))
{
/* Builtins like those for most math functions have actual implementations
in libraries so make sure to output references into the symbol table to
make those libraries referenced. Note this is incomplete handling for
now and only covers math functions. */
if (builtin_with_linkage_p (decl))
return true;
else
return false;
}
/* We have real symbol that should be in symbol table. However try to trim
down the refernces to libraries bit more because linker will otherwise