diff --git a/contrib/download_prerequisites b/contrib/download_prerequisites index b83fcc9db5dde..ce7efe1d1edc9 100755 --- a/contrib/download_prerequisites +++ b/contrib/download_prerequisites @@ -33,7 +33,11 @@ mpc='mpc-1.2.1.tar.gz' isl='isl-0.24.tar.bz2' gettext='gettext-0.22.tar.gz' -base_url='http://gcc.gnu.org/pub/gcc/infrastructure/' +#base_url='http://gcc.gnu.org/pub/gcc/infrastructure/' +# We use rust-lang mirrors because the GCC infrastructure is unreliable. +# When dependencies are changed, we have to modify our mirrors. +# Please contact t-infra for that. +base_url='https://ci-mirrors.rust-lang.org/rustc/gcc/' echo_archives() { echo "${gettext}" diff --git a/gcc/config/i386/i386-rust-and-jit.inc b/gcc/config/i386/i386-rust-and-jit.inc index 998f44cfa3f52..0a701a0ba179e 100644 --- a/gcc/config/i386/i386-rust-and-jit.inc +++ b/gcc/config/i386/i386-rust-and-jit.inc @@ -91,3 +91,5 @@ if (TARGET_CMPXCHG16B) ADD_TARGET_INFO ("target_feature", "cmpxchg16b"); if (TARGET_MOVBE) ADD_TARGET_INFO ("target_feature", "movbe"); +if (TARGET_80387) + ADD_TARGET_INFO ("target_feature", "x87"); diff --git a/gcc/jit/dummy-frontend.cc b/gcc/jit/dummy-frontend.cc index eedfbcb4c7499..4db49710a886c 100644 --- a/gcc/jit/dummy-frontend.cc +++ b/gcc/jit/dummy-frontend.cc @@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see #include "config.h" #include "system.h" #include "coretypes.h" +#include "c-family/c-common.h" #include "target.h" #include "jit-playback.h" #include "stor-layout.h" @@ -43,107 +44,6 @@ using namespace gcc::jit; /* Attribute handling. */ -static tree handle_alias_attribute (tree *, tree, tree, int, bool *); -static tree handle_always_inline_attribute (tree *, tree, tree, int, - bool *); -static tree handle_cold_attribute (tree *, tree, tree, int, bool *); -static tree handle_const_attribute (tree *, tree, tree, int, bool *); -static tree handle_fnspec_attribute (tree *, tree, tree, int, bool *); -static tree handle_format_arg_attribute (tree *, tree, tree, int, bool *); -static tree handle_format_attribute (tree *, tree, tree, int, bool *); -static tree handle_leaf_attribute (tree *, tree, tree, int, bool *); -static tree handle_malloc_attribute (tree *, tree, tree, int, bool *); -static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); -static tree handle_nonnull_attribute (tree *, tree, tree, int, bool *); -static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); -static tree handle_nothrow_attribute (tree *, tree, tree, int, bool *); -static tree handle_novops_attribute (tree *, tree, tree, int, bool *); -static tree handle_patchable_function_entry_attribute (tree *, tree, tree, - int, bool *); -static tree handle_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *); -static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *); -static tree handle_target_attribute (tree *, tree, tree, int, bool *); -static tree handle_transaction_pure_attribute (tree *, tree, tree, int, bool *); -static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *); -static tree handle_used_attribute (tree *, tree, tree, int, bool *); -static tree handle_visibility_attribute (tree *, tree, tree, int, - bool *); -static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ; - -static tree ignore_attribute (tree *, tree, tree, int, bool *); - -/* Helper to define attribute exclusions. */ -#define ATTR_EXCL(name, function, type, variable) \ - { name, function, type, variable } - -/* Define attributes that are mutually exclusive with one another. */ -static const struct attribute_spec::exclusions attr_noreturn_exclusions[] = -{ - ATTR_EXCL ("alloc_align", true, true, true), - ATTR_EXCL ("alloc_size", true, true, true), - ATTR_EXCL ("const", true, true, true), - ATTR_EXCL ("malloc", true, true, true), - ATTR_EXCL ("pure", true, true, true), - ATTR_EXCL ("returns_twice", true, true, true), - ATTR_EXCL ("warn_unused_result", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_returns_twice_exclusions[] = -{ - ATTR_EXCL ("noreturn", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -/* Exclusions that apply to attribute alloc_align, alloc_size, and malloc. */ -static const struct attribute_spec::exclusions attr_alloc_exclusions[] = -{ - ATTR_EXCL ("const", true, true, true), - ATTR_EXCL ("noreturn", true, true, true), - ATTR_EXCL ("pure", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_const_pure_exclusions[] = -{ - ATTR_EXCL ("const", true, true, true), - ATTR_EXCL ("alloc_align", true, true, true), - ATTR_EXCL ("alloc_size", true, true, true), - ATTR_EXCL ("malloc", true, true, true), - ATTR_EXCL ("noreturn", true, true, true), - ATTR_EXCL ("pure", true, true, true), - ATTR_EXCL (NULL, false, false, false) -}; - -static const struct attribute_spec::exclusions attr_always_inline_exclusions[] = -{ - ATTR_EXCL ("noinline", true, true, true), - ATTR_EXCL ("target_clones", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -extern const struct attribute_spec::exclusions attr_cold_hot_exclusions[] = -{ - ATTR_EXCL ("cold", true, true, true), - ATTR_EXCL ("hot", true, true, true), - ATTR_EXCL (NULL, false, false, false) -}; - -static const struct attribute_spec::exclusions attr_noinline_exclusions[] = -{ - ATTR_EXCL ("always_inline", true, true, true), - ATTR_EXCL ("gnu_inline", true, true, true), - ATTR_EXCL (NULL, false, false, false), -}; - -static const struct attribute_spec::exclusions attr_target_exclusions[] = -{ - ATTR_EXCL ("target_clones", TARGET_HAS_FMV_TARGET_ATTRIBUTE, - TARGET_HAS_FMV_TARGET_ATTRIBUTE, TARGET_HAS_FMV_TARGET_ATTRIBUTE), - ATTR_EXCL (NULL, false, false, false), -}; - /* These variables act as a cache for the target builtins. This is needed in order to be able to type-check the calls since we can only get those types in the playback phase while we need them in the recording phase. */ @@ -152,98 +52,10 @@ std::unordered_map target_function_types {}; recording::context target_builtins_ctxt{NULL}; -/* Table of machine-independent attributes supported in libgccjit. */ -static const attribute_spec jit_gnu_attributes[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, - affects_type_identity, handler, exclude } */ - { "alias", 1, 1, true, false, false, false, - handle_alias_attribute, NULL }, - { "always_inline", 0, 0, true, false, false, false, - handle_always_inline_attribute, - attr_always_inline_exclusions }, - { "cold", 0, 0, true, false, false, false, - handle_cold_attribute, - attr_cold_hot_exclusions }, - /* The same comments as for noreturn attributes apply to const ones. */ - { "const", 0, 0, true, false, false, false, - handle_const_attribute, - attr_const_pure_exclusions }, - { "fn spec", 1, 1, false, true, true, false, - handle_fnspec_attribute, NULL }, - - { "leaf", 0, 0, true, false, false, false, - handle_leaf_attribute, NULL }, - { "malloc", 0, 0, true, false, false, false, - handle_malloc_attribute, attr_alloc_exclusions }, - { "noreturn", 0, 0, true, false, false, false, - handle_noreturn_attribute, - attr_noreturn_exclusions }, - { "no vops", 0, 0, true, false, false, false, - handle_novops_attribute, NULL }, - { "noinline", 0, 0, true, false, false, false, - handle_noinline_attribute, - attr_noinline_exclusions }, - { "nonnull", 0, -1, false, true, true, false, - handle_nonnull_attribute, NULL }, - { "nothrow", 0, 0, true, false, false, false, - handle_nothrow_attribute, NULL }, - { "patchable_function_entry", 1, 2, true, false, false, false, - handle_patchable_function_entry_attribute, - NULL }, - { "pure", 0, 0, true, false, false, false, - handle_pure_attribute, - attr_const_pure_exclusions }, - { "returns_twice", 0, 0, true, false, false, false, - handle_returns_twice_attribute, - attr_returns_twice_exclusions }, - { "sentinel", 0, 1, false, true, true, false, - handle_sentinel_attribute, NULL }, - { "target", 1, -1, true, false, false, false, - handle_target_attribute, attr_target_exclusions }, - { "type generic", 0, 0, false, true, true, false, - handle_type_generic_attribute, NULL }, - { "transaction_pure", 0, 0, false, true, true, false, - handle_transaction_pure_attribute, NULL }, - { "used", 0, 0, true, false, false, false, - handle_used_attribute, NULL }, - { "visibility", 1, 1, false, false, false, false, - handle_visibility_attribute, NULL }, - { "weak", 0, 0, true, false, false, false, - handle_weak_attribute, NULL }, - /* For internal use only. The leading '*' both prevents its usage in - source code and signals that it may be overridden by machine tables. */ - { "*tm regparm", 0, 0, false, true, true, false, - ignore_attribute, NULL }, -}; - -static const scoped_attribute_specs jit_gnu_attribute_table = -{ - "gnu", { jit_gnu_attributes } -}; - -/* Give the specifications for the format attributes, used by C and all - descendants. */ - -static const attribute_spec jit_format_attributes[] = -{ - /* { name, min_len, max_len, decl_req, type_req, fn_type_req, - affects_type_identity, handler, exclude } */ - { "format", 3, 3, false, true, true, false, - handle_format_attribute, NULL }, - { "format_arg", 1, 1, false, true, true, false, - handle_format_arg_attribute, NULL } -}; - -static const scoped_attribute_specs jit_format_attribute_table = -{ - "gnu", { jit_format_attributes } -}; - static const scoped_attribute_specs *const jit_attribute_table[] = { - &jit_gnu_attribute_table, - &jit_format_attribute_table + &c_common_gnu_attribute_table, + &c_common_format_attribute_table }; char* jit_personality_func_name = NULL; @@ -260,693 +72,6 @@ jit_preserve_from_gc (tree t) jit_gc_root = tree_cons (NULL_TREE, t, jit_gc_root); } -/* Attribute handlers. */ - -/* Handle a "noreturn" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_noreturn_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - tree type = TREE_TYPE (*node); - - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_THIS_VOLATILE (*node) = 1; - else if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) - TREE_TYPE (*node) - = build_pointer_type - (build_type_variant (TREE_TYPE (type), - TYPE_READONLY (TREE_TYPE (type)), 1)); - else - gcc_unreachable (); - - return NULL_TREE; -} - -/* Handle a "leaf" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_leaf_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - if (!TREE_PUBLIC (*node)) - { - warning (OPT_Wattributes, "%qE attribute has no effect on unit local functions", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "const" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_const_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree type = TREE_TYPE (*node); - - /* See FIXME comment on noreturn in c_common_attribute_table. */ - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_READONLY (*node) = 1; - else if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) - TREE_TYPE (*node) - = (build_qualified_type - (build_pointer_type - (build_type_variant (TREE_TYPE (type), 1, - TREE_THIS_VOLATILE (TREE_TYPE (type)))), - TYPE_QUALS (type))); - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - - -/* Handle a "malloc" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_malloc_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))) - DECL_IS_MALLOC (*node) = 1; - else - gcc_unreachable (); - - return NULL_TREE; -} - - -/* Handle a "pure" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_pure_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_PURE_P (*node) = 1; - else - gcc_unreachable (); - - return NULL_TREE; -} - - -/* Handle a "no vops" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_novops_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool *ARG_UNUSED (no_add_attrs)) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - DECL_IS_NOVOPS (*node) = 1; - return NULL_TREE; -} - - -/* Helper for nonnull attribute handling; fetch the operand number - from the attribute argument list. */ - -static bool -get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp) -{ - /* Verify the arg number is a constant. */ - if (!tree_fits_uhwi_p (arg_num_expr)) - return false; - - *valp = TREE_INT_CST_LOW (arg_num_expr); - return true; -} - -/* Handle the "nonnull" attribute. */ - -static tree -handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), - tree args, int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - tree type = *node; - - /* If no arguments are specified, all pointer arguments should be - non-null. Verify a full prototype is given so that the arguments - will have the correct types when we actually check them later. - Avoid diagnosing type-generic built-ins since those have no - prototype. */ - if (!args) - { - gcc_assert (prototype_p (type) - || !TYPE_ATTRIBUTES (type) - || lookup_attribute ("type generic", TYPE_ATTRIBUTES (type))); - - return NULL_TREE; - } - - /* Argument list specified. Verify that each argument number references - a pointer argument. */ - for (; args; args = TREE_CHAIN (args)) - { - tree argument; - unsigned HOST_WIDE_INT arg_num = 0, ck_num; - - if (!get_nonnull_operand (TREE_VALUE (args), &arg_num)) - gcc_unreachable (); - - argument = TYPE_ARG_TYPES (type); - if (argument) - { - for (ck_num = 1; ; ck_num++) - { - if (!argument || ck_num == arg_num) - break; - argument = TREE_CHAIN (argument); - } - - gcc_assert (argument - && TREE_CODE (TREE_VALUE (argument)) == POINTER_TYPE); - } - } - - return NULL_TREE; -} - - -/* Handle a "nothrow" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_nothrow_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - TREE_NOTHROW (*node) = 1; - else - gcc_unreachable (); - - return NULL_TREE; -} - - -/* Handle a "sentinel" attribute. */ - -static tree -handle_sentinel_attribute (tree *node, tree ARG_UNUSED (name), tree args, - int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - gcc_assert (stdarg_p (*node)); - - if (args) - { - tree position = TREE_VALUE (args); - gcc_assert (TREE_CODE (position) == INTEGER_CST); - if (tree_int_cst_lt (position, integer_zero_node)) - gcc_unreachable (); - } - - return NULL_TREE; -} - -/* Handle a "type_generic" attribute. */ - -static tree -handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - /* Ensure we have a function type. */ - gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); - - /* Ensure we have a variadic function. */ - gcc_assert (!prototype_p (*node) || stdarg_p (*node)); - - return NULL_TREE; -} - -/* Handle a "transaction_pure" attribute. */ - -static tree -handle_transaction_pure_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - /* Ensure we have a function type. */ - gcc_assert (TREE_CODE (*node) == FUNCTION_TYPE); - - return NULL_TREE; -} - -/* Handle a "returns_twice" attribute. */ - -static tree -handle_returns_twice_attribute (tree *node, tree ARG_UNUSED (name), - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - gcc_assert (TREE_CODE (*node) == FUNCTION_DECL); - - DECL_IS_RETURNS_TWICE (*node) = 1; - - return NULL_TREE; -} - -static tree -handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *) -{ - /* Nothing to be done here. */ - return NULL_TREE; -} - -/* Ignore the given attribute. Used when this attribute may be usefully - overridden by the target, but is not used generically. */ - -static tree -ignore_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - *no_add_attrs = true; - return NULL_TREE; -} - -/* Handle a "format" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_format_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - *no_add_attrs = true; - return NULL_TREE; -} - - -/* Handle a "format_arg" attribute; arguments as in - struct attribute_spec.handler. */ - -tree -handle_format_arg_attribute (tree * ARG_UNUSED (node), tree ARG_UNUSED (name), - tree ARG_UNUSED (args), int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - *no_add_attrs = true; - return NULL_TREE; -} - - -/* Handle a "fn spec" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_fnspec_attribute (tree *node ATTRIBUTE_UNUSED, tree ARG_UNUSED (name), - tree args, int ARG_UNUSED (flags), - bool *no_add_attrs ATTRIBUTE_UNUSED) -{ - gcc_assert (args - && TREE_CODE (TREE_VALUE (args)) == STRING_CST - && !TREE_CHAIN (args)); - return NULL_TREE; -} - -/* Handle an "visibility" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_visibility_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), - bool *ARG_UNUSED (no_add_attrs)) -{ - tree decl = *node; - tree id = TREE_VALUE (args); - enum symbol_visibility vis; - - if (TYPE_P (*node)) - { - if (TREE_CODE (*node) == ENUMERAL_TYPE) - /* OK. */; - else if (!RECORD_OR_UNION_TYPE_P (*node)) - { - warning (OPT_Wattributes, "%qE attribute ignored on non-class types", - name); - return NULL_TREE; - } - else if (TYPE_FIELDS (*node)) - { - error ("%qE attribute ignored because %qT is already defined", - name, *node); - return NULL_TREE; - } - } - else if (decl_function_context (decl) != 0 || !TREE_PUBLIC (decl)) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - return NULL_TREE; - } - - if (TREE_CODE (id) != STRING_CST) - { - error ("visibility argument not a string"); - return NULL_TREE; - } - - /* If this is a type, set the visibility on the type decl. */ - if (TYPE_P (decl)) - { - decl = TYPE_NAME (decl); - if (!decl) - return NULL_TREE; - if (TREE_CODE (decl) == IDENTIFIER_NODE) - { - warning (OPT_Wattributes, "%qE attribute ignored on types", - name); - return NULL_TREE; - } - } - - if (strcmp (TREE_STRING_POINTER (id), "default") == 0) - vis = VISIBILITY_DEFAULT; - else if (strcmp (TREE_STRING_POINTER (id), "internal") == 0) - vis = VISIBILITY_INTERNAL; - else if (strcmp (TREE_STRING_POINTER (id), "hidden") == 0) - vis = VISIBILITY_HIDDEN; - else if (strcmp (TREE_STRING_POINTER (id), "protected") == 0) - vis = VISIBILITY_PROTECTED; - else - { - error ("attribute %qE argument must be one of %qs, %qs, %qs, or %qs", - name, "default", "hidden", "protected", "internal"); - vis = VISIBILITY_DEFAULT; - } - - if (DECL_VISIBILITY_SPECIFIED (decl) - && vis != DECL_VISIBILITY (decl)) - { - tree attributes = (TYPE_P (*node) - ? TYPE_ATTRIBUTES (*node) - : DECL_ATTRIBUTES (decl)); - if (lookup_attribute ("visibility", attributes)) - error ("%qD redeclared with different visibility", decl); - else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllimport", attributes)) - error ("%qD was declared %qs which implies default visibility", - decl, "dllimport"); - else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && lookup_attribute ("dllexport", attributes)) - error ("%qD was declared %qs which implies default visibility", - decl, "dllexport"); - } - - DECL_VISIBILITY (decl) = vis; - DECL_VISIBILITY_SPECIFIED (decl) = 1; - - /* Go ahead and attach the attribute to the node as well. This is needed - so we can determine whether we have VISIBILITY_DEFAULT because the - visibility was not specified, or because it was explicitly overridden - from the containing scope. */ - - return NULL_TREE; -} - -/* Handle a "always_inline" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_always_inline_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - { - /* Set the attribute and mark it for disregarding inline - limits. */ - DECL_DISREGARD_INLINE_LIMITS (*node) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "cold" and attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - || TREE_CODE (*node) == LABEL_DECL) - { - /* Attribute cold processing is done later with lookup_attribute. */ - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "noinline" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_noinline_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - if (TREE_CODE (*node) == FUNCTION_DECL) - DECL_UNINLINABLE (*node) = 1; - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle a "weak" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_weak_attribute (tree *node, tree name, - tree ARG_UNUSED (args), - int ARG_UNUSED (flags), - bool * ARG_UNUSED (no_add_attrs)) -{ - if (TREE_CODE (*node) == FUNCTION_DECL - && DECL_DECLARED_INLINE_P (*node)) - { - warning (OPT_Wattributes, "inline function %q+D declared weak", *node); - *no_add_attrs = true; - } - else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (*node))) - { - error ("indirect function %q+D cannot be declared weak", *node); - *no_add_attrs = true; - return NULL_TREE; - } - else if (VAR_OR_FUNCTION_DECL_P (*node)) - declare_weak (*node); - else - warning (OPT_Wattributes, "%qE attribute ignored", name); - - return NULL_TREE; -} - -/* Handle a "target" attribute. */ - -static tree -handle_target_attribute (tree *node, tree name, tree args, int flags, - bool *no_add_attrs) -{ - /* Ensure we have a function declaration. */ - if (TREE_CODE (*node) != FUNCTION_DECL) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - else if (! targetm.target_option.valid_attribute_p (*node, name, args, - flags)) - *no_add_attrs = true; - - /* Check that there's no empty string in values of the attribute. */ - for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t)) - { - tree value = TREE_VALUE (t); - if (TREE_CODE (value) == STRING_CST - && TREE_STRING_LENGTH (value) == 1 - && TREE_STRING_POINTER (value)[0] == '\0') - { - warning (OPT_Wattributes, "empty string in attribute %"); - *no_add_attrs = true; - } - } - - return NULL_TREE; -} - -/* Handle a "used" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_used_attribute (tree *pnode, tree name, tree ARG_UNUSED (args), - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - tree node = *pnode; - - if (TREE_CODE (node) == FUNCTION_DECL - || (VAR_P (node) && TREE_STATIC (node)) - || (TREE_CODE (node) == TYPE_DECL)) - { - TREE_USED (node) = 1; - DECL_PRESERVE_P (node) = 1; - if (VAR_P (node)) - DECL_READ_P (node) = 1; - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - return NULL_TREE; -} - -/* Handle an "alias" or "ifunc" attribute; arguments as in - struct attribute_spec.handler, except that IS_ALIAS tells us - whether this is an alias as opposed to ifunc attribute. */ - -static tree -handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args, - bool *no_add_attrs) -{ - tree decl = *node; - - if (TREE_CODE (decl) != FUNCTION_DECL - && (!is_alias || !VAR_P (decl))) - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - else if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) - || (TREE_CODE (decl) != FUNCTION_DECL - && TREE_PUBLIC (decl) && !DECL_EXTERNAL (decl)) - /* A static variable declaration is always a tentative definition, - but the alias is a non-tentative definition which overrides. */ - || (TREE_CODE (decl) != FUNCTION_DECL - && ! TREE_PUBLIC (decl) && DECL_INITIAL (decl))) - { - error ("%q+D defined both normally and as %qE attribute", decl, name); - *no_add_attrs = true; - return NULL_TREE; - } - else if (!is_alias - && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl)) - || lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))) - { - error ("weak %q+D cannot be defined %qE", decl, name); - *no_add_attrs = true; - return NULL_TREE; - } - - /* Note that the very first time we process a nested declaration, - decl_function_context will not be set. Indeed, *would* never - be set except for the DECL_INITIAL/DECL_EXTERNAL frobbery that - we do below. After such frobbery, pushdecl would set the context. - In any case, this is never what we want. */ - else if (decl_function_context (decl) == 0 && current_function_decl == NULL) - { - tree id; - - id = TREE_VALUE (args); - if (TREE_CODE (id) != STRING_CST) - { - error ("attribute %qE argument not a string", name); - *no_add_attrs = true; - return NULL_TREE; - } - id = get_identifier (TREE_STRING_POINTER (id)); - /* This counts as a use of the object pointed to. */ - TREE_USED (id) = 1; - - if (TREE_CODE (decl) == FUNCTION_DECL) - DECL_INITIAL (decl) = error_mark_node; - else - TREE_STATIC (decl) = 1; - - if (!is_alias) - { - /* ifuncs are also aliases, so set that attribute too. */ - DECL_ATTRIBUTES (decl) - = tree_cons (get_identifier ("alias"), args, - DECL_ATTRIBUTES (decl)); - DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"), - NULL, DECL_ATTRIBUTES (decl)); - } - } - else - { - warning (OPT_Wattributes, "%qE attribute ignored", name); - *no_add_attrs = true; - } - - if (decl_in_symtab_p (*node)) - { - struct symtab_node *n = symtab_node::get (decl); - if (n && n->refuse_visibility_changes) - error ("%+qD declared %qs after being used", - decl, is_alias ? "alias" : "ifunc"); - } - - - return NULL_TREE; -} - -/* Handle an "alias" or "ifunc" attribute; arguments as in - struct attribute_spec.handler. */ - -static tree -handle_alias_attribute (tree *node, tree name, tree args, - int ARG_UNUSED (flags), bool *no_add_attrs) -{ - return handle_alias_ifunc_attribute (true, node, name, args, no_add_attrs); -} - -/* (end of attribute-handling). */ - /* Language-dependent contents of a type. */ struct GTY(()) lang_type diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc index 347f9f9a78278..6901c24b14ddf 100644 --- a/gcc/jit/jit-playback.cc +++ b/gcc/jit/jit-playback.cc @@ -583,6 +583,10 @@ const char* fn_attribute_to_string (gcc_jit_fn_attribute attr) return "weak"; case GCC_JIT_FN_ATTRIBUTE_NONNULL: return "nonnull"; + case GCC_JIT_FN_ATTRIBUTE_MS_ABI: + return "ms_abi"; + case GCC_JIT_FN_ATTRIBUTE_SYSV_ABI: + return "sysv_abi"; case GCC_JIT_FN_ATTRIBUTE_MAX: return NULL; } diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc index 4ac5d6b602f0a..b842d901c2eaf 100644 --- a/gcc/jit/jit-recording.cc +++ b/gcc/jit/jit-recording.cc @@ -2671,7 +2671,7 @@ recording::memento_of_get_type::get_size () break; case GCC_JIT_TYPE_FLOAT: m = targetm.c.mode_for_floating_type (TI_FLOAT_TYPE); - size = GET_MODE_PRECISION (m).to_constant (); + size = GET_MODE_UNIT_SIZE (m) * BITS_PER_UNIT; break; #ifdef HAVE_BFmode case GCC_JIT_TYPE_BFLOAT16: @@ -2679,11 +2679,11 @@ recording::memento_of_get_type::get_size () #endif case GCC_JIT_TYPE_DOUBLE: m = targetm.c.mode_for_floating_type (TI_DOUBLE_TYPE); - size = GET_MODE_PRECISION (m).to_constant (); + size = GET_MODE_UNIT_SIZE (m) * BITS_PER_UNIT; break; case GCC_JIT_TYPE_LONG_DOUBLE: m = targetm.c.mode_for_floating_type (TI_LONG_DOUBLE_TYPE); - size = GET_MODE_PRECISION (m).to_constant (); + size = GET_MODE_UNIT_SIZE (m) * BITS_PER_UNIT; break; case GCC_JIT_TYPE_FLOAT16: size = 16; @@ -4954,6 +4954,8 @@ static const char * const fn_attribute_reproducer_strings[] = "GCC_JIT_FN_ATTRIBUTE_CONST", "GCC_JIT_FN_ATTRIBUTE_WEAK", "GCC_JIT_FN_ATTRIBUTE_NONNULL", + "GCC_JIT_FN_ATTRIBUTE_MS_ABI", + "GCC_JIT_FN_ATTRIBUTE_SYSV_ABI", }; std::string diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 9ecd201c4d0cd..17bd85f920f2d 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -2169,6 +2169,10 @@ enum gcc_jit_fn_attribute GCC_JIT_FN_ATTRIBUTE_WEAK, GCC_JIT_FN_ATTRIBUTE_NONNULL, + // x86 attributes. + GCC_JIT_FN_ATTRIBUTE_MS_ABI, + GCC_JIT_FN_ATTRIBUTE_SYSV_ABI, + /* Maximum value of this enum, should always be last. */ GCC_JIT_FN_ATTRIBUTE_MAX, };