cgraph.c (insert_new_cgraph_node_version): Use cgraph_get_node instead of cgraph_get_create_node.
2012-11-13 Sriraman Tallam <tmsriram@google.com> * cgraph.c (insert_new_cgraph_node_version): Use cgraph_get_node instead of cgraph_get_create_node. * config/i386/i386.c (ix86_get_function_versions_dispatcher): Move ifunc not supported code to the end. * class.c (mark_versions_used): Remove. (resolve_address_of_overloaded_function): Call target hook for versioned functions. Refactor to call get_function_versions_dispatcher. * decl.c (duplicate_decls): Add comments. * cp/call.c (get_function_version_dispatcher): Expose function. (mark_versions_used): Expose function. * cp/cp-tree.h (mark_versions_used): New declaration. (get_function_version_dispatcher): Ditto. * testsuite/g++.dg/mv4.C: Add require ifunc. Change error message. * testsuite/g++.dg/mv5.C: Add require ifunc. * testsuite/g++.dg/mv6.C: Add require ifunc. From-SVN: r193486
This commit is contained in:
parent
73c3ed27fc
commit
beb42d2022
|
@ -1,3 +1,10 @@
|
|||
2012-11-13 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* cgraph.c (insert_new_cgraph_node_version): Use cgraph_get_node
|
||||
instead of cgraph_get_create_node.
|
||||
* config/i386/i386.c (ix86_get_function_versions_dispatcher): Move ifunc
|
||||
not supported code to the end.
|
||||
|
||||
2012-11-13 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR tree-optimization/55253
|
||||
|
|
|
@ -206,7 +206,7 @@ insert_new_cgraph_node_version (struct cgraph_node *node)
|
|||
void
|
||||
delete_function_version (tree decl)
|
||||
{
|
||||
struct cgraph_node *decl_node = cgraph_get_create_node (decl);
|
||||
struct cgraph_node *decl_node = cgraph_get_node (decl);
|
||||
struct cgraph_function_version_info *decl_v = NULL;
|
||||
|
||||
if (decl_node == NULL)
|
||||
|
|
|
@ -28961,11 +28961,6 @@ ix86_get_function_versions_dispatcher (void *decl)
|
|||
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
|
||||
/* Right now, the dispatching is done via ifunc. */
|
||||
dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
|
||||
#else
|
||||
error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
|
||||
"Multiversioning needs ifunc which is not supported "
|
||||
"in this configuration");
|
||||
#endif
|
||||
|
||||
dispatcher_node = cgraph_get_create_node (dispatch_decl);
|
||||
gcc_assert (dispatcher_node != NULL);
|
||||
|
@ -28982,7 +28977,11 @@ ix86_get_function_versions_dispatcher (void *decl)
|
|||
it_v->dispatcher_resolver = dispatch_decl;
|
||||
it_v = it_v->next;
|
||||
}
|
||||
|
||||
#else
|
||||
error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
|
||||
"multiversioning needs ifunc which is not supported "
|
||||
"in this configuration");
|
||||
#endif
|
||||
return dispatch_decl;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
2012-11-13 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* class.c (mark_versions_used): Remove.
|
||||
(resolve_address_of_overloaded_function): Call target hook
|
||||
for versioned functions. Refactor to call
|
||||
get_function_versions_dispatcher.
|
||||
* decl.c (duplicate_decls): Add comments.
|
||||
* cp/call.c (get_function_version_dispatcher): Expose function.
|
||||
(mark_versions_used): Expose function.
|
||||
* cp/cp-tree.h (mark_versions_used): New declaration.
|
||||
(get_function_version_dispatcher): Ditto.
|
||||
|
||||
2012-11-13 Dodji Seketeli <dodji@redhat.com>
|
||||
|
||||
PR c++/54466
|
||||
|
|
|
@ -6517,7 +6517,7 @@ magic_varargs_p (tree fn)
|
|||
|
||||
/* Returns the decl of the dispatcher function if FN is a function version. */
|
||||
|
||||
static tree
|
||||
tree
|
||||
get_function_version_dispatcher (tree fn)
|
||||
{
|
||||
tree dispatcher_decl = NULL;
|
||||
|
@ -6530,8 +6530,8 @@ get_function_version_dispatcher (tree fn)
|
|||
|
||||
if (dispatcher_decl == NULL)
|
||||
{
|
||||
error_at (input_location, "Call to multiversioned function"
|
||||
" without a default is not allowed");
|
||||
error_at (input_location, "use of multiversioned function "
|
||||
"without a default");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -6543,7 +6543,7 @@ get_function_version_dispatcher (tree fn)
|
|||
/* fn is a function version dispatcher that is marked used. Mark all the
|
||||
semantically identical function versions it will dispatch as used. */
|
||||
|
||||
static void
|
||||
void
|
||||
mark_versions_used (tree fn)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
|
|
|
@ -7068,38 +7068,6 @@ pop_lang_context (void)
|
|||
{
|
||||
current_lang_name = VEC_pop (tree, current_lang_base);
|
||||
}
|
||||
|
||||
/* fn is a function version dispatcher that is marked used. Mark all the
|
||||
semantically identical function versions it will dispatch as used. */
|
||||
|
||||
static void
|
||||
mark_versions_used (tree fn)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
struct cgraph_function_version_info *node_v;
|
||||
struct cgraph_function_version_info *it_v;
|
||||
|
||||
gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
|
||||
|
||||
node = cgraph_get_node (fn);
|
||||
if (node == NULL)
|
||||
return;
|
||||
|
||||
gcc_assert (node->dispatcher_function);
|
||||
|
||||
node_v = get_cgraph_node_version (node);
|
||||
if (node_v == NULL)
|
||||
return;
|
||||
|
||||
/* All semantically identical versions are chained. Traverse and mark each
|
||||
one of them as used. */
|
||||
it_v = node_v->next;
|
||||
while (it_v != NULL)
|
||||
{
|
||||
mark_used (it_v->this_node->symbol.decl);
|
||||
it_v = it_v->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Type instantiation routines. */
|
||||
|
||||
|
@ -7315,22 +7283,13 @@ resolve_address_of_overloaded_function (tree target_type,
|
|||
|
||||
fn = TREE_PURPOSE (matches);
|
||||
|
||||
/* For multi-versioned functions, more than one match is just fine.
|
||||
Call decls_match to make sure they are different because they are
|
||||
versioned. */
|
||||
if (DECL_FUNCTION_VERSIONED (fn))
|
||||
{
|
||||
for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
|
||||
if (!DECL_FUNCTION_VERSIONED (TREE_PURPOSE (match))
|
||||
|| decls_match (fn, TREE_PURPOSE (match)))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
|
||||
if (!decls_match (fn, TREE_PURPOSE (match)))
|
||||
break;
|
||||
}
|
||||
/* For multi-versioned functions, more than one match is just fine and
|
||||
decls_match will return false as they are different. */
|
||||
for (match = TREE_CHAIN (matches); match; match = TREE_CHAIN (match))
|
||||
if (!decls_match (fn, TREE_PURPOSE (match))
|
||||
&& !targetm.target_option.function_versions
|
||||
(fn, TREE_PURPOSE (match)))
|
||||
break;
|
||||
|
||||
if (match)
|
||||
{
|
||||
|
@ -7377,17 +7336,9 @@ resolve_address_of_overloaded_function (tree target_type,
|
|||
function version at run-time. */
|
||||
if (DECL_FUNCTION_VERSIONED (fn))
|
||||
{
|
||||
tree dispatcher_decl = NULL;
|
||||
gcc_assert (targetm.get_function_versions_dispatcher);
|
||||
dispatcher_decl = targetm.get_function_versions_dispatcher (fn);
|
||||
if (!dispatcher_decl)
|
||||
{
|
||||
error_at (input_location, "Pointer to a multiversioned function"
|
||||
" without a default is not allowed");
|
||||
return error_mark_node;
|
||||
}
|
||||
retrofit_lang_decl (dispatcher_decl);
|
||||
fn = dispatcher_decl;
|
||||
fn = get_function_version_dispatcher (fn);
|
||||
if (fn == NULL)
|
||||
return error_mark_node;
|
||||
/* Mark all the versions corresponding to the dispatcher as used. */
|
||||
if (!(flags & tf_conv))
|
||||
mark_versions_used (fn);
|
||||
|
|
|
@ -4971,6 +4971,8 @@ extern bool is_list_ctor (tree);
|
|||
#ifdef ENABLE_CHECKING
|
||||
extern void validate_conversion_obstack (void);
|
||||
#endif /* ENABLE_CHECKING */
|
||||
extern void mark_versions_used (tree);
|
||||
extern tree get_function_version_dispatcher (tree);
|
||||
|
||||
/* in class.c */
|
||||
extern tree build_vfield_ref (tree, tree);
|
||||
|
|
|
@ -2307,12 +2307,15 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
|
|||
else if (DECL_PRESERVE_P (newdecl))
|
||||
DECL_PRESERVE_P (olddecl) = 1;
|
||||
|
||||
/* If the olddecl is a version, so is the newdecl. */
|
||||
/* Merge the DECL_FUNCTION_VERSIONED information. newdecl will be copied
|
||||
to olddecl and deleted. */
|
||||
if (TREE_CODE (newdecl) == FUNCTION_DECL
|
||||
&& DECL_FUNCTION_VERSIONED (olddecl))
|
||||
{
|
||||
/* Set the flag for newdecl so that it gets copied to olddecl. */
|
||||
DECL_FUNCTION_VERSIONED (newdecl) = 1;
|
||||
/* newdecl will be purged and is no longer a version. */
|
||||
/* newdecl will be purged after copying to olddecl and is no longer
|
||||
a version. */
|
||||
delete_function_version (newdecl);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2012-11-13 Sriraman Tallam <tmsriram@google.com>
|
||||
|
||||
* testsuite/g++.dg/mv4.C: Add require ifunc. Change error message.
|
||||
* testsuite/g++.dg/mv5.C: Add require ifunc.
|
||||
* testsuite/g++.dg/mv6.C: Add require ifunc.
|
||||
|
||||
2012-11-13 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR tree-optimization/55253
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
and its pointer is taken. */
|
||||
|
||||
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O2 -mno-sse -mno-popcnt" } */
|
||||
|
||||
int __attribute__ ((target ("sse")))
|
||||
|
@ -18,6 +19,6 @@ foo ()
|
|||
|
||||
int main ()
|
||||
{
|
||||
int (*p)() = &foo; /* { dg-error "Pointer to a multiversioned function without a default is not allowed" {} } */
|
||||
int (*p)() = &foo; /* { dg-error "use of multiversioned function without a default" {} } */
|
||||
return (*p)();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
marked comdat with inline keyword. */
|
||||
|
||||
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
/* { dg-options "-O2 -mno-popcnt" } */
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Test to check if member version multiversioning works correctly. */
|
||||
|
||||
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
|
||||
/* { dg-require-ifunc "" } */
|
||||
|
||||
class Foo
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue