summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortmsriram <tmsriram@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-27 01:58:06 +0000
committertmsriram <tmsriram@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-27 01:58:06 +0000
commitc87676637f095c8232e0e100375aefa8f94cf911 (patch)
tree6ecc2e00fdb5157210f90bdc5849eedd4a227257
parent4b5b792d796c400a31faee89eeeb2d6ac03b98b4 (diff)
downloadppe42-gcc-c87676637f095c8232e0e100375aefa8f94cf911.tar.gz
ppe42-gcc-c87676637f095c8232e0e100375aefa8f94cf911.zip
Before this patch, function multiversioning determines that two functions
are different by comparing the arch type and isa flags that are set after the target string is processed. This leads to cases where the versions become identical when the command-line target options are altered. This patch modifies the function version determination to just compare the target string. 2012-12-27 Sriraman Tallam <tmsriram@google.com> * doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document new target hook. * doc/tm.texi: Regenerate. * c-family/c-common.c (handle_target_attribute): Retain target attribute for targets that support versioning. * target.def (supports_function_versions): New hook. * cp/class.c (add_method): Remove calls to DECL_FUNCTION_SPECIFIC_TARGET. * config/i386/i386.c (ix86_function_versions): Use target string to check for function versions instead of target flags. * (ix86_supports_function_versions): New function. * (is_function_default_version): Check target string. * TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro. 2012-12-27 Sriraman Tallam <tmsriram@google.com> * testsuite/g++.dg/mv1.C: Remove target options. * testsuite/g++.dg/mv2.C: Ditto. * testsuite/g++.dg/mv3.C: Ditto. * testsuite/g++.dg/mv4.C: Ditto. * testsuite/g++.dg/mv5.C: Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194730 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/c-family/c-common.c6
-rw-r--r--gcc/config/i386/i386.c101
-rw-r--r--gcc/cp/class.c2
-rw-r--r--gcc/doc/tm.texi5
-rw-r--r--gcc/doc/tm.texi.in5
-rw-r--r--gcc/target.def8
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/mv1.C2
-rw-r--r--gcc/testsuite/g++.dg/mv2.C2
-rw-r--r--gcc/testsuite/g++.dg/mv3.C2
-rw-r--r--gcc/testsuite/g++.dg/mv4.C2
-rw-r--r--gcc/testsuite/g++.dg/mv5.C2
13 files changed, 114 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 651ba4835b6..148388d4aa9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,26 @@
+<<<<<<< .mine
+2012-12-26 Sriraman Tallam <tmsriram@google.com>
+
+ * doc/tm.texi.in (TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS): Document
+ new target hook.
+ * doc/tm.texi: Regenerate.
+ * c-family/c-common.c (handle_target_attribute): Retain target attribute
+ for targets that support versioning.
+ * target.def (supports_function_versions): New hook.
+ * cp/class.c (add_method): Remove calls
+ to DECL_FUNCTION_SPECIFIC_TARGET.
+ * config/i386/i386.c (ix86_function_versions): Use target string
+ to check for function versions instead of target flags.
+ * (ix86_supports_function_versions): New function.
+ * (is_function_default_version): Check target string.
+ * TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS: New macro.
+
+=======
2012-12-27 Steven Bosscher <steven@gcc.gnu.org>
* cgraph.c (verify_cgraph_node): Don't allocate/free visited_nodes set.
+>>>>>>> .r194729
2012-12-25 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR target/53789
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 872a6a0feed..012751330f3 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -8742,8 +8742,12 @@ handle_target_attribute (tree *node, tree name, tree args, int flags,
warning (OPT_Wattributes, "%qE attribute ignored", name);
*no_add_attrs = true;
}
+ /* Do not strip invalid target attributes for targets which support function
+ multiversioning as the target string is used to determine versioned
+ functions. */
else if (! targetm.target_option.valid_attribute_p (*node, name, args,
- flags))
+ flags)
+ && ! targetm.target_option.supports_function_versions ())
*no_add_attrs = true;
return NULL_TREE;
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b466a4fbbdf..08eb06cded8 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -28945,47 +28945,6 @@ dispatch_function_versions (tree dispatch_decl,
return 0;
}
-/* This function returns true if FN1 and FN2 are versions of the same function,
- that is, the targets of the function decls are different. This assumes
- that FN1 and FN2 have the same signature. */
-
-static bool
-ix86_function_versions (tree fn1, tree fn2)
-{
- tree attr1, attr2;
- struct cl_target_option *target1, *target2;
-
- if (TREE_CODE (fn1) != FUNCTION_DECL
- || TREE_CODE (fn2) != FUNCTION_DECL)
- return false;
-
- attr1 = DECL_FUNCTION_SPECIFIC_TARGET (fn1);
- attr2 = DECL_FUNCTION_SPECIFIC_TARGET (fn2);
-
- /* Atleast one function decl should have target attribute specified. */
- if (attr1 == NULL_TREE && attr2 == NULL_TREE)
- return false;
-
- if (attr1 == NULL_TREE)
- attr1 = target_option_default_node;
- else if (attr2 == NULL_TREE)
- attr2 = target_option_default_node;
-
- target1 = TREE_TARGET_OPTION (attr1);
- target2 = TREE_TARGET_OPTION (attr2);
-
- /* target1 and target2 must be different in some way. */
- if (target1->x_ix86_isa_flags == target2->x_ix86_isa_flags
- && target1->x_target_flags == target2->x_target_flags
- && target1->arch == target2->arch
- && target1->tune == target2->tune
- && target1->x_ix86_fpmath == target2->x_ix86_fpmath
- && target1->branch_cost == target2->branch_cost)
- return false;
-
- return true;
-}
-
/* Comparator function to be used in qsort routine to sort attribute
specification strings to "target". */
@@ -29098,6 +29057,60 @@ ix86_mangle_function_version_assembler_name (tree decl, tree id)
return get_identifier (assembler_name);
}
+/* This function returns true if FN1 and FN2 are versions of the same function,
+ that is, the target strings of the function decls are different. This assumes
+ that FN1 and FN2 have the same signature. */
+
+static bool
+ix86_function_versions (tree fn1, tree fn2)
+{
+ tree attr1, attr2;
+ const char *attr_str1, *attr_str2;
+ char *target1, *target2;
+ bool result;
+
+ if (TREE_CODE (fn1) != FUNCTION_DECL
+ || TREE_CODE (fn2) != FUNCTION_DECL)
+ return false;
+
+ attr1 = lookup_attribute ("target", DECL_ATTRIBUTES (fn1));
+ attr2 = lookup_attribute ("target", DECL_ATTRIBUTES (fn2));
+
+ /* At least one function decl should have the target attribute specified. */
+ if (attr1 == NULL_TREE && attr2 == NULL_TREE)
+ return false;
+
+ /* If one function does not have a target attribute, these are versions. */
+ if (attr1 == NULL_TREE || attr2 == NULL_TREE)
+ return true;
+
+ attr_str1 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr1)));
+ attr_str2 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr2)));
+
+ target1 = sorted_attr_string (attr_str1);
+ target2 = sorted_attr_string (attr_str2);
+
+ /* The sorted target strings must be different for fn1 and fn2
+ to be versions. */
+ if (strcmp (target1, target2) == 0)
+ result = false;
+ else
+ result = true;
+
+ free (target1);
+ free (target2);
+
+ return result;
+}
+
+/* This target supports function multiversioning. */
+
+static bool
+ix86_supports_function_versions (void)
+{
+ return true;
+}
+
static tree
ix86_mangle_decl_assembler_name (tree decl, tree id)
{
@@ -29195,7 +29208,7 @@ is_function_default_version (const tree decl)
{
return (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_FUNCTION_VERSIONED (decl)
- && DECL_FUNCTION_SPECIFIC_TARGET (decl) == NULL_TREE);
+ && lookup_attribute ("target", DECL_ATTRIBUTES (decl)) == NULL_TREE);
}
/* Make a dispatcher declaration for the multi-versioned function DECL.
@@ -42463,6 +42476,10 @@ ix86_memmodel_check (unsigned HOST_WIDE_INT val)
#undef TARGET_OPTION_FUNCTION_VERSIONS
#define TARGET_OPTION_FUNCTION_VERSIONS ix86_function_versions
+#undef TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
+#define TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS \
+ ix86_supports_function_versions
+
#undef TARGET_CAN_INLINE_P
#define TARGET_CAN_INLINE_P ix86_can_inline_p
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 82b2c0a3810..0aecabb380e 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1096,8 +1096,6 @@ add_method (tree type, tree method, tree using_decl)
&& TREE_CODE (method) == FUNCTION_DECL
&& !DECL_EXTERN_C_P (fn)
&& !DECL_EXTERN_C_P (method)
- && (DECL_FUNCTION_SPECIFIC_TARGET (fn)
- || DECL_FUNCTION_SPECIFIC_TARGET (method))
&& targetm.target_option.function_versions (fn, method))
{
/* Mark functions as versions if necessary. Modify the mangled
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 75aa8672758..55a103700f6 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -9909,6 +9909,11 @@ different target specific attributes, that is, they are compiled for
different target machines.
@end deftypefn
+@deftypefn {Target Hook} bool TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS (void)
+This target hook returns @code{true} if the target supports function
+multiversioning.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_CAN_INLINE_P (tree @var{caller}, tree @var{callee})
This target hook returns @code{false} if the @var{caller} function
cannot inline @var{callee}, based on target specific information. By
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 95fab189c70..e820f77be45 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -9770,6 +9770,11 @@ different target specific attributes, that is, they are compiled for
different target machines.
@end deftypefn
+@hook TARGET_OPTION_SUPPORTS_FUNCTION_VERSIONS
+This target hook returns @code{true} if the target supports function
+multiversioning.
+@end deftypefn
+
@hook TARGET_CAN_INLINE_P
This target hook returns @code{false} if the @var{caller} function
cannot inline @var{callee}, based on target specific information. By
diff --git a/gcc/target.def b/gcc/target.def
index c5bbfae6f18..79bb955a05e 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2833,6 +2833,14 @@ DEFHOOK
bool, (tree decl1, tree decl2),
hook_bool_tree_tree_false)
+/* This function returns true if the target supports function
+ multiversioning. */
+DEFHOOK
+(supports_function_versions,
+ "",
+ bool, (void),
+ hool_bool_void_false)
+
/* Function to determine if one function can inline another function. */
#undef HOOK_PREFIX
#define HOOK_PREFIX "TARGET_"
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 59f344106c1..0d97252967a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2012-12-27 Sriraman Tallam <tmsriram@google.com>
+
+ * testsuite/g++.dg/mv1.C: Remove target options.
+ * testsuite/g++.dg/mv2.C: Ditto.
+ * testsuite/g++.dg/mv3.C: Ditto.
+ * testsuite/g++.dg/mv4.C: Ditto.
+ * testsuite/g++.dg/mv5.C: Ditto.
+
2012-12-26 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/55539
diff --git a/gcc/testsuite/g++.dg/mv1.C b/gcc/testsuite/g++.dg/mv1.C
index 150b4511267..bad0c4496d3 100644
--- a/gcc/testsuite/g++.dg/mv1.C
+++ b/gcc/testsuite/g++.dg/mv1.C
@@ -1,7 +1,7 @@
/* Test case to check if Multiversioning works. */
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-require-ifunc "" } */
-/* { dg-options "-O2 -fPIC -march=x86-64 -mno-avx -mno-popcnt" } */
+/* { dg-options "-O2 -fPIC" } */
#include <assert.h>
diff --git a/gcc/testsuite/g++.dg/mv2.C b/gcc/testsuite/g++.dg/mv2.C
index f94877a674f..baaa5da350a 100644
--- a/gcc/testsuite/g++.dg/mv2.C
+++ b/gcc/testsuite/g++.dg/mv2.C
@@ -2,7 +2,7 @@
dispatching order when versions are for various ISAs. */
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-require-ifunc "" } */
-/* { dg-options "-O2 -mno-sse -mno-mmx -mno-popcnt -mno-avx" } */
+/* { dg-options "-O2" } */
#include <assert.h>
diff --git a/gcc/testsuite/g++.dg/mv3.C b/gcc/testsuite/g++.dg/mv3.C
index c7088f2b013..ec2aa1ffec2 100644
--- a/gcc/testsuite/g++.dg/mv3.C
+++ b/gcc/testsuite/g++.dg/mv3.C
@@ -10,7 +10,7 @@
test should pass. */
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O2 -mno-sse -mno-popcnt" } */
+/* { dg-options "-O2" } */
int __attribute__ ((target ("sse")))
diff --git a/gcc/testsuite/g++.dg/mv4.C b/gcc/testsuite/g++.dg/mv4.C
index ac5c5481c66..ff1cc2f63f4 100644
--- a/gcc/testsuite/g++.dg/mv4.C
+++ b/gcc/testsuite/g++.dg/mv4.C
@@ -4,7 +4,7 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
/* { dg-require-ifunc "" } */
-/* { dg-options "-O2 -mno-sse -mno-popcnt" } */
+/* { dg-options "-O2" } */
int __attribute__ ((target ("sse")))
foo ()
diff --git a/gcc/testsuite/g++.dg/mv5.C b/gcc/testsuite/g++.dg/mv5.C
index cac6d04e2e3..93daab650e0 100644
--- a/gcc/testsuite/g++.dg/mv5.C
+++ b/gcc/testsuite/g++.dg/mv5.C
@@ -3,7 +3,7 @@
/* { dg-do run { target i?86-*-* x86_64-*-* } } */
/* { dg-require-ifunc "" } */
-/* { dg-options "-O2 -mno-popcnt" } */
+/* { dg-options "-O2" } */
/* Default version. */
OpenPOWER on IntegriCloud