diff options
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r-- | gcc/config/i386/i386.c | 101 |
1 files changed, 59 insertions, 42 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b466a4f..08eb06c 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 |