Commit aab778d3 by H.J. Lu Committed by H.J. Lu

Don't mark IFUNC resolver as only called directly

Since IFUNC resolver is called indirectly, don't mark IFUNC resolver as
only called directly.  This patch adds ifunc_resolver to cgraph_node,
sets ifunc_resolver for ifunc attribute and checks ifunc_resolver
instead of looking up ifunc attribute.

gcc/

	PR target/85345
	* cgraph.h (cgraph_node::create): Set ifunc_resolver for ifunc
	attribute.
	(cgraph_node::create_alias): Likewise.
	(cgraph_node::get_availability): Check ifunc_resolver instead
	of looking up ifunc attribute.
	* cgraphunit.c (maybe_diag_incompatible_alias): Likewise.
	* varasm.c (do_assemble_alias): Likewise.
	(assemble_alias): Likewise.
	(default_binds_local_p_3): Likewise.
	* cgraph.h (cgraph_node): Add ifunc_resolver.
	(cgraph_node::only_called_directly_or_aliased_p): Return false
	for IFUNC resolver.
	* lto-cgraph.c (input_node): Set ifunc_resolver for ifunc
	attribute.
	* symtab.c (symtab_node::verify_base): Verify that ifunc_resolver
	is equivalent to lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)).
	(symtab_node::binds_to_current_def_p): Check ifunc_resolver
	instead of looking up ifunc attribute.

gcc/testsuite/

	PR target/85345
	* gcc.target/i386/pr85345.c: New test.

From-SVN: r260547
parent 58c2ad42
2018-05-22 H.J. Lu <hongjiu.lu@intel.com>
PR target/85345
* cgraph.h (cgraph_node::create): Set ifunc_resolver for ifunc
attribute.
(cgraph_node::create_alias): Likewise.
(cgraph_node::get_availability): Check ifunc_resolver instead
of looking up ifunc attribute.
* cgraphunit.c (maybe_diag_incompatible_alias): Likewise.
* varasm.c (do_assemble_alias): Likewise.
(assemble_alias): Likewise.
(default_binds_local_p_3): Likewise.
* cgraph.h (cgraph_node): Add ifunc_resolver.
(cgraph_node::only_called_directly_or_aliased_p): Return false
for IFUNC resolver.
* lto-cgraph.c (input_node): Set ifunc_resolver for ifunc
attribute.
* symtab.c (symtab_node::verify_base): Verify that ifunc_resolver
is equivalent to lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)).
(symtab_node::binds_to_current_def_p): Check ifunc_resolver
instead of looking up ifunc attribute.
2018-05-22 Luis Machado <luis.machado@linaro.org>
* config/aarch64/aarch64.md (*ashift<mode>_extv_bfiz): New pattern.
......
......@@ -517,6 +517,9 @@ cgraph_node::create (tree decl)
g->have_offload = true;
}
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
node->ifunc_resolver = true;
node->register_symbol ();
if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
......@@ -575,6 +578,8 @@ cgraph_node::create_alias (tree alias, tree target)
alias_node->alias = true;
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
alias_node->transparent_alias = alias_node->weakref = true;
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)))
alias_node->ifunc_resolver = true;
return alias_node;
}
......@@ -2299,7 +2304,7 @@ cgraph_node::get_availability (symtab_node *ref)
avail = AVAIL_AVAILABLE;
else if (transparent_alias)
ultimate_alias_target (&avail, ref);
else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
else if (ifunc_resolver
|| lookup_attribute ("noipa", DECL_ATTRIBUTES (decl)))
avail = AVAIL_INTERPOSABLE;
else if (!externally_visible)
......
......@@ -530,6 +530,9 @@ public:
/* Set when symbol can be streamed into bytecode for offloading. */
unsigned offloadable : 1;
/* Set when symbol is an IFUNC resolver. */
unsigned ifunc_resolver : 1;
/* Ordering of all symtab entries. */
int order;
......@@ -2886,6 +2889,7 @@ cgraph_node::only_called_directly_or_aliased_p (void)
{
gcc_assert (!global.inlined_to);
return (!force_output && !address_taken
&& !ifunc_resolver
&& !used_from_other_partition
&& !DECL_VIRTUAL_P (decl)
&& !DECL_STATIC_CONSTRUCTOR (decl)
......
......@@ -1307,7 +1307,7 @@ maybe_diag_incompatible_alias (tree alias, tree target)
tree altype = TREE_TYPE (alias);
tree targtype = TREE_TYPE (target);
bool ifunc = lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias));
bool ifunc = cgraph_node::get (alias)->ifunc_resolver;
tree funcptr = altype;
if (ifunc)
......
......@@ -1257,6 +1257,8 @@ input_node (struct lto_file_decl_data *file_data,
of ipa passes is done. Alays forcingly create a fresh node. */
node = symtab->create_empty ();
node->decl = fn_decl;
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
node->ifunc_resolver = 1;
node->register_symbol ();
}
......
......@@ -998,6 +998,13 @@ symtab_node::verify_base (void)
error ("function symbol is not function");
error_found = true;
}
else if ((lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
!= NULL)
!= dyn_cast <cgraph_node *> (this)->ifunc_resolver)
{
error ("inconsistent `ifunc' attribute");
error_found = true;
}
}
else if (is_a <varpool_node *> (this))
{
......@@ -2253,13 +2260,13 @@ symtab_node::binds_to_current_def_p (symtab_node *ref)
if (transparent_alias)
return definition
&& get_alias_target()->binds_to_current_def_p (ref);
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
if (cnode && cnode->ifunc_resolver)
return false;
if (decl_binds_to_current_def_p (decl))
return true;
/* Inline clones always binds locally. */
cgraph_node *cnode = dyn_cast <cgraph_node *> (this);
if (cnode && cnode->global.inlined_to)
return true;
......
2018-05-22 H.J. Lu <hongjiu.lu@intel.com>
PR target/85345
* gcc.target/i386/pr85345.c: New test.
2018-05-22 Luis Machado <luis.machado@linaro.org>
* gcc.target/aarch64/lsl_asr_sbfiz.c: New test.
......
/* { dg-do compile } */
/* { dg-options "-O2 -fcf-protection" } */
/* { dg-final { scan-assembler-times {\mendbr} 4 } } */
int resolver_fn = 0;
int resolved_fn = 0;
static inline void
do_it_right_at_runtime_A (void)
{
resolved_fn++;
}
static inline void
do_it_right_at_runtime_B (void)
{
resolved_fn++;
}
static inline void do_it_right_at_runtime (void);
void do_it_right_at_runtime (void)
__attribute__ ((ifunc ("resolve_do_it_right_at_runtime")));
extern int r;
static void (*resolve_do_it_right_at_runtime (void)) (void)
{
resolver_fn++;
typeof(do_it_right_at_runtime) *func;
if (r & 1)
func = do_it_right_at_runtime_A;
else
func = do_it_right_at_runtime_B;
return (void *) func;
}
int
main ()
{
do_it_right_at_runtime ();
return 0;
}
......@@ -5833,7 +5833,8 @@ do_assemble_alias (tree decl, tree target)
globalize_decl (decl);
maybe_assemble_visibility (decl);
}
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
if (TREE_CODE (decl) == FUNCTION_DECL
&& cgraph_node::get (decl)->ifunc_resolver)
{
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
if (targetm.has_ifunc_p ())
......@@ -5916,7 +5917,7 @@ assemble_alias (tree decl, tree target)
# else
if (!DECL_WEAK (decl))
{
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
if (cgraph_node::get (decl)->ifunc_resolver)
error_at (DECL_SOURCE_LOCATION (decl),
"ifunc is not supported in this configuration");
else
......@@ -7048,7 +7049,8 @@ default_binds_local_p_3 (const_tree exp, bool shlib, bool weak_dominate,
weakref alias. */
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
|| (TREE_CODE (exp) == FUNCTION_DECL
&& lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
&& cgraph_node::get (exp)
&& cgraph_node::get (exp)->ifunc_resolver))
return false;
/* Static variables are always local. */
......
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