diff options
author | Sriraman Tallam <tmsriram@google.com> | 2012-11-13 21:56:30 +0000 |
---|---|---|
committer | Sriraman Tallam <tmsriram@gcc.gnu.org> | 2012-11-13 21:56:30 +0000 |
commit | beb42d2022899f07712a3537beedbedd13f67fab (patch) | |
tree | e0a478402322716f4df3e0475249558057df7da6 | |
parent | 73c3ed27fc6dc454b282d6e0d3fa76dbbd18e6dd (diff) | |
download | gcc-beb42d2022899f07712a3537beedbedd13f67fab.zip gcc-beb42d2022899f07712a3537beedbedd13f67fab.tar.gz gcc-beb42d2022899f07712a3537beedbedd13f67fab.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cgraph.c | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 11 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/cp/call.c | 8 | ||||
-rw-r--r-- | gcc/cp/class.c | 69 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
-rw-r--r-- | gcc/cp/decl.c | 7 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/mv4.C | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/mv5.C | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/mv6.C | 1 |
12 files changed, 56 insertions, 73 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32b0102..4966b5dc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 556eaff..1969576 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3af1cf8..de94d4b 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0f23cbc..8d12568 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4373bce..bbeea85 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d3d9aed..0665e90 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index be7bc0b..7dd6679 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 420937e..115c567 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 41a91af..fec239c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 diff --git a/gcc/testsuite/g++.dg/mv4.C b/gcc/testsuite/g++.dg/mv4.C index 1a72906..ac5c548 100644 --- a/gcc/testsuite/g++.dg/mv4.C +++ b/gcc/testsuite/g++.dg/mv4.C @@ -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)(); } diff --git a/gcc/testsuite/g++.dg/mv5.C b/gcc/testsuite/g++.dg/mv5.C index 33d7280..cac6d04 100644 --- a/gcc/testsuite/g++.dg/mv5.C +++ b/gcc/testsuite/g++.dg/mv5.C @@ -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" } */ diff --git a/gcc/testsuite/g++.dg/mv6.C b/gcc/testsuite/g++.dg/mv6.C index 7e5aa29..a2cde53 100644 --- a/gcc/testsuite/g++.dg/mv6.C +++ b/gcc/testsuite/g++.dg/mv6.C @@ -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 { |