* Makefile.in (dodump.h): Add $(BASIC_BLOCK_H) dependency.
+ * opts.h (CL_SAVE): New option class for marking options that are
+ target specific options usable in the target attribute.
+ (CL_MIN_OPTION_CLASS): CL_SAVE is now the minimum option.
+
+ * opt-functions.awk (switch_flags): Add CL_SAVE flag so backends
+ can easily find the target specific options that are safe to use
+ in the attribute or pragma.
+
+ * attribs.c (decl_attributes): Change #pragma GCC option to
+ #pragma GCC target, and attribute((option(...))) to
+ attribute((target(...))).
+
+ * doc/extend.texi (target attribute): Change from option
+ attribute. Delete push/pop/reset.
+ (#pragma GCC target): Change from #pragma GCC option. Delete
+ push/pop/reset.
+ (#pragma GCC push_options): Document new pragma.
+ (#pragma GCC pop_options): Document new pragma.
+ (#pragma GCC reset_options): Document new pragma.
+
+ * targhooks.c (default_target_option_valid_attribute_p): Add
+ warning about port not supporting target attributes.
+ (default_target_option_pragma_parse): New function, warn about
+ #pragma GCC target not being supported.
+
+ * targhooks.h (default_target_option_pragma_parse): Add
+ declaration.
+
+ * tree.h (TI_CURRENT_TARGET_PRAGMA): Rename from
+ TI_CURRENT_OPTION_PRAGMA.
+ (current_target_pragma): Rename from current_option_pragma.
+
+ * target.h: (struct target_option): Delete booleans for changing
+ the optimization level on hot/cold functions. Change signature of
+ pragma_parse hook to take a second tree.
+
+ * c-tree.h (c_builtin_function_ext_scope): Add declaration.
+
+ * c-decl.c (c_builtin_function_ext_scope): New function, guarantee
+ that the declaration is done at global scope.
+
+ * langhooks.c (add_builtin_function_common): Move most of the code
+ from add_builtin_function here, calling the hook passed in.
+ (add_builtin_function): Call add_builtin_function_common with
+ standard builtin hook.
+ (add_builtin_function_ext_scope): New function to add builtins to
+ global scope.
+
+ * langhooks.h (struct lang_hooks): Add builtin_function_ext_scope
+ hook.
+ (add_builtin_function_ext_scope): Add declaration.
+
+ * c-pragma.c (handle_pragma_target): Rename from
+ handle_pragma_option, #pragma GCC option is now #pragma GCC
+ target. Move warning about port not supporting target options to
+ default pragma parse hook. Remove push/pop/reset from this
+ pragma.
+ (handle_pragma_optimize): Remove push/pop/reset from this pragma.
+ (option_stack): Delete static variable.
+ (optimize_stack): Ditto.
+ (optons_stack): New stack of saved target and optimization
+ options.
+ (handle_pragma_push_options): New function to handle pushing both
+ target and optimization options.
+ (handle_pragma_pop_options): New function to handle popping both
+ target and optimization options.
+ (handle_pragma_reset_options): New function to handle resetting
+ both target and optimization options to their initial state.
+ (init_pragma): Rename handle_pragma_option to
+ handle_pragma_target. Add support for push_options, pop_options,
+ and reset_options pragmas.
+
+ * target-def.h (TARGET_OPTION_PRAGMA_PARSE): Change default to
+ default_target_option_pragma_parse.
+ (TARGET_OPTION_VALID_ATTRIBUTE_P): Change default to
+ default_target_option_valid_attribute_p.
+ (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION): Delete.
+ (TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION): Ditto.
+ (TARGET_OPTION_HOOKS): Delete the fields for whether to change
+ optimization level on hot/cold functions.
+
+ * tree-inline.c (tree_can_inline_p): Disable suppressing inlining
+ if the caller and callee have different optimization levels.
+
+ * c-common.c (handle_target_attribute): Rename from
+ handle_option_attribute, attribute((option(...))) is now
+ attribute((target(...))). Move warning if the port does not
+ support target attributes to the default hook.
+ (handle_hot_attribute): Delete code to change the optimization
+ level of hot functions.
+ (handle_cold_attribute): Ditto.
+
+ * config/i386/i386-c.c (ix86_pragma_target_parse): Take a second
+ argument that is the binary tree options to use if there are no
+ arguments. Call ix86_valid_target_attribute_tree instead of
+ ix86_valid_option_attribute_tree.
+ (ix86_pragma_target_parse): Rename from ix86_pragma_option_parse.
+ (ix86_register_pragmas): Use ix86_pragma_target_parse instead of
+ ix86_pragma_option_parse.
+
+ * config/i386/i386-protos.h (ix86_valid_target_attribute_tree):
+ Rename from ix86_valid_option_attribute_tree.
+
+ * config/i386/i386.c (ix86_add_new_builtins): New function to add
+ new builtins when the ISA changes.
+ (ix86_valid_target_attribute_tree): Rename from
+ ix86_valid_option_attribute_tree. Change callers. If the
+ function specified optimization options, use those as the starting
+ point before setting up the target attributes. If the
+ optimization options were changed in the course of setting the
+ target attributes, record the new optimization options.
+ (ix86_valid_target_attribute_tree_inner_p): Rename from
+ ix86_valid_option_attribute_tree_inner_p. Change callers. Call
+ ix86_add_new_builtins if the ISA changed.
+ (ix86_valid_target_attribute_p): Rename from
+ ix86_valid_option_attribute_p. Change callers.
+ (enum ix86_builtins): Add IX86_BUILTIN_PCMOV to allow both
+ __builtin_ia32_pcmov and __builtin_ia32_pcmov_v2di to be declared
+ as delayed builtin functions.
+ (struct builtin_isa): New structure to record builtin functions
+ that should be delayed until the ISA for that function is used.
+ (ix86_builtins_isa): Change from int to struct to track builtin
+ functions we want to declare at some point.
+ (def_builtin): If the front end can delay defining the builtin
+ functions, don't create builtins for ISAs not part of the default
+ options.
+ (def_builtin_const): Ditto.
+ (bdesc_multi_arg): Declare __builtin_ia32_pcmov and
+ __builtin_ia32_pcmov_v2di to be different builtin functions.
+ (ix86_expand_builtin): Changes due to ix86_builtins_isa now being
+ a structure instead of an int.
+ (TARGET_OPTION_VALID_ATTRIBUTE_P): Use
+ ix86_valid_target_attribute_p, not ix86_valid_option_attribute_p.
+ (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION): Delete.
+ (TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION): Ditto.
+
+ * config/ia64/ia64.h
+ (TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION): Delete.
+ (TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION): Ditto.
+
+ * langhooks-def.h (LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE): New
+ hook, default to being the same as LANG_HOOKS_BUILTIN_FUNCTION.
+ (LANG_HOOKS_INITIALIZER): Add
+ LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE hook.
+
2008-08-30 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/37270
&& !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node))
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) = optimization_current_node;
- /* If this is a function and the user used #pragma GCC option, add the
- options to the attribute((option(...))) list. */
+ /* If this is a function and the user used #pragma GCC target, add the
+ options to the attribute((target(...))) list. */
if (TREE_CODE (*node) == FUNCTION_DECL
- && current_option_pragma
+ && current_target_pragma
&& targetm.target_option.valid_attribute_p (*node, NULL_TREE,
- current_option_pragma, 0))
+ current_target_pragma, 0))
{
- tree cur_attr = lookup_attribute ("option", attributes);
- tree opts = copy_list (current_option_pragma);
+ tree cur_attr = lookup_attribute ("target", attributes);
+ tree opts = copy_list (current_target_pragma);
if (! cur_attr)
- attributes = tree_cons (get_identifier ("option"), opts, attributes);
+ attributes = tree_cons (get_identifier ("target"), opts, attributes);
else
TREE_VALUE (cur_attr) = chainon (opts, TREE_VALUE (cur_attr));
}
static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
static tree handle_type_generic_attribute (tree *, tree, tree, int, bool *);
static tree handle_alloc_size_attribute (tree *, tree, tree, int, bool *);
-static tree handle_option_attribute (tree *, tree, tree, int, bool *);
+static tree handle_target_attribute (tree *, tree, tree, int, bool *);
static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
static void check_function_nonnull (tree, int, tree *);
handle_error_attribute },
{ "error", 1, 1, true, false, false,
handle_error_attribute },
- { "option", 1, -1, true, false, false,
- handle_option_attribute },
+ { "target", 1, -1, true, false, false,
+ handle_target_attribute },
{ "optimize", 1, -1, true, false, false,
handle_optimize_attribute },
{ NULL, 0, 0, false, false, false, NULL }
name, "cold");
*no_add_attrs = true;
}
- else
- {
- tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
-
- /* If we are not at -O3, but are optimizing, turn on -O3
- optimizations just for this one function. */
- if (((optimize > 0 && optimize < 3) || optimize_size)
- && targetm.target_option.hot_attribute_sets_optimization
- && (!old_opts || old_opts == optimization_default_node))
- {
- /* Create the hot optimization node if needed. */
- if (!optimization_hot_node)
- {
- struct cl_optimization current_options;
- static const char *os_argv[] = { NULL, "-O3", NULL };
-
- cl_optimization_save (¤t_options);
- decode_options (2, os_argv);
- optimization_hot_node = build_optimization_node ();
- cl_optimization_restore (¤t_options);
- }
-
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
- = optimization_hot_node;
- }
- /* Most of the rest of the hot processing is done later with
- lookup_attribute. */
- }
+ /* Most of the rest of the hot processing is done later with
+ lookup_attribute. */
}
else
{
name, "hot");
*no_add_attrs = true;
}
- else
- {
- tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
-
- /* If we are optimizing, but not optimizing for space, turn on -Os
- optimizations just for this one function. */
- if (optimize && !optimize_size
- && targetm.target_option.cold_attribute_sets_optimization
- && (!old_opts || old_opts == optimization_default_node))
- {
- /* Create the cold optimization node if needed. */
- if (!optimization_cold_node)
- {
- struct cl_optimization current_options;
- static const char *os_argv[] = { NULL, "-Os", NULL };
-
- cl_optimization_save (¤t_options);
- decode_options (2, os_argv);
- optimization_cold_node = build_optimization_node ();
- cl_optimization_restore (¤t_options);
- }
-
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
- = optimization_cold_node;
- }
- /* Most of the rest of the cold processing is done later with
- lookup_attribute. */
- }
+ /* Most of the rest of the cold processing is done later with
+ lookup_attribute. */
}
else
{
return NULL_TREE;
}
-/* For handling "option" attribute. arguments as in
- struct attribute_spec.handler. */
+/* Handle a "target" attribute. */
static tree
-handle_option_attribute (tree *node, tree name, tree args, int flags,
+handle_target_attribute (tree *node, tree name, tree args, int flags,
bool *no_add_attrs)
{
/* Ensure we have a function type. */
warning (OPT_Wattributes, "%qE attribute ignored", name);
*no_add_attrs = true;
}
- else if (targetm.target_option.valid_attribute_p
- == default_target_option_valid_attribute_p)
- {
- warning (OPT_Wattributes,
- "%qE attribute is not supported on this machine",
- name);
- *no_add_attrs = true;
- }
else if (! targetm.target_option.valid_attribute_p (*node, name, args,
flags))
*no_add_attrs = true;
return decl;
}
+
+tree
+c_builtin_function_ext_scope (tree decl)
+{
+ tree type = TREE_TYPE (decl);
+ tree id = DECL_NAME (decl);
+
+ const char *name = IDENTIFIER_POINTER (id);
+ C_DECL_BUILTIN_PROTOTYPE (decl) = (TYPE_ARG_TYPES (type) != 0);
+
+ /* Should never be called on a symbol with a preexisting meaning. */
+ gcc_assert (!I_SYMBOL_BINDING (id));
+
+ bind (id, decl, external_scope, /*invisible=*/false, /*nested=*/false);
+
+ /* Builtins in the implementation namespace are made visible without
+ needing to be explicitly declared. See push_file_scope. */
+ if (name[0] == '_' && (name[1] == '_' || ISUPPER (name[1])))
+ {
+ TREE_CHAIN (decl) = visible_builtins;
+ visible_builtins = decl;
+ }
+
+ return decl;
+}
\f
/* Called when a declaration is seen that contains no names to declare.
If its type is a reference to a structure, union or enum inherited
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL c_dup_lang_specific_decl
#undef LANG_HOOKS_BUILTIN_FUNCTION
#define LANG_HOOKS_BUILTIN_FUNCTION c_builtin_function
+#undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
+#define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE c_builtin_function_ext_scope
/* Attribute hooks. */
#undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
}
-/* Stack of the #pragma GCC options created with #pragma GCC option push. */
-static GTY(()) VEC(tree,gc) *option_stack;
-
-/* Parse #pragma GCC option (xxx) to set target specific options. */
+/* Parse #pragma GCC target (xxx) to set target specific options. */
static void
-handle_pragma_option(cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_target(cpp_reader *ARG_UNUSED(dummy))
{
enum cpp_ttype token;
- const char *name;
tree x;
bool close_paren_needed_p = false;
return;
}
- if (!targetm.target_option.pragma_parse)
- {
- error ("#pragma GCC option is not supported for this system");
- return;
- }
-
token = pragma_lex (&x);
if (token == CPP_OPEN_PAREN)
{
token = pragma_lex (&x);
}
- if (token == CPP_NAME)
- {
- bool call_pragma_parse_p = false;
- bool ok_p;
-
- name = IDENTIFIER_POINTER (x);
- if (strcmp (name, "reset") == 0)
- {
- current_option_pragma = NULL_TREE;
- call_pragma_parse_p = true;
- }
-
- else if (strcmp (name, "push") == 0)
- VEC_safe_push (tree, gc, option_stack,
- copy_list (current_option_pragma));
-
- else if (strcmp (name, "pop") == 0)
- {
- int len = VEC_length (tree, option_stack);
- if (len == 0)
- {
- GCC_BAD ("%<#pragma GCC option pop%> without a %<#pragma GCC "
- "option push%>");
- return;
- }
- else
- {
- VEC_truncate (tree, option_stack, len-1);
- current_option_pragma = ((len > 1)
- ? VEC_last (tree, option_stack)
- : NULL_TREE);
-
- call_pragma_parse_p = true;
- }
- }
-
- else
- {
- GCC_BAD ("%<#pragma GCC option%> is not a string or "
- "push/pop/reset");
- return;
- }
-
- token = pragma_lex (&x);
- if (close_paren_needed_p)
- {
- if (token == CPP_CLOSE_PAREN)
- token = pragma_lex (&x);
- else
- GCC_BAD ("%<#pragma GCC option ([push|pop|reset])%> does not "
- "have a final %<)%>.");
- }
-
- if (token != CPP_EOF)
- {
- GCC_BAD ("%<#pragma GCC option [push|pop|reset]%> is badly "
- "formed");
- return;
- }
-
- /* See if we need to call the pragma_parse hook. This must occur at the
- end after processing all of the tokens, or we may get spurious errors
- when we define or undef macros. */
- ok_p = targetm.target_option.pragma_parse (current_option_pragma);
- gcc_assert (ok_p);
- }
-
- else if (token != CPP_STRING)
+ if (token != CPP_STRING)
{
- GCC_BAD ("%<#pragma GCC option%> is not a string or push/pop/reset");
+ GCC_BAD ("%<#pragma GCC option%> is not a string");
return;
}
if (token == CPP_CLOSE_PAREN)
token = pragma_lex (&x);
else
- GCC_BAD ("%<#pragma GCC option (string [,string]...)%> does "
+ GCC_BAD ("%<#pragma GCC target (string [,string]...)%> does "
"not have a final %<)%>.");
}
if (token != CPP_EOF)
{
- error ("#pragma GCC option string... is badly formed");
+ error ("#pragma GCC target string... is badly formed");
return;
}
/* put arguments in the order the user typed them. */
args = nreverse (args);
- if (targetm.target_option.pragma_parse (args))
- current_option_pragma = args;
+ if (targetm.target_option.pragma_parse (args, NULL_TREE))
+ current_target_pragma = args;
}
}
-/* Stack of the #pragma GCC optimize options created with #pragma GCC optimize
- push. */
-static GTY(()) VEC(tree,gc) *optimize_stack;
-
/* Handle #pragma GCC optimize to set optimization options. */
static void
-handle_pragma_optimize(cpp_reader *ARG_UNUSED(dummy))
+handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy))
{
enum cpp_ttype token;
- const char *name;
tree x;
bool close_paren_needed_p = false;
tree optimization_previous_node = optimization_current_node;
token = pragma_lex (&x);
}
- if (token == CPP_NAME)
+ if (token != CPP_STRING && token != CPP_NUMBER)
{
- bool call_opt_p = false;
-
- name = IDENTIFIER_POINTER (x);
- if (strcmp (name, "reset") == 0)
- {
- struct cl_optimization *def
- = TREE_OPTIMIZATION (optimization_default_node);
- current_optimize_pragma = NULL_TREE;
- optimization_current_node = optimization_default_node;
- cl_optimization_restore (def);
- call_opt_p = true;
- }
-
- else if (strcmp (name, "push") == 0)
- VEC_safe_push (tree, gc, optimize_stack, current_optimize_pragma);
-
- else if (strcmp (name, "pop") == 0)
- {
- int len = VEC_length (tree, optimize_stack);
- if (len == 0)
- {
- GCC_BAD ("%<#pragma GCC optimize pop%> without a %<#pragma "
- "GCC optimize push%>");
- return;
- }
- else
- {
- VEC_truncate (tree, optimize_stack, len-1);
- current_optimize_pragma
- = ((len > 1)
- ? VEC_last (tree, optimize_stack)
- : NULL_TREE);
-
- call_opt_p = true;
- if (current_optimize_pragma)
- {
- bool ok_p
- = parse_optimize_options (current_optimize_pragma, false);
- gcc_assert (ok_p); /* should be parsed previously. */
- optimization_current_node = build_optimization_node ();
- }
- else
- {
- struct cl_optimization *opt
- = TREE_OPTIMIZATION (optimization_default_node);
- optimization_current_node = optimization_default_node;
- cl_optimization_restore (opt);
- }
- }
- }
-
- else
- {
- GCC_BAD ("%<#pragma GCC optimize%> is not a string or "
- "push/pop/reset");
- return;
- }
-
- token = pragma_lex (&x);
- if (close_paren_needed_p)
- {
- if (token == CPP_CLOSE_PAREN)
- token = pragma_lex (&x);
- else
- GCC_BAD ("%<#pragma GCC optimize ([push|pop|reset])%> does not "
- "have a final %<)%>.");
- }
-
- if (token != CPP_EOF)
- {
- GCC_BAD ("%<#pragma GCC optimize [push|pop|reset]%> is badly "
- "formed");
- return;
- }
-
- if (call_opt_p &&
- (optimization_previous_node != optimization_current_node))
- c_cpp_builtins_optimize_pragma (parse_in,
- optimization_previous_node,
- optimization_current_node);
-
- }
-
- else if (token != CPP_STRING && token != CPP_NUMBER)
- {
- GCC_BAD ("%<#pragma GCC optimize%> is not a string, number, or "
- "push/pop/reset");
+ GCC_BAD ("%<#pragma GCC optimize%> is not a string or number");
return;
}
args = nreverse (args);
parse_optimize_options (args, false);
+ current_optimize_pragma = chainon (current_optimize_pragma, args);
optimization_current_node = build_optimization_node ();
c_cpp_builtins_optimize_pragma (parse_in,
optimization_previous_node,
}
}
+/* Stack of the #pragma GCC options created with #pragma GCC push_option. Save
+ both the binary representation of the options and the TREE_LIST of
+ strings that will be added to the function's attribute list. */
+typedef struct opt_stack GTY(())
+{
+ struct opt_stack *prev;
+ tree target_binary;
+ tree target_strings;
+ tree optimize_binary;
+ tree optimize_strings;
+} opt_stack;
+
+static GTY(()) struct opt_stack * options_stack;
+
+/* Handle #pragma GCC push_options to save the current target and optimization
+ options. */
+
+static void
+handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy))
+{
+ enum cpp_ttype token;
+ tree x = 0;
+ opt_stack *p;
+
+ token = pragma_lex (&x);
+ if (token != CPP_EOF)
+ {
+ warning (OPT_Wpragmas, "junk at end of %<#pragma push_options%>");
+ return;
+ }
+
+ p = GGC_NEW (opt_stack);
+ p->prev = options_stack;
+ options_stack = p;
+
+ /* Save optimization and target flags in binary format. */
+ p->optimize_binary = build_optimization_node ();
+ p->target_binary = build_target_option_node ();
+
+ /* Save optimization and target flags in string list format. */
+ p->optimize_strings = copy_list (current_optimize_pragma);
+ p->target_strings = copy_list (current_target_pragma);
+}
+
+/* Handle #pragma GCC pop_options to restore the current target and
+ optimization options from a previous push_options. */
+
+static void
+handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy))
+{
+ enum cpp_ttype token;
+ tree x = 0;
+ opt_stack *p;
+
+ token = pragma_lex (&x);
+ if (token != CPP_EOF)
+ {
+ warning (OPT_Wpragmas, "junk at end of %<#pragma pop_options%>");
+ return;
+ }
+
+ if (! options_stack)
+ {
+ warning (OPT_Wpragmas,
+ "%<#pragma GCC pop_options%> without a corresponding "
+ "%<#pragma GCC push_options%>");
+ return;
+ }
+
+ p = options_stack;
+ options_stack = p->prev;
+
+ if (p->target_binary != target_option_current_node)
+ {
+ (void) targetm.target_option.pragma_parse (NULL_TREE, p->target_binary);
+ target_option_current_node = p->target_binary;
+ }
+
+ if (p->optimize_binary != optimization_current_node)
+ {
+ tree old_optimize = optimization_current_node;
+ cl_optimization_restore (TREE_OPTIMIZATION (p->optimize_binary));
+ c_cpp_builtins_optimize_pragma (parse_in, old_optimize,
+ p->optimize_binary);
+ optimization_current_node = p->optimize_binary;
+ }
+
+ current_target_pragma = p->target_strings;
+ current_optimize_pragma = p->optimize_strings;
+}
+
+/* Handle #pragma GCC reset_options to restore the current target and
+ optimization options to the original options used on the command line. */
+
+static void
+handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy))
+{
+ enum cpp_ttype token;
+ tree x = 0;
+ tree new_optimize = optimization_default_node;
+ tree new_target = target_option_default_node;
+
+ token = pragma_lex (&x);
+ if (token != CPP_EOF)
+ {
+ warning (OPT_Wpragmas, "junk at end of %<#pragma reset_options%>");
+ return;
+ }
+
+ if (new_target != target_option_current_node)
+ {
+ (void) targetm.target_option.pragma_parse (NULL_TREE, new_target);
+ target_option_current_node = new_target;
+ }
+
+ if (new_optimize != optimization_current_node)
+ {
+ tree old_optimize = optimization_current_node;
+ cl_optimization_restore (TREE_OPTIMIZATION (new_optimize));
+ c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
+ optimization_current_node = new_optimize;
+ }
+
+ current_target_pragma = NULL_TREE;
+ current_optimize_pragma = NULL_TREE;
+}
+
/* Print a plain user-specified message. */
static void
#endif
c_register_pragma ("GCC", "diagnostic", handle_pragma_diagnostic);
- c_register_pragma ("GCC", "option", handle_pragma_option);
+ c_register_pragma ("GCC", "target", handle_pragma_target);
c_register_pragma ("GCC", "optimize", handle_pragma_optimize);
+ c_register_pragma ("GCC", "push_options", handle_pragma_push_options);
+ c_register_pragma ("GCC", "pop_options", handle_pragma_pop_options);
+ c_register_pragma ("GCC", "reset_options", handle_pragma_reset_options);
c_register_pragma_with_expansion (0, "redefine_extname", handle_pragma_redefine_extname);
c_register_pragma (0, "extern_prefix", handle_pragma_extern_prefix);
extern struct c_declarator *set_array_declarator_inner (struct c_declarator *,
struct c_declarator *);
extern tree c_builtin_function (tree);
+extern tree c_builtin_function_ext_scope (tree);
extern void shadow_tag (const struct c_declspecs *);
extern void shadow_tag_warned (const struct c_declspecs *, int);
extern tree start_enum (struct c_enum_contents *, tree);
#include "cpplib.h"
#include "c-pragma.h"
-static bool ix86_pragma_option_parse (tree);
+static bool ix86_pragma_target_parse (tree, tree);
static void ix86_target_macros_internal
(int, enum processor_type, enum processor_type, enum fpmath_unit,
void (*def_or_undef) (cpp_reader *, const char *));
}
\f
-/* Hook to validate the current #pragma option and set the state, and update
- the macros based on what was changed. */
+/* Hook to validate the current #pragma GCC target and set the state, and
+ update the macros based on what was changed. If ARGS is NULL, then
+ POP_TARGET is used to reset the options. */
static bool
-ix86_pragma_option_parse (tree args)
+ix86_pragma_target_parse (tree args, tree pop_target)
{
tree prev_tree = build_target_option_node ();
tree cur_tree;
if (! args)
{
- cur_tree = target_option_default_node;
+ cur_tree = ((pop_target)
+ ? pop_target
+ : target_option_default_node);
cl_target_option_restore (TREE_TARGET_OPTION (cur_tree));
}
else
{
- cur_tree = ix86_valid_option_attribute_tree (args);
+ cur_tree = ix86_valid_target_attribute_tree (args);
if (!cur_tree)
return false;
}
void
ix86_register_pragmas (void)
{
- /* Update pragma hook to allow parsing #pragma GCC option. */
- targetm.target_option.pragma_parse = ix86_pragma_option_parse;
+ /* Update pragma hook to allow parsing #pragma GCC target. */
+ targetm.target_option.pragma_parse = ix86_pragma_target_parse;
#ifdef REGISTER_SUBTARGET_PRAGMAS
REGISTER_SUBTARGET_PRAGMAS ();
extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
extern int x86_field_alignment (tree, int);
-extern tree ix86_valid_option_attribute_tree (tree);
+extern tree ix86_valid_target_attribute_tree (tree);
#endif
extern rtx ix86_tls_get_addr (void);
static void ix86_compute_frame_layout (struct ix86_frame *);
static bool ix86_expand_vector_init_one_nonzero (bool, enum machine_mode,
rtx, rtx, int);
+static void ix86_add_new_builtins (int);
enum ix86_function_specific_strings
{
static void ix86_function_specific_restore (struct cl_target_option *);
static void ix86_function_specific_print (FILE *, int,
struct cl_target_option *);
-static bool ix86_valid_option_attribute_p (tree, tree, tree, int);
-static bool ix86_valid_option_attribute_inner_p (tree, char *[]);
+static bool ix86_valid_target_attribute_p (tree, tree, tree, int);
+static bool ix86_valid_target_attribute_inner_p (tree, char *[]);
static bool ix86_can_inline_p (tree, tree);
static void ix86_set_current_function (tree);
int const pta_size = ARRAY_SIZE (processor_alias_table);
/* Set up prefix/suffix so the error messages refer to either the command
- line argument, or the attribute(option). */
+ line argument, or the attribute(target). */
if (main_args_p)
{
prefix = "-m";
}
\f
-/* Inner function to process the attribute((option(...))), take an argument and
+/* Inner function to process the attribute((target(...))), take an argument and
set the current options from the argument. If we have a list, recursively go
over the list. */
static bool
-ix86_valid_option_attribute_inner_p (tree args, char *p_strings[])
+ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
{
char *next_optstr;
bool ret = true;
for (; args; args = TREE_CHAIN (args))
if (TREE_VALUE (args)
- && !ix86_valid_option_attribute_inner_p (TREE_VALUE (args), p_strings))
+ && !ix86_valid_target_attribute_inner_p (TREE_VALUE (args), p_strings))
ret = false;
return ret;
/* Process the option. */
if (opt == N_OPTS)
{
- error ("attribute(option(\"%s\")) is unknown", orig_p);
+ error ("attribute(target(\"%s\")) is unknown", orig_p);
ret = false;
}
/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
tree
-ix86_valid_option_attribute_tree (tree args)
+ix86_valid_target_attribute_tree (tree args)
{
const char *orig_arch_string = ix86_arch_string;
const char *orig_tune_string = ix86_tune_string;
= TREE_TARGET_OPTION (target_option_default_node);
/* Process each of the options on the chain. */
- if (! ix86_valid_option_attribute_inner_p (args, option_strings))
+ if (! ix86_valid_target_attribute_inner_p (args, option_strings))
return NULL_TREE;
/* If the changed options are different from the default, rerun override_options,
/* Do any overrides, such as arch=xxx, or tune=xxx support. */
override_options (false);
+ /* Add any builtin functions with the new isa if any. */
+ ix86_add_new_builtins (ix86_isa_flags);
+
/* Save the current options unless we are validating options for
#pragma. */
t = build_target_option_node ();
return t;
}
-/* Hook to validate attribute((option("string"))). */
+/* Hook to validate attribute((target("string"))). */
static bool
-ix86_valid_option_attribute_p (tree fndecl,
+ix86_valid_target_attribute_p (tree fndecl,
tree ARG_UNUSED (name),
tree args,
int ARG_UNUSED (flags))
{
- struct cl_target_option cur_opts;
+ struct cl_target_option cur_target;
bool ret = true;
- tree new_opts;
-
- cl_target_option_save (&cur_opts);
- new_opts = ix86_valid_option_attribute_tree (args);
- if (!new_opts)
+ tree old_optimize = build_optimization_node ();
+ tree new_target, new_optimize;
+ tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+
+ /* If the function changed the optimization levels as well as setting target
+ options, start with the optimizations specified. */
+ if (func_optimize && func_optimize != old_optimize)
+ cl_optimization_restore (TREE_OPTIMIZATION (func_optimize));
+
+ /* The target attributes may also change some optimization flags, so update
+ the optimization options if necessary. */
+ cl_target_option_save (&cur_target);
+ new_target = ix86_valid_target_attribute_tree (args);
+ new_optimize = build_optimization_node ();
+
+ if (!new_target)
ret = false;
else if (fndecl)
- DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_opts;
+ {
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
+
+ if (old_optimize != new_optimize)
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+ }
+
+ cl_target_option_restore (&cur_target);
+
+ if (old_optimize != new_optimize)
+ cl_optimization_restore (TREE_OPTIMIZATION (old_optimize));
- cl_target_option_restore (&cur_opts);
return ret;
}
IX86_BUILTIN_FNMSUBSD,
IX86_BUILTIN_FNMSUBPS,
IX86_BUILTIN_FNMSUBPD,
+ IX86_BUILTIN_PCMOV,
IX86_BUILTIN_PCMOV_V2DI,
IX86_BUILTIN_PCMOV_V4SI,
IX86_BUILTIN_PCMOV_V8HI,
/* Table for the ix86 builtin decls. */
static GTY(()) tree ix86_builtins[(int) IX86_BUILTIN_MAX];
-/* Table to record which ISA options the builtin needs. */
-static int ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
+/* Table of all of the builtin functions that are possible with different ISA's
+ but are waiting to be built until a function is declared to use that
+ ISA. */
+struct builtin_isa GTY(())
+{
+ tree type; /* builtin type to use in the declaration */
+ const char *name; /* function name */
+ int isa; /* isa_flags this builtin is defined for */
+ bool const_p; /* true if the declaration is constant */
+};
+
+static GTY(()) struct builtin_isa ix86_builtins_isa[(int) IX86_BUILTIN_MAX];
+
/* Add an ix86 target builtin function with CODE, NAME and TYPE. Save the MASK
* of which isa_flags to use in the ix86_builtins_isa array. Stores the
* function decl in the ix86_builtins array. Returns the function decl or
* NULL_TREE, if the builtin was not added.
*
- * Record all builtins, even if it isn't an instruction set in the current ISA
- * in case the user uses function specific options for a different ISA. When
- * the builtin is expanded, check at that time whether it is valid. */
+ * If the front end has a special hook for builtin functions, delay adding
+ * builtin functions that aren't in the current ISA until the ISA is changed
+ * with function specific optimization. Doing so, can save about 300K for the
+ * default compiler. When the builtin is expanded, check at that time whether
+ * it is valid.
+ *
+ * If the front end doesn't have a special hook, record all builtins, even if
+ * it isn't an instruction set in the current ISA in case the user uses
+ * function specific options for a different ISA, so that we don't get scope
+ * errors if a builtin is added in the middle of a function scope. */
static inline tree
def_builtin (int mask, const char *name, tree type, enum ix86_builtins code)
if (!(mask & OPTION_MASK_ISA_64BIT) || TARGET_64BIT)
{
- decl = add_builtin_function (name, type, code, BUILT_IN_MD,
- NULL, NULL_TREE);
- ix86_builtins[(int) code] = decl;
- ix86_builtins_isa[(int) code] = mask;
+ ix86_builtins_isa[(int) code].isa = mask;
+
+ if ((mask & ix86_isa_flags) != 0
+ || (lang_hooks.builtin_function
+ == lang_hooks.builtin_function_ext_scope))
+
+ {
+ decl = add_builtin_function (name, type, code, BUILT_IN_MD, NULL,
+ NULL_TREE);
+ ix86_builtins[(int) code] = decl;
+ ix86_builtins_isa[(int) code].type = NULL_TREE;
+ }
+ else
+ {
+ ix86_builtins[(int) code] = NULL_TREE;
+ ix86_builtins_isa[(int) code].const_p = false;
+ ix86_builtins_isa[(int) code].type = type;
+ ix86_builtins_isa[(int) code].name = name;
+ }
}
return decl;
tree decl = def_builtin (mask, name, type, code);
if (decl)
TREE_READONLY (decl) = 1;
+ else
+ ix86_builtins_isa[(int) code].const_p = true;
+
return decl;
}
+/* Add any new builtin functions for a given ISA that may not have been
+ declared. This saves a bit of space compared to adding all of the
+ declarations to the tree, even if we didn't use them. */
+
+static void
+ix86_add_new_builtins (int isa)
+{
+ int i;
+ tree decl;
+
+ for (i = 0; i < (int)IX86_BUILTIN_MAX; i++)
+ {
+ if ((ix86_builtins_isa[i].isa & isa) != 0
+ && ix86_builtins_isa[i].type != NULL_TREE)
+ {
+ decl = add_builtin_function_ext_scope (ix86_builtins_isa[i].name,
+ ix86_builtins_isa[i].type,
+ i, BUILT_IN_MD, NULL,
+ NULL_TREE);
+
+ ix86_builtins[i] = decl;
+ ix86_builtins_isa[i].type = NULL_TREE;
+ if (ix86_builtins_isa[i].const_p)
+ TREE_READONLY (decl) = 1;
+ }
+ }
+}
+
/* Bits for builtin_description.flag. */
/* Set when we don't support the comparison natively, and should
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5i_vmfnmsubv2df4, "__builtin_ia32_fnmsubsd", IX86_BUILTIN_FNMSUBSD, 0, (int)MULTI_ARG_3_DF },
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5i_fnmsubv4sf4, "__builtin_ia32_fnmsubps", IX86_BUILTIN_FNMSUBPS, 0, (int)MULTI_ARG_3_SF },
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5i_fnmsubv2df4, "__builtin_ia32_fnmsubpd", IX86_BUILTIN_FNMSUBPD, 0, (int)MULTI_ARG_3_DF },
- { OPTION_MASK_ISA_SSE5, CODE_FOR_sse5_pcmov_v2di, "__builtin_ia32_pcmov", IX86_BUILTIN_PCMOV_V2DI, 0, (int)MULTI_ARG_3_DI },
+ { OPTION_MASK_ISA_SSE5, CODE_FOR_sse5_pcmov_v2di, "__builtin_ia32_pcmov", IX86_BUILTIN_PCMOV, 0, (int)MULTI_ARG_3_DI },
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5_pcmov_v2di, "__builtin_ia32_pcmov_v2di", IX86_BUILTIN_PCMOV_V2DI, 0, (int)MULTI_ARG_3_DI },
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5_pcmov_v4si, "__builtin_ia32_pcmov_v4si", IX86_BUILTIN_PCMOV_V4SI, 0, (int)MULTI_ARG_3_SI },
{ OPTION_MASK_ISA_SSE5, CODE_FOR_sse5_pcmov_v8hi, "__builtin_ia32_pcmov_v8hi", IX86_BUILTIN_PCMOV_V8HI, 0, (int)MULTI_ARG_3_HI },
current ISA based on the command line switches. With function specific
options, we need to check in the context of the function making the call
whether it is supported. */
- if (ix86_builtins_isa[fcode]
- && !(ix86_builtins_isa[fcode] & ix86_isa_flags))
+ if (ix86_builtins_isa[fcode].isa
+ && !(ix86_builtins_isa[fcode].isa & ix86_isa_flags))
{
- char *opts = ix86_target_string (ix86_builtins_isa[fcode], 0, NULL,
+ char *opts = ix86_target_string (ix86_builtins_isa[fcode].isa, 0, NULL,
NULL, NULL, false);
if (!opts)
#define TARGET_SET_CURRENT_FUNCTION ix86_set_current_function
#undef TARGET_OPTION_VALID_ATTRIBUTE_P
-#define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_option_attribute_p
+#define TARGET_OPTION_VALID_ATTRIBUTE_P ix86_valid_target_attribute_p
#undef TARGET_OPTION_SAVE
#define TARGET_OPTION_SAVE ix86_function_specific_save
#undef TARGET_OPTION_CAN_INLINE_P
#define TARGET_OPTION_CAN_INLINE_P ix86_can_inline_p
-#undef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION true
-
-#undef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION true
-
struct gcc_target targetm = TARGET_INITIALIZER;
\f
#include "gt-i386.h"
#undef TARGET_C_MODE_FOR_SUFFIX
#define TARGET_C_MODE_FOR_SUFFIX ia64_c_mode_for_suffix
-#undef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION true
-
-#undef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION true
-
struct gcc_target targetm = TARGET_INITIALIZER;
\f
typedef enum
+2008-08-29 Michael Meissner <gnu@the-meissners.org>
+
+ * decl.c (builtin_function_1): Take a bool argument to decide
+ whether to use pushdecl or pushdecl_top_level.
+ (duplicate_decls): Copy function specific target and optimization
+ options on duplicate declarations.
+ (cxx_builtin_function): Update builtin_function_1 call.
+ (cxx_builtin_function_ext_scope): New function, guarantee that the
+ declaration is done at global scope.
+
+ * cp-objcp-common.h (LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE): New
+ macro, define builtin function hook for delayed machine specific
+ builtins.
+
+ * cp-tree.h (cxx_builtin_function_ext_scope): Add declaration.
+
2008-08-30 Jason Merrill <jason@redhat.com>
PR c++/37288
#define LANG_HOOKS_COMDAT_GROUP cxx_comdat_group
#undef LANG_HOOKS_BUILTIN_FUNCTION
#define LANG_HOOKS_BUILTIN_FUNCTION cxx_builtin_function
+#undef LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE
+#define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE cxx_builtin_function_ext_scope
#undef LANG_HOOKS_TYPE_HASH_EQ
#define LANG_HOOKS_TYPE_HASH_EQ cxx_type_hash_eq
#undef LANG_HOOKS_MISSING_NORETURN_OK_P
extern tmpl_spec_kind current_tmpl_spec_kind (int);
extern tree cp_fname_init (const char *, tree *);
extern tree cxx_builtin_function (tree decl);
+extern tree cxx_builtin_function_ext_scope (tree decl);
extern tree check_elaborated_type_specifier (enum tag_types, tree, bool);
extern void warn_extern_redeclared_static (tree, tree);
extern const char *cxx_comdat_group (tree);
static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
int, int, tree);
static void record_unknown_type (tree, const char *);
-static tree builtin_function_1 (tree, tree);
+static tree builtin_function_1 (tree, tree, bool);
static tree build_library_fn_1 (tree, enum tree_code, tree);
static int member_function_or_else (tree, tree, enum overload_flags);
static void bad_specifiers (tree, const char *, int, int, int, int,
if (TREE_DEPRECATED (newdecl))
TREE_DEPRECATED (olddecl) = 1;
+ /* Preserve function specific target and optimization options */
+ if (TREE_CODE (newdecl) == FUNCTION_DECL)
+ {
+ if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
+ && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
+ DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
+ = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);
+
+ if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
+ && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
+ = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
+ }
+
/* Merge the initialization information. */
if (DECL_INITIAL (newdecl) == NULL_TREE
&& DECL_INITIAL (olddecl) != NULL_TREE)
}
static tree
-builtin_function_1 (tree decl, tree context)
+builtin_function_1 (tree decl, tree context, bool is_global)
{
tree id = DECL_NAME (decl);
const char *name = IDENTIFIER_POINTER (id);
DECL_CONTEXT (decl) = context;
- pushdecl (decl);
+ if (is_global)
+ pushdecl_top_level (decl);
+ else
+ pushdecl (decl);
/* A function in the user's namespace should have an explicit
declaration before it is used. Mark the built-in function as
{
tree decl2 = copy_node(decl);
push_namespace (std_identifier);
- builtin_function_1 (decl2, std_node);
+ builtin_function_1 (decl2, std_node, false);
+ pop_namespace ();
+ }
+
+ return builtin_function_1 (decl, NULL_TREE, false);
+}
+
+/* Like cxx_builtin_function, but guarantee the function is added to the global
+ scope. This is to allow function specific options to add new machine
+ dependent builtins when the target ISA changes via attribute((target(...)))
+ which saves space on program startup if the program does not use non-generic
+ ISAs. */
+
+tree
+cxx_builtin_function_ext_scope (tree decl)
+{
+
+ tree id = DECL_NAME (decl);
+ const char *name = IDENTIFIER_POINTER (id);
+ /* All builtins that don't begin with an '_' should additionally
+ go in the 'std' namespace. */
+ if (name[0] != '_')
+ {
+ tree decl2 = copy_node(decl);
+ push_namespace (std_identifier);
+ builtin_function_1 (decl2, std_node, true);
pop_namespace ();
}
- return builtin_function_1 (decl, NULL_TREE);
+ return builtin_function_1 (decl, NULL_TREE, true);
}
/* Generate a FUNCTION_DECL with the typical flags for a runtime library
implemented in GCC versions earlier than 3.3.
@item option
-@cindex @code{option} function attribute
-The @code{option} attribute is used to specify that a function is to
+@cindex @code{target} function attribute
+The @code{target} attribute is used to specify that a function is to
be compiled with different target options than specified on the
command line. This can be used for instance to have functions
compiled with a different ISA (instruction set architecture) than the
-default. You can also use the @samp{#pragma GCC option} pragma to set
+default. You can also use the @samp{#pragma GCC target} pragma to set
more than one function to be compiled with specific target options.
@xref{Function Specific Option Pragmas}, for details about the
-@samp{#pragma GCC option} pragma.
+@samp{#pragma GCC target} pragma.
For instance on a 386, you could compile one function with
-@code{option("sse4.1,arch=core2")} and another with
-@code{option("sse4a,arch=amdfam10")} that would be equivalent to
+@code{target("sse4.1,arch=core2")} and another with
+@code{target("sse4a,arch=amdfam10")} that would be equivalent to
compiling the first function with @option{-msse4.1} and
@option{-march=core2} options, and the second function with
@option{-msse4a} and @option{-march=amdfam10} options. It is up to the
family are used).
@smallexample
-int core2_func (void) __attribute__ ((__option__ ("arch=core2")));
-int sse3_func (void) __attribute__ ((__option__ ("sse3")));
+int core2_func (void) __attribute__ ((__target__ ("arch=core2")));
+int sse3_func (void) __attribute__ ((__target__ ("sse3")));
@end smallexample
On the 386, the following options are allowed:
@table @samp
@item abm
@itemx no-abm
-@cindex option("abm")
+@cindex @code{target("abm")} attribute
Enable/disable the generation of the advanced bit instructions.
@item aes
@itemx no-aes
-@cindex @code{option("aes")} attribute
+@cindex @code{target("aes")} attribute
Enable/disable the generation of the AES instructions.
@item mmx
@itemx no-mmx
-@cindex @code{option("mmx")} attribute
+@cindex @code{target("mmx")} attribute
Enable/disable the generation of the MMX instructions.
@item pclmul
@itemx no-pclmul
-@cindex @code{option("pclmul")} attribute
+@cindex @code{target("pclmul")} attribute
Enable/disable the generation of the PCLMUL instructions.
@item popcnt
@itemx no-popcnt
-@cindex @code{option("popcnt")} attribute
+@cindex @code{target("popcnt")} attribute
Enable/disable the generation of the POPCNT instruction.
@item sse
@itemx no-sse
-@cindex @code{option("sse")} attribute
+@cindex @code{target("sse")} attribute
Enable/disable the generation of the SSE instructions.
@item sse2
@itemx no-sse2
-@cindex @code{option("sse2")} attribute
+@cindex @code{target("sse2")} attribute
Enable/disable the generation of the SSE2 instructions.
@item sse3
@itemx no-sse3
-@cindex @code{option("sse3")} attribute
+@cindex @code{target("sse3")} attribute
Enable/disable the generation of the SSE3 instructions.
@item sse4
@itemx no-sse4
-@cindex @code{option("sse4")} attribute
+@cindex @code{target("sse4")} attribute
Enable/disable the generation of the SSE4 instructions (both SSE4.1
and SSE4.2).
@item sse4.1
@itemx no-sse4.1
-@cindex @code{option("sse4.1")} attribute
+@cindex @code{target("sse4.1")} attribute
Enable/disable the generation of the sse4.1 instructions.
@item sse4.2
@itemx no-sse4.2
-@cindex @code{option("sse4.2")} attribute
+@cindex @code{target("sse4.2")} attribute
Enable/disable the generation of the sse4.2 instructions.
@item sse4a
@itemx no-sse4a
-@cindex @code{option("sse4a")} attribute
+@cindex @code{target("sse4a")} attribute
Enable/disable the generation of the SSE4A instructions.
@item sse5
@itemx no-sse5
-@cindex @code{option("sse5")} attribute
+@cindex @code{target("sse5")} attribute
Enable/disable the generation of the SSE5 instructions.
@item ssse3
@itemx no-ssse3
-@cindex @code{option("ssse3")} attribute
+@cindex @code{target("ssse3")} attribute
Enable/disable the generation of the SSSE3 instructions.
@item cld
@itemx no-cld
-@cindex @code{option("cld")} attribute
+@cindex @code{target("cld")} attribute
Enable/disable the generation of the CLD before string moves.
@item fancy-math-387
@itemx no-fancy-math-387
-@cindex @code{option("fancy-math-387")} attribute
+@cindex @code{target("fancy-math-387")} attribute
Enable/disable the generation of the @code{sin}, @code{cos}, and
@code{sqrt} instructions on the 387 floating point unit.
@item fused-madd
@itemx no-fused-madd
-@cindex @code{option("fused-madd")} attribute
+@cindex @code{target("fused-madd")} attribute
Enable/disable the generation of the fused multiply/add instructions.
@item ieee-fp
@itemx no-ieee-fp
-@cindex @code{option("ieee-fp")} attribute
+@cindex @code{target("ieee-fp")} attribute
Enable/disable the generation of floating point that depends on IEEE arithmetic.
@item inline-all-stringops
@itemx no-inline-all-stringops
-@cindex @code{option("inline-all-stringops")} attribute
+@cindex @code{target("inline-all-stringops")} attribute
Enable/disable inlining of string operations.
@item inline-stringops-dynamically
@itemx no-inline-stringops-dynamically
-@cindex @code{option("inline-stringops-dynamically")} attribute
+@cindex @code{target("inline-stringops-dynamically")} attribute
Enable/disable the generation of the inline code to do small string
operations and calling the library routines for large operations.
@item align-stringops
@itemx no-align-stringops
-@cindex @code{option("align-stringops")} attribute
+@cindex @code{target("align-stringops")} attribute
Do/do not align destination of inlined string operations.
@item recip
@itemx no-recip
-@cindex @code{option("recip")} attribute
+@cindex @code{target("recip")} attribute
Enable/disable the generation of RCPSS, RCPPS, RSQRTSS and RSQRTPS
instructions followed an additional Newton-Rhapson step instead of
doing a floating point division.
@item arch=@var{ARCH}
-@cindex @code{option("arch=@var{ARCH}")} attribute
+@cindex @code{target("arch=@var{ARCH}")} attribute
Specify the architecture to generate code for in compiling the function.
@item tune=@var{TUNE}
-@cindex @code{option("tune=@var{TUNE}")} attribute
+@cindex @code{target("tune=@var{TUNE}")} attribute
Specify the architecture to tune for in compiling the function.
@item fpmath=@var{FPMATH}
-@cindex @code{option("fpmath=@var{FPMATH}")} attribute
+@cindex @code{target("fpmath=@var{FPMATH}")} attribute
Specify which floating point unit to use. The
-@code{option("fpmath=sse,387")} option must be specified as
-@code{option("fpmath=sse+387")} because the comma would separate
+@code{target("fpmath=sse,387")} option must be specified as
+@code{target("fpmath=sse+387")} because the comma would separate
different options.
@end table
On the 386, the inliner will not inline a function that has different
target options than the caller, unless the callee has a subset of the
target options of the caller. For example a function declared with
-@code{option("sse5")} can inline a function with
-@code{option("sse2")}, since @code{-msse5} implies @code{-msse2}.
+@code{target("sse5")} can inline a function with
+@code{target("sse2")}, since @code{-msse5} implies @code{-msse2}.
-The @code{option} attribute is not implemented in GCC versions earlier
+The @code{target} attribute is not implemented in GCC versions earlier
than 4.4, and at present only the 386 uses it.
@item optimize
This can be used for instance to have frequently executed functions
compiled with more aggressive optimization options that produce faster
and larger code, while other functions can be called with less
-aggressive options. On some targets, the @code{hot} attribute implies
-@code{optimize("O3")}, and @code{cold} attribute implies
-@code{optimize("Os")}.
-
-@smallexample
-int fast_func (void) __attribute__ ((__optimize__ ("O3,unroll-loops")));
-int slow_func (void) __attribute__ ((__optimize__ ("Os")));
-@end smallexample
-
-The inliner will not inline functions with a higher optimization level
-than the caller or different space/time trade offs.
+aggressive options.
@item pure
@cindex @code{pure} function attribute
The @code{hot} attribute is not implemented in GCC versions earlier
than 4.3.
-Starting with GCC 4.4, the @code{hot} attribute sets
-@code{optimize("O3")} to turn on more aggressive optimization on the
-the i386, x86_64, and IA-64 targets.
-
@item cold
@cindex @code{cold} function attribute
The @code{cold} attribute is used to inform the compiler that a function is
The @code{cold} attribute is not implemented in GCC versions earlier than 4.3.
-Starting with GCC 4.4, the @code{cold} attribute sets
-@code{optimize("Os")} to save space on the the i386, x86_64, and IA-64
-targets.
-
@item regparm (@var{number})
@cindex @code{regparm} attribute
@cindex functions that are passed arguments in registers on the 386
@subsection Function Specific Option Pragmas
@table @code
-@item #pragma GCC option (@var{"string"}...)
-@cindex pragma GCC option
+@item #pragma GCC target (@var{"string"}...)
+@cindex pragma GCC target
This pragma allows you to set target specific options for functions
defined later in the source file. One or more strings can be
specified. Each function that is defined after this point will be as
-if @code{attribute((option("STRING")))} was specified for that
+if @code{attribute((target("STRING")))} was specified for that
function. The parenthesis around the options is optional.
@xref{Function Attributes}, for more information about the
-@code{option} attribute and the attribute syntax.
+@code{target} attribute and the attribute syntax.
-The @samp{#pragma GCC option} pragma is not implemented in GCC
+The @samp{#pragma GCC target} pragma is not implemented in GCC
versions earlier than 4.4, and is currently only implemented for the
-386 and x86_64 backend.
-@end table
-
-@table @code
-@item #pragma GCC option (push)
-@itemx #pragma GCC option (pop)
-@cindex pragma GCC option
-
-These pragmas maintain a stack of the current options. It is
-intended for include files where you temporarily want to switch to
-using a different @samp{#pragma GCC option} and then to pop back to
-the previous options.
+386 and x86_64 backends.
@end table
@table @code
-@item #pragma GCC option (reset)
-@cindex pragma, target option
-@cindex pragma GCC option
-
-This pragma clears the current @code{#pragma GCC options} to use the
-default switches as specified on the command line.
-@end table
-@table @code
@item #pragma GCC optimize (@var{"string"}...)
@cindex pragma GCC optimize
@end table
@table @code
-@item #pragma GCC optimize (push)
-@itemx #pragma GCC optimize (pop)
-@cindex pragma GCC optimize
-
-These pragmas maintain a stack of the current optimization options.
-It is intended for include files where you temporarily want to switch
-to using a different @code{#pragma GCC optimize} and then to pop back
-to the previous optimizations.
+@item #pragma GCC push_options
+@itemx #pragma GCC pop_options
+@cindex pragma GCC push_options
+@cindex pragma GCC pop_options
+
+These pragmas maintain a stack of the current target and optimization
+options. It is intended for include files where you temporarily want
+to switch to using a different @samp{#pragma GCC target} or
+@samp{#pragma GCC optimize} and then to pop back to the previous
+options.
+
+The @samp{#pragma GCC push_options} and @samp{#pragma GCC pop_options}
+pragmas are not implemented in GCC versions earlier than 4.4.
@end table
@table @code
-@item #pragma GCC optimize reset
-@cindex pragma GCC optimize
+@item #pragma GCC reset_options
+@cindex pragma GCC reset_options
-This pragma clears the current @code{#pragma GCC optimize} to use the
-default switches as specified on the command line.
+This pragma clears the current @code{#pragma GCC target} and
+@code{#pragma GCC optimize} to use the default switches as specified
+on the command line.
+
+The @samp{#pragma GCC reset_options} pragma is not implemented in GCC
+versions earlier than 4.4.
@end table
@node Unnamed Fields
#define LANG_HOOKS_TREE_SIZE lhd_tree_size
#define LANG_HOOKS_TYPES_COMPATIBLE_P lhd_types_compatible_p
#define LANG_HOOKS_BUILTIN_FUNCTION lhd_builtin_function
+#define LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE LANG_HOOKS_BUILTIN_FUNCTION
#define LANG_HOOKS_EXPR_TO_DECL lhd_expr_to_decl
#define LANG_HOOKS_TO_TARGET_CHARSET lhd_to_target_charset
#define LANG_HOOKS_INIT_TS lhd_do_nothing
LANG_HOOKS_GIMPLIFY_EXPR, \
LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
LANG_HOOKS_BUILTIN_FUNCTION, \
+ LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
LANG_HOOKS_INIT_TS, \
LANG_HOOKS_EXPR_TO_DECL, \
}
{
}
-tree
-add_builtin_function (const char *name,
- tree type,
- int function_code,
- enum built_in_class cl,
- const char *library_name,
- tree attrs)
+/* Common function for add_builtin_function and
+ add_builtin_function_ext_scope. */
+static tree
+add_builtin_function_common (const char *name,
+ tree type,
+ int function_code,
+ enum built_in_class cl,
+ const char *library_name,
+ tree attrs,
+ tree (*hook) (tree))
{
tree id = get_identifier (name);
tree decl = build_decl (FUNCTION_DECL, id, type);
else
decl_attributes (&decl, NULL_TREE, 0);
- return lang_hooks.builtin_function (decl);
+ return hook (decl);
+
+}
+
+/* Create a builtin function. */
+
+tree
+add_builtin_function (const char *name,
+ tree type,
+ int function_code,
+ enum built_in_class cl,
+ const char *library_name,
+ tree attrs)
+{
+ return add_builtin_function_common (name, type, function_code, cl,
+ library_name, attrs,
+ lang_hooks.builtin_function);
+}
+/* Like add_builtin_function, but make sure the scope is the external scope.
+ This is used to delay putting in back end builtin functions until the ISA
+ that defines the builtin is declared via function specific target options,
+ which can save memory for machines like the x86_64 that have multiple ISAs.
+ If this points to the same function as builtin_function, the backend must
+ add all of the builtins at program initialization time. */
+
+tree
+add_builtin_function_ext_scope (const char *name,
+ tree type,
+ int function_code,
+ enum built_in_class cl,
+ const char *library_name,
+ tree attrs)
+{
+ return add_builtin_function_common (name, type, function_code, cl,
+ library_name, attrs,
+ lang_hooks.builtin_function_ext_scope);
}
tree
/* Do language specific processing in the builtin function DECL */
tree (*builtin_function) (tree decl);
+ /* Like builtin_function, but make sure the scope is the external scope.
+ This is used to delay putting in back end builtin functions until the ISA
+ that defines the builtin is declared via function specific target options,
+ which can save memory for machines like the x86_64 that have multiple
+ ISAs. If this points to the same function as builtin_function, the
+ backend must add all of the builtins at program initialization time. */
+ tree (*builtin_function_ext_scope) (tree decl);
+
/* Used to set up the tree_contains_structure array for a frontend. */
void (*init_ts) (void);
const char *library_name,
tree attrs);
+extern tree add_builtin_function_ext_scope (const char *name, tree type,
+ int function_code,
+ enum built_in_class cl,
+ const char *library_name,
+ tree attrs);
+
#endif /* GCC_LANG_HOOKS_H */
result = result \
test_flag("Common", flags, " | CL_COMMON") \
test_flag("Target", flags, " | CL_TARGET") \
+ test_flag("Save", flags, " | CL_SAVE") \
test_flag("Joined", flags, " | CL_JOINED") \
test_flag("JoinedOrMissing", flags, " | CL_JOINED | CL_MISSING_OK") \
test_flag("Separate", flags, " | CL_SEPARATE") \
extern const char *const lang_names[];
extern const unsigned int cl_lang_count;
+#define CL_SAVE (1 << 17) /* Target-specific option for attribute. */
#define CL_PARAMS (1 << 18) /* Fake entry. Used to display --param info with --help. */
#define CL_WARNING (1 << 19) /* Enables an (optional) warning message. */
#define CL_OPTIMIZATION (1 << 20) /* Enables an (optional) optimization. */
#define CL_TARGET (1 << 21) /* Target-specific option. */
#define CL_COMMON (1 << 22) /* Language-independent. */
-#define CL_MIN_OPTION_CLASS CL_PARAMS
+#define CL_MIN_OPTION_CLASS CL_SAVE
#define CL_MAX_OPTION_CLASS CL_COMMON
/* From here on the bits describe attributes of the options.
/* Function specific option attribute support. */
#ifndef TARGET_OPTION_VALID_ATTRIBUTE_P
-#define TARGET_OPTION_VALID_ATTRIBUTE_P NULL
+#define TARGET_OPTION_VALID_ATTRIBUTE_P \
+ default_target_option_valid_attribute_p
#endif
#ifndef TARGET_OPTION_SAVE
#endif
#ifndef TARGET_OPTION_PRAGMA_PARSE
-#define TARGET_OPTION_PRAGMA_PARSE NULL
+#define TARGET_OPTION_PRAGMA_PARSE default_target_option_pragma_parse
#endif
#ifndef TARGET_OPTION_CAN_INLINE_P
#define TARGET_OPTION_CAN_INLINE_P default_target_option_can_inline_p
#endif
-#ifndef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION false
-#endif
-
-#ifndef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION false
-#endif
-
#define TARGET_OPTION_HOOKS \
{ \
TARGET_OPTION_VALID_ATTRIBUTE_P, \
TARGET_OPTION_PRINT, \
TARGET_OPTION_PRAGMA_PARSE, \
TARGET_OPTION_CAN_INLINE_P, \
- TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION, \
- TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION, \
}
/* The whole shebang. */
void (*print) (FILE *, int, struct cl_target_option *);
/* Function to parse arguments to be validated for #pragma option, and to
- change the state if the options are valid. If the arguments are NULL,
- use the default target options. Return true if the options are valid,
- and set the current state. */
- bool (*pragma_parse) (tree);
+ change the state if the options are valid. If the first argument is
+ NULL, the second argument specifies the default options to use. Return
+ true if the options are valid, and set the current state. */
+ bool (*pragma_parse) (tree, tree);
/* Function to determine if one function can inline another function. */
bool (*can_inline_p) (tree, tree);
-
- /* Whether the cold attribute changes the optimization level. */
- bool cold_attribute_sets_optimization;
-
- /* Whether the hot attribute changes the optimization level. */
- bool hot_attribute_sets_optimization;
} target_option;
/* For targets that need to mark extra registers as live on entry to
tree ARG_UNUSED (args),
int ARG_UNUSED (flags))
{
+ warning (OPT_Wattributes,
+ "target attribute is not supported on this machine");
+
+ return false;
+}
+
+bool
+default_target_option_pragma_parse (tree ARG_UNUSED (args),
+ tree ARG_UNUSED (pop_target))
+{
+ warning (OPT_Wpragmas,
+ "#pragma GCC target is not supported for this machine");
+
return false;
}
extern tree default_emutls_var_init (tree, tree, tree);
extern bool default_hard_regno_scratch_ok (unsigned int);
extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
+extern bool default_target_option_pragma_parse (tree, tree);
extern bool default_target_option_can_inline_p (tree, tree);
+2008-08-29 Michael Meissner <gnu@the-meissners.org>
+
+ * gcc.target/i386/sse-22.c: Change #pragma GCC option to #pragma
+ GCC target. Change attribute((option(...))) to
+ attribute((target(...))).
+ * gcc.target/i386/sse-23.c: Ditto.
+ * gcc.target/i386/funcspec-1.c: Ditto.
+ * gcc.target/i386/funcspec-2.c: Ditto.
+ * gcc.target/i386/funcspec-3.c: Ditto.
+ * gcc.target/i386/funcspec-4.c: Ditto.
+ * gcc.target/i386/funcspec-5.c: Ditto.
+ * gcc.target/i386/funcspec-6.c: Ditto.
+ * gcc.target/i386/funcspec-7.c: Ditto.
+ * gcc.target/i386/funcspec-8.c: Ditto.
+ * gcc.target/i386/funcspec-9.c: Ditto.
+ * gcc.target/i386/funcspec-10.c: Ditto.
+ * gcc.target/i386/funcspec-11.c: Ditto.
+
+ * gcc.target/i386/cold-1.c: Delete.
+ * gcc.target/i386/hot-1.c: Ditto.
+
+ * gcc.dg/pr36997.c: Add -msse2 to the target flags.
+
+ * gcc.target/i386/funcspec-8.c: #pragma GCC option push is now
+ #pragma GCC push_options, and #pragma GCC option pop is now
+ #pragma GCC pop_options.
+ * gcc.target/i386/opt-2.c: Ditto.
+
2008-08-29 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/mangle-neon.C: Add substitution test.
/* { dg-do compile { target x86_64-*-* i?86-*-* } } */
-/* { dg-options "-std=c99" } */
+/* { dg-options "-std=c99 -msse2" } */
typedef int __m64 __attribute__ ((__vector_size__ (8), __may_alias__));
__m64 _mm_add_si64 (__m64 __m1, __m64 __m2)
+++ /dev/null
-/* Test whether using attribute((cold)) really turns on -Os. Do this test
- by checking whether strcpy calls the library function rather than doing
- the move inline. */
-/* { dg-do compile } */
-/* { dg-options "-O3 -march=k8" } */
-/* { dg-final { scan-assembler "(jmp|call)\t(.*)strcpy" } } */
-
-void cold (char *) __attribute__((__cold__));
-
-void cold (char *a)
-{
- __builtin_strcpy (a, "testing 1.2.3 testing 1.2.3");
-}
static float b[SIZE] __attribute__((__aligned__(16)));
static float c[SIZE] __attribute__((__aligned__(16)));
-void sse_addnums (void) __attribute__ ((__option__ ("sse2")));
+void sse_addnums (void) __attribute__ ((__target__ ("sse2")));
void
sse_addnums (void)
/* { dg-options "-O2 -march=i686" } */
/* { dg-final { scan-assembler-not "cmov" } } */
-extern int foo (int) __attribute__((__option__("arch=i386")));
+extern int foo (int) __attribute__((__target__("arch=i386")));
int
foo (int x)
/* { dg-options "-O2 -march=i386" } */
/* { dg-final { scan-assembler "cmov" } } */
-extern int foo (int) __attribute__((__option__("arch=i686")));
+extern int foo (int) __attribute__((__target__("arch=i686")));
int
foo (int x)
extern void exit (int);
-#define SSE5_ATTR __attribute__((__option__("sse5,fused-madd")))
+#define SSE5_ATTR __attribute__((__target__("sse5,fused-madd")))
extern float flt_mul_add (float a, float b, float c) SSE5_ATTR;
extern float flt_mul_sub (float a, float b, float c) SSE5_ATTR;
extern float flt_neg_mul_add (float a, float b, float c) SSE5_ATTR;
extern void exit (int);
extern void abort (void);
-#define SSE4A_ATTR __attribute__((__option__("arch=amdfam10")))
-#define SSE42_ATTR __attribute__((__option__("sse4.2")))
+#define SSE4A_ATTR __attribute__((__target__("arch=amdfam10")))
+#define SSE42_ATTR __attribute__((__target__("sse4.2")))
static int sse4a_pop_i (int a) SSE4A_ATTR;
static long sse42_pop_l (long a) SSE42_ATTR;
/* { dg-do compile } */
/* no sse500 switch */
-extern void error1 (void) __attribute__((__option__("sse500"))); /* { dg-error "unknown" } */
+extern void error1 (void) __attribute__((__target__("sse500"))); /* { dg-error "unknown" } */
/* Multiple arch switches */
-extern void error2 (void) __attribute__((__option__("arch=core2,arch=k8"))); /* { dg-error "already specified" } */
+extern void error2 (void) __attribute__((__target__("arch=core2,arch=k8"))); /* { dg-error "already specified" } */
/* Unknown tune target */
-extern void error3 (void) __attribute__((__option__("tune=foobar"))); /* { dg-error "bad value" } */
+extern void error3 (void) __attribute__((__target__("tune=foobar"))); /* { dg-error "bad value" } */
/* option on a variable */
-extern int error4 __attribute__((__option__("sse2"))); /* { dg-warning "ignored" } */
+extern int error4 __attribute__((__target__("sse2"))); /* { dg-warning "ignored" } */
/* { dg-do compile } */
/* { dg-require-effective-target ilp32 } */
-extern void test_abm (void) __attribute__((__option__("abm")));
-extern void test_aes (void) __attribute__((__option__("aes")));
-extern void test_fused_madd (void) __attribute__((__option__("fused-madd")));
-extern void test_mmx (void) __attribute__((__option__("mmx")));
-extern void test_pclmul (void) __attribute__((__option__("pclmul")));
-extern void test_popcnt (void) __attribute__((__option__("popcnt")));
-extern void test_recip (void) __attribute__((__option__("recip")));
-extern void test_sse (void) __attribute__((__option__("sse")));
-extern void test_sse2 (void) __attribute__((__option__("sse2")));
-extern void test_sse3 (void) __attribute__((__option__("sse3")));
-extern void test_sse4 (void) __attribute__((__option__("sse4")));
-extern void test_sse4_1 (void) __attribute__((__option__("sse4.1")));
-extern void test_sse4_2 (void) __attribute__((__option__("sse4.2")));
-extern void test_sse4a (void) __attribute__((__option__("sse4a")));
-extern void test_sse5 (void) __attribute__((__option__("sse5")));
-extern void test_ssse3 (void) __attribute__((__option__("ssse3")));
+extern void test_abm (void) __attribute__((__target__("abm")));
+extern void test_aes (void) __attribute__((__target__("aes")));
+extern void test_fused_madd (void) __attribute__((__target__("fused-madd")));
+extern void test_mmx (void) __attribute__((__target__("mmx")));
+extern void test_pclmul (void) __attribute__((__target__("pclmul")));
+extern void test_popcnt (void) __attribute__((__target__("popcnt")));
+extern void test_recip (void) __attribute__((__target__("recip")));
+extern void test_sse (void) __attribute__((__target__("sse")));
+extern void test_sse2 (void) __attribute__((__target__("sse2")));
+extern void test_sse3 (void) __attribute__((__target__("sse3")));
+extern void test_sse4 (void) __attribute__((__target__("sse4")));
+extern void test_sse4_1 (void) __attribute__((__target__("sse4.1")));
+extern void test_sse4_2 (void) __attribute__((__target__("sse4.2")));
+extern void test_sse4a (void) __attribute__((__target__("sse4a")));
+extern void test_sse5 (void) __attribute__((__target__("sse5")));
+extern void test_ssse3 (void) __attribute__((__target__("ssse3")));
-extern void test_no_abm (void) __attribute__((__option__("no-abm")));
-extern void test_no_aes (void) __attribute__((__option__("no-aes")));
-extern void test_no_fused_madd (void) __attribute__((__option__("no-fused-madd")));
-extern void test_no_mmx (void) __attribute__((__option__("no-mmx")));
-extern void test_no_pclmul (void) __attribute__((__option__("no-pclmul")));
-extern void test_no_popcnt (void) __attribute__((__option__("no-popcnt")));
-extern void test_no_recip (void) __attribute__((__option__("no-recip")));
-extern void test_no_sse (void) __attribute__((__option__("no-sse")));
-extern void test_no_sse2 (void) __attribute__((__option__("no-sse2")));
-extern void test_no_sse3 (void) __attribute__((__option__("no-sse3")));
-extern void test_no_sse4 (void) __attribute__((__option__("no-sse4")));
-extern void test_no_sse4_1 (void) __attribute__((__option__("no-sse4.1")));
-extern void test_no_sse4_2 (void) __attribute__((__option__("no-sse4.2")));
-extern void test_no_sse4a (void) __attribute__((__option__("no-sse4a")));
-extern void test_no_sse5 (void) __attribute__((__option__("no-sse5")));
-extern void test_no_ssse3 (void) __attribute__((__option__("no-ssse3")));
+extern void test_no_abm (void) __attribute__((__target__("no-abm")));
+extern void test_no_aes (void) __attribute__((__target__("no-aes")));
+extern void test_no_fused_madd (void) __attribute__((__target__("no-fused-madd")));
+extern void test_no_mmx (void) __attribute__((__target__("no-mmx")));
+extern void test_no_pclmul (void) __attribute__((__target__("no-pclmul")));
+extern void test_no_popcnt (void) __attribute__((__target__("no-popcnt")));
+extern void test_no_recip (void) __attribute__((__target__("no-recip")));
+extern void test_no_sse (void) __attribute__((__target__("no-sse")));
+extern void test_no_sse2 (void) __attribute__((__target__("no-sse2")));
+extern void test_no_sse3 (void) __attribute__((__target__("no-sse3")));
+extern void test_no_sse4 (void) __attribute__((__target__("no-sse4")));
+extern void test_no_sse4_1 (void) __attribute__((__target__("no-sse4.1")));
+extern void test_no_sse4_2 (void) __attribute__((__target__("no-sse4.2")));
+extern void test_no_sse4a (void) __attribute__((__target__("no-sse4a")));
+extern void test_no_sse5 (void) __attribute__((__target__("no-sse5")));
+extern void test_no_ssse3 (void) __attribute__((__target__("no-ssse3")));
-extern void test_arch_i386 (void) __attribute__((__option__("arch=i386")));
-extern void test_arch_i486 (void) __attribute__((__option__("arch=i486")));
-extern void test_arch_i586 (void) __attribute__((__option__("arch=i586")));
-extern void test_arch_pentium (void) __attribute__((__option__("arch=pentium")));
-extern void test_arch_pentium_mmx (void) __attribute__((__option__("arch=pentium-mmx")));
-extern void test_arch_winchip_c6 (void) __attribute__((__option__("arch=winchip-c6")));
-extern void test_arch_winchip2 (void) __attribute__((__option__("arch=winchip2")));
-extern void test_arch_c3 (void) __attribute__((__option__("arch=c3")));
-extern void test_arch_c3_2 (void) __attribute__((__option__("arch=c3-2")));
-extern void test_arch_i686 (void) __attribute__((__option__("arch=i686")));
-extern void test_arch_pentiumpro (void) __attribute__((__option__("arch=pentiumpro")));
-extern void test_arch_pentium2 (void) __attribute__((__option__("arch=pentium2")));
-extern void test_arch_pentium3 (void) __attribute__((__option__("arch=pentium3")));
-extern void test_arch_pentium3m (void) __attribute__((__option__("arch=pentium3m")));
-extern void test_arch_pentium_m (void) __attribute__((__option__("arch=pentium-m")));
-extern void test_arch_pentium4 (void) __attribute__((__option__("arch=pentium4")));
-extern void test_arch_pentium4m (void) __attribute__((__option__("arch=pentium4m")));
-extern void test_arch_prescott (void) __attribute__((__option__("arch=prescott")));
-extern void test_arch_nocona (void) __attribute__((__option__("arch=nocona")));
-extern void test_arch_core2 (void) __attribute__((__option__("arch=core2")));
-extern void test_arch_geode (void) __attribute__((__option__("arch=geode")));
-extern void test_arch_k6 (void) __attribute__((__option__("arch=k6")));
-extern void test_arch_k6_2 (void) __attribute__((__option__("arch=k6-2")));
-extern void test_arch_k6_3 (void) __attribute__((__option__("arch=k6-3")));
-extern void test_arch_athlon (void) __attribute__((__option__("arch=athlon")));
-extern void test_arch_athlon_tbird (void) __attribute__((__option__("arch=athlon-tbird")));
-extern void test_arch_athlon_4 (void) __attribute__((__option__("arch=athlon-4")));
-extern void test_arch_athlon_xp (void) __attribute__((__option__("arch=athlon-xp")));
-extern void test_arch_athlon_mp (void) __attribute__((__option__("arch=athlon-mp")));
-extern void test_arch_k8 (void) __attribute__((__option__("arch=k8")));
-extern void test_arch_k8_sse3 (void) __attribute__((__option__("arch=k8-sse3")));
-extern void test_arch_opteron (void) __attribute__((__option__("arch=opteron")));
-extern void test_arch_opteron_sse3 (void) __attribute__((__option__("arch=opteron-sse3")));
-extern void test_arch_athlon64 (void) __attribute__((__option__("arch=athlon64")));
-extern void test_arch_athlon64_sse3 (void) __attribute__((__option__("arch=athlon64-sse3")));
-extern void test_arch_athlon_fx (void) __attribute__((__option__("arch=athlon-fx")));
-extern void test_arch_amdfam10 (void) __attribute__((__option__("arch=amdfam10")));
-extern void test_arch_barcelona (void) __attribute__((__option__("arch=barcelona")));
-extern void test_arch_foo (void) __attribute__((__option__("arch=foo"))); /* { dg-error "bad value" } */
+extern void test_arch_i386 (void) __attribute__((__target__("arch=i386")));
+extern void test_arch_i486 (void) __attribute__((__target__("arch=i486")));
+extern void test_arch_i586 (void) __attribute__((__target__("arch=i586")));
+extern void test_arch_pentium (void) __attribute__((__target__("arch=pentium")));
+extern void test_arch_pentium_mmx (void) __attribute__((__target__("arch=pentium-mmx")));
+extern void test_arch_winchip_c6 (void) __attribute__((__target__("arch=winchip-c6")));
+extern void test_arch_winchip2 (void) __attribute__((__target__("arch=winchip2")));
+extern void test_arch_c3 (void) __attribute__((__target__("arch=c3")));
+extern void test_arch_c3_2 (void) __attribute__((__target__("arch=c3-2")));
+extern void test_arch_i686 (void) __attribute__((__target__("arch=i686")));
+extern void test_arch_pentiumpro (void) __attribute__((__target__("arch=pentiumpro")));
+extern void test_arch_pentium2 (void) __attribute__((__target__("arch=pentium2")));
+extern void test_arch_pentium3 (void) __attribute__((__target__("arch=pentium3")));
+extern void test_arch_pentium3m (void) __attribute__((__target__("arch=pentium3m")));
+extern void test_arch_pentium_m (void) __attribute__((__target__("arch=pentium-m")));
+extern void test_arch_pentium4 (void) __attribute__((__target__("arch=pentium4")));
+extern void test_arch_pentium4m (void) __attribute__((__target__("arch=pentium4m")));
+extern void test_arch_prescott (void) __attribute__((__target__("arch=prescott")));
+extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona")));
+extern void test_arch_core2 (void) __attribute__((__target__("arch=core2")));
+extern void test_arch_geode (void) __attribute__((__target__("arch=geode")));
+extern void test_arch_k6 (void) __attribute__((__target__("arch=k6")));
+extern void test_arch_k6_2 (void) __attribute__((__target__("arch=k6-2")));
+extern void test_arch_k6_3 (void) __attribute__((__target__("arch=k6-3")));
+extern void test_arch_athlon (void) __attribute__((__target__("arch=athlon")));
+extern void test_arch_athlon_tbird (void) __attribute__((__target__("arch=athlon-tbird")));
+extern void test_arch_athlon_4 (void) __attribute__((__target__("arch=athlon-4")));
+extern void test_arch_athlon_xp (void) __attribute__((__target__("arch=athlon-xp")));
+extern void test_arch_athlon_mp (void) __attribute__((__target__("arch=athlon-mp")));
+extern void test_arch_k8 (void) __attribute__((__target__("arch=k8")));
+extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3")));
+extern void test_arch_opteron (void) __attribute__((__target__("arch=opteron")));
+extern void test_arch_opteron_sse3 (void) __attribute__((__target__("arch=opteron-sse3")));
+extern void test_arch_athlon64 (void) __attribute__((__target__("arch=athlon64")));
+extern void test_arch_athlon64_sse3 (void) __attribute__((__target__("arch=athlon64-sse3")));
+extern void test_arch_athlon_fx (void) __attribute__((__target__("arch=athlon-fx")));
+extern void test_arch_amdfam10 (void) __attribute__((__target__("arch=amdfam10")));
+extern void test_arch_barcelona (void) __attribute__((__target__("arch=barcelona")));
+extern void test_arch_foo (void) __attribute__((__target__("arch=foo"))); /* { dg-error "bad value" } */
-extern void test_tune_i386 (void) __attribute__((__option__("tune=i386")));
-extern void test_tune_i486 (void) __attribute__((__option__("tune=i486")));
-extern void test_tune_i586 (void) __attribute__((__option__("tune=i586")));
-extern void test_tune_pentium (void) __attribute__((__option__("tune=pentium")));
-extern void test_tune_pentium_mmx (void) __attribute__((__option__("tune=pentium-mmx")));
-extern void test_tune_winchip_c6 (void) __attribute__((__option__("tune=winchip-c6")));
-extern void test_tune_winchip2 (void) __attribute__((__option__("tune=winchip2")));
-extern void test_tune_c3 (void) __attribute__((__option__("tune=c3")));
-extern void test_tune_c3_2 (void) __attribute__((__option__("tune=c3-2")));
-extern void test_tune_i686 (void) __attribute__((__option__("tune=i686")));
-extern void test_tune_pentiumpro (void) __attribute__((__option__("tune=pentiumpro")));
-extern void test_tune_pentium2 (void) __attribute__((__option__("tune=pentium2")));
-extern void test_tune_pentium3 (void) __attribute__((__option__("tune=pentium3")));
-extern void test_tune_pentium3m (void) __attribute__((__option__("tune=pentium3m")));
-extern void test_tune_pentium_m (void) __attribute__((__option__("tune=pentium-m")));
-extern void test_tune_pentium4 (void) __attribute__((__option__("tune=pentium4")));
-extern void test_tune_pentium4m (void) __attribute__((__option__("tune=pentium4m")));
-extern void test_tune_prescott (void) __attribute__((__option__("tune=prescott")));
-extern void test_tune_nocona (void) __attribute__((__option__("tune=nocona")));
-extern void test_tune_core2 (void) __attribute__((__option__("tune=core2")));
-extern void test_tune_geode (void) __attribute__((__option__("tune=geode")));
-extern void test_tune_k6 (void) __attribute__((__option__("tune=k6")));
-extern void test_tune_k6_2 (void) __attribute__((__option__("tune=k6-2")));
-extern void test_tune_k6_3 (void) __attribute__((__option__("tune=k6-3")));
-extern void test_tune_athlon (void) __attribute__((__option__("tune=athlon")));
-extern void test_tune_athlon_tbird (void) __attribute__((__option__("tune=athlon-tbird")));
-extern void test_tune_athlon_4 (void) __attribute__((__option__("tune=athlon-4")));
-extern void test_tune_athlon_xp (void) __attribute__((__option__("tune=athlon-xp")));
-extern void test_tune_athlon_mp (void) __attribute__((__option__("tune=athlon-mp")));
-extern void test_tune_k8 (void) __attribute__((__option__("tune=k8")));
-extern void test_tune_k8_sse3 (void) __attribute__((__option__("tune=k8-sse3")));
-extern void test_tune_opteron (void) __attribute__((__option__("tune=opteron")));
-extern void test_tune_opteron_sse3 (void) __attribute__((__option__("tune=opteron-sse3")));
-extern void test_tune_athlon64 (void) __attribute__((__option__("tune=athlon64")));
-extern void test_tune_athlon64_sse3 (void) __attribute__((__option__("tune=athlon64-sse3")));
-extern void test_tune_athlon_fx (void) __attribute__((__option__("tune=athlon-fx")));
-extern void test_tune_amdfam10 (void) __attribute__((__option__("tune=amdfam10")));
-extern void test_tune_barcelona (void) __attribute__((__option__("tune=barcelona")));
-extern void test_tune_generic (void) __attribute__((__option__("tune=generic")));
-extern void test_tune_foo (void) __attribute__((__option__("tune=foo"))); /* { dg-error "bad value" } */
+extern void test_tune_i386 (void) __attribute__((__target__("tune=i386")));
+extern void test_tune_i486 (void) __attribute__((__target__("tune=i486")));
+extern void test_tune_i586 (void) __attribute__((__target__("tune=i586")));
+extern void test_tune_pentium (void) __attribute__((__target__("tune=pentium")));
+extern void test_tune_pentium_mmx (void) __attribute__((__target__("tune=pentium-mmx")));
+extern void test_tune_winchip_c6 (void) __attribute__((__target__("tune=winchip-c6")));
+extern void test_tune_winchip2 (void) __attribute__((__target__("tune=winchip2")));
+extern void test_tune_c3 (void) __attribute__((__target__("tune=c3")));
+extern void test_tune_c3_2 (void) __attribute__((__target__("tune=c3-2")));
+extern void test_tune_i686 (void) __attribute__((__target__("tune=i686")));
+extern void test_tune_pentiumpro (void) __attribute__((__target__("tune=pentiumpro")));
+extern void test_tune_pentium2 (void) __attribute__((__target__("tune=pentium2")));
+extern void test_tune_pentium3 (void) __attribute__((__target__("tune=pentium3")));
+extern void test_tune_pentium3m (void) __attribute__((__target__("tune=pentium3m")));
+extern void test_tune_pentium_m (void) __attribute__((__target__("tune=pentium-m")));
+extern void test_tune_pentium4 (void) __attribute__((__target__("tune=pentium4")));
+extern void test_tune_pentium4m (void) __attribute__((__target__("tune=pentium4m")));
+extern void test_tune_prescott (void) __attribute__((__target__("tune=prescott")));
+extern void test_tune_nocona (void) __attribute__((__target__("tune=nocona")));
+extern void test_tune_core2 (void) __attribute__((__target__("tune=core2")));
+extern void test_tune_geode (void) __attribute__((__target__("tune=geode")));
+extern void test_tune_k6 (void) __attribute__((__target__("tune=k6")));
+extern void test_tune_k6_2 (void) __attribute__((__target__("tune=k6-2")));
+extern void test_tune_k6_3 (void) __attribute__((__target__("tune=k6-3")));
+extern void test_tune_athlon (void) __attribute__((__target__("tune=athlon")));
+extern void test_tune_athlon_tbird (void) __attribute__((__target__("tune=athlon-tbird")));
+extern void test_tune_athlon_4 (void) __attribute__((__target__("tune=athlon-4")));
+extern void test_tune_athlon_xp (void) __attribute__((__target__("tune=athlon-xp")));
+extern void test_tune_athlon_mp (void) __attribute__((__target__("tune=athlon-mp")));
+extern void test_tune_k8 (void) __attribute__((__target__("tune=k8")));
+extern void test_tune_k8_sse3 (void) __attribute__((__target__("tune=k8-sse3")));
+extern void test_tune_opteron (void) __attribute__((__target__("tune=opteron")));
+extern void test_tune_opteron_sse3 (void) __attribute__((__target__("tune=opteron-sse3")));
+extern void test_tune_athlon64 (void) __attribute__((__target__("tune=athlon64")));
+extern void test_tune_athlon64_sse3 (void) __attribute__((__target__("tune=athlon64-sse3")));
+extern void test_tune_athlon_fx (void) __attribute__((__target__("tune=athlon-fx")));
+extern void test_tune_amdfam10 (void) __attribute__((__target__("tune=amdfam10")));
+extern void test_tune_barcelona (void) __attribute__((__target__("tune=barcelona")));
+extern void test_tune_generic (void) __attribute__((__target__("tune=generic")));
+extern void test_tune_foo (void) __attribute__((__target__("tune=foo"))); /* { dg-error "bad value" } */
-extern void test_fpmath_sse (void) __attribute__((__option__("sse2,fpmath=sse")));
-extern void test_fpmath_387 (void) __attribute__((__option__("sse2,fpmath=387")));
-extern void test_fpmath_sse_387 (void) __attribute__((__option__("sse2,fpmath=sse+387")));
-extern void test_fpmath_387_sse (void) __attribute__((__option__("sse2,fpmath=387+sse")));
-extern void test_fpmath_both (void) __attribute__((__option__("sse2,fpmath=both")));
+extern void test_fpmath_sse (void) __attribute__((__target__("sse2,fpmath=sse")));
+extern void test_fpmath_387 (void) __attribute__((__target__("sse2,fpmath=387")));
+extern void test_fpmath_sse_387 (void) __attribute__((__target__("sse2,fpmath=sse+387")));
+extern void test_fpmath_387_sse (void) __attribute__((__target__("sse2,fpmath=387+sse")));
+extern void test_fpmath_both (void) __attribute__((__target__("sse2,fpmath=both")));
/* { dg-do compile } */
/* { dg-require-effective-target lp64 } */
-extern void test_abm (void) __attribute__((__option__("abm")));
-extern void test_aes (void) __attribute__((__option__("aes")));
-extern void test_fused_madd (void) __attribute__((__option__("fused-madd")));
-extern void test_mmx (void) __attribute__((__option__("mmx")));
-extern void test_pclmul (void) __attribute__((__option__("pclmul")));
-extern void test_popcnt (void) __attribute__((__option__("popcnt")));
-extern void test_recip (void) __attribute__((__option__("recip")));
-extern void test_sse (void) __attribute__((__option__("sse")));
-extern void test_sse2 (void) __attribute__((__option__("sse2")));
-extern void test_sse3 (void) __attribute__((__option__("sse3")));
-extern void test_sse4 (void) __attribute__((__option__("sse4")));
-extern void test_sse4_1 (void) __attribute__((__option__("sse4.1")));
-extern void test_sse4_2 (void) __attribute__((__option__("sse4.2")));
-extern void test_sse4a (void) __attribute__((__option__("sse4a")));
-extern void test_sse5 (void) __attribute__((__option__("sse5")));
-extern void test_ssse3 (void) __attribute__((__option__("ssse3")));
+extern void test_abm (void) __attribute__((__target__("abm")));
+extern void test_aes (void) __attribute__((__target__("aes")));
+extern void test_fused_madd (void) __attribute__((__target__("fused-madd")));
+extern void test_mmx (void) __attribute__((__target__("mmx")));
+extern void test_pclmul (void) __attribute__((__target__("pclmul")));
+extern void test_popcnt (void) __attribute__((__target__("popcnt")));
+extern void test_recip (void) __attribute__((__target__("recip")));
+extern void test_sse (void) __attribute__((__target__("sse")));
+extern void test_sse2 (void) __attribute__((__target__("sse2")));
+extern void test_sse3 (void) __attribute__((__target__("sse3")));
+extern void test_sse4 (void) __attribute__((__target__("sse4")));
+extern void test_sse4_1 (void) __attribute__((__target__("sse4.1")));
+extern void test_sse4_2 (void) __attribute__((__target__("sse4.2")));
+extern void test_sse4a (void) __attribute__((__target__("sse4a")));
+extern void test_sse5 (void) __attribute__((__target__("sse5")));
+extern void test_ssse3 (void) __attribute__((__target__("ssse3")));
-extern void test_no_abm (void) __attribute__((__option__("no-abm")));
-extern void test_no_aes (void) __attribute__((__option__("no-aes")));
-extern void test_no_fused_madd (void) __attribute__((__option__("no-fused-madd")));
-extern void test_no_mmx (void) __attribute__((__option__("no-mmx")));
-extern void test_no_pclmul (void) __attribute__((__option__("no-pclmul")));
-extern void test_no_popcnt (void) __attribute__((__option__("no-popcnt")));
-extern void test_no_recip (void) __attribute__((__option__("no-recip")));
-extern void test_no_sse (void) __attribute__((__option__("no-sse")));
-extern void test_no_sse2 (void) __attribute__((__option__("no-sse2")));
-extern void test_no_sse3 (void) __attribute__((__option__("no-sse3")));
-extern void test_no_sse4 (void) __attribute__((__option__("no-sse4")));
-extern void test_no_sse4_1 (void) __attribute__((__option__("no-sse4.1")));
-extern void test_no_sse4_2 (void) __attribute__((__option__("no-sse4.2")));
-extern void test_no_sse4a (void) __attribute__((__option__("no-sse4a")));
-extern void test_no_sse5 (void) __attribute__((__option__("no-sse5")));
-extern void test_no_ssse3 (void) __attribute__((__option__("no-ssse3")));
+extern void test_no_abm (void) __attribute__((__target__("no-abm")));
+extern void test_no_aes (void) __attribute__((__target__("no-aes")));
+extern void test_no_fused_madd (void) __attribute__((__target__("no-fused-madd")));
+extern void test_no_mmx (void) __attribute__((__target__("no-mmx")));
+extern void test_no_pclmul (void) __attribute__((__target__("no-pclmul")));
+extern void test_no_popcnt (void) __attribute__((__target__("no-popcnt")));
+extern void test_no_recip (void) __attribute__((__target__("no-recip")));
+extern void test_no_sse (void) __attribute__((__target__("no-sse")));
+extern void test_no_sse2 (void) __attribute__((__target__("no-sse2")));
+extern void test_no_sse3 (void) __attribute__((__target__("no-sse3")));
+extern void test_no_sse4 (void) __attribute__((__target__("no-sse4")));
+extern void test_no_sse4_1 (void) __attribute__((__target__("no-sse4.1")));
+extern void test_no_sse4_2 (void) __attribute__((__target__("no-sse4.2")));
+extern void test_no_sse4a (void) __attribute__((__target__("no-sse4a")));
+extern void test_no_sse5 (void) __attribute__((__target__("no-sse5")));
+extern void test_no_ssse3 (void) __attribute__((__target__("no-ssse3")));
-extern void test_arch_nocona (void) __attribute__((__option__("arch=nocona")));
-extern void test_arch_core2 (void) __attribute__((__option__("arch=core2")));
-extern void test_arch_k8 (void) __attribute__((__option__("arch=k8")));
-extern void test_arch_k8_sse3 (void) __attribute__((__option__("arch=k8-sse3")));
-extern void test_arch_opteron (void) __attribute__((__option__("arch=opteron")));
-extern void test_arch_opteron_sse3 (void) __attribute__((__option__("arch=opteron-sse3")));
-extern void test_arch_athlon64 (void) __attribute__((__option__("arch=athlon64")));
-extern void test_arch_athlon64_sse3 (void) __attribute__((__option__("arch=athlon64-sse3")));
-extern void test_arch_athlon_fx (void) __attribute__((__option__("arch=athlon-fx")));
-extern void test_arch_amdfam10 (void) __attribute__((__option__("arch=amdfam10")));
-extern void test_arch_barcelona (void) __attribute__((__option__("arch=barcelona")));
-extern void test_arch_foo (void) __attribute__((__option__("arch=foo"))); /* { dg-error "bad value" } */
+extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona")));
+extern void test_arch_core2 (void) __attribute__((__target__("arch=core2")));
+extern void test_arch_k8 (void) __attribute__((__target__("arch=k8")));
+extern void test_arch_k8_sse3 (void) __attribute__((__target__("arch=k8-sse3")));
+extern void test_arch_opteron (void) __attribute__((__target__("arch=opteron")));
+extern void test_arch_opteron_sse3 (void) __attribute__((__target__("arch=opteron-sse3")));
+extern void test_arch_athlon64 (void) __attribute__((__target__("arch=athlon64")));
+extern void test_arch_athlon64_sse3 (void) __attribute__((__target__("arch=athlon64-sse3")));
+extern void test_arch_athlon_fx (void) __attribute__((__target__("arch=athlon-fx")));
+extern void test_arch_amdfam10 (void) __attribute__((__target__("arch=amdfam10")));
+extern void test_arch_barcelona (void) __attribute__((__target__("arch=barcelona")));
+extern void test_arch_foo (void) __attribute__((__target__("arch=foo"))); /* { dg-error "bad value" } */
-extern void test_tune_nocona (void) __attribute__((__option__("tune=nocona")));
-extern void test_tune_core2 (void) __attribute__((__option__("tune=core2")));
-extern void test_tune_k8 (void) __attribute__((__option__("tune=k8")));
-extern void test_tune_k8_sse3 (void) __attribute__((__option__("tune=k8-sse3")));
-extern void test_tune_opteron (void) __attribute__((__option__("tune=opteron")));
-extern void test_tune_opteron_sse3 (void) __attribute__((__option__("tune=opteron-sse3")));
-extern void test_tune_athlon64 (void) __attribute__((__option__("tune=athlon64")));
-extern void test_tune_athlon64_sse3 (void) __attribute__((__option__("tune=athlon64-sse3")));
-extern void test_tune_athlon_fx (void) __attribute__((__option__("tune=athlon-fx")));
-extern void test_tune_amdfam10 (void) __attribute__((__option__("tune=amdfam10")));
-extern void test_tune_barcelona (void) __attribute__((__option__("tune=barcelona")));
-extern void test_tune_generic (void) __attribute__((__option__("tune=generic")));
-extern void test_tune_foo (void) __attribute__((__option__("tune=foo"))); /* { dg-error "bad value" } */
+extern void test_tune_nocona (void) __attribute__((__target__("tune=nocona")));
+extern void test_tune_core2 (void) __attribute__((__target__("tune=core2")));
+extern void test_tune_k8 (void) __attribute__((__target__("tune=k8")));
+extern void test_tune_k8_sse3 (void) __attribute__((__target__("tune=k8-sse3")));
+extern void test_tune_opteron (void) __attribute__((__target__("tune=opteron")));
+extern void test_tune_opteron_sse3 (void) __attribute__((__target__("tune=opteron-sse3")));
+extern void test_tune_athlon64 (void) __attribute__((__target__("tune=athlon64")));
+extern void test_tune_athlon64_sse3 (void) __attribute__((__target__("tune=athlon64-sse3")));
+extern void test_tune_athlon_fx (void) __attribute__((__target__("tune=athlon-fx")));
+extern void test_tune_amdfam10 (void) __attribute__((__target__("tune=amdfam10")));
+extern void test_tune_barcelona (void) __attribute__((__target__("tune=barcelona")));
+extern void test_tune_generic (void) __attribute__((__target__("tune=generic")));
+extern void test_tune_foo (void) __attribute__((__target__("tune=foo"))); /* { dg-error "bad value" } */
-extern void test_fpmath_sse (void) __attribute__((__option__("sse2,fpmath=sse")));
-extern void test_fpmath_387 (void) __attribute__((__option__("sse2,fpmath=387")));
-extern void test_fpmath_sse_387 (void) __attribute__((__option__("sse2,fpmath=sse+387")));
-extern void test_fpmath_387_sse (void) __attribute__((__option__("sse2,fpmath=387+sse")));
-extern void test_fpmath_both (void) __attribute__((__option__("sse2,fpmath=both")));
+extern void test_fpmath_sse (void) __attribute__((__target__("sse2,fpmath=sse")));
+extern void test_fpmath_387 (void) __attribute__((__target__("sse2,fpmath=387")));
+extern void test_fpmath_sse_387 (void) __attribute__((__target__("sse2,fpmath=sse+387")));
+extern void test_fpmath_387_sse (void) __attribute__((__target__("sse2,fpmath=387+sse")));
+extern void test_fpmath_both (void) __attribute__((__target__("sse2,fpmath=both")));
/* { dg-do compile } */
/* { dg-options "-O2 -march=k8 -mno-recip -mfpmath=sse -ffast-math" } */
-float do_recip (float a) __attribute__((__option__("recip")));
+float do_recip (float a) __attribute__((__target__("recip")));
float do_normal (float a);
float do_recip (float a) { return 1.0f / __builtin_sqrtf (a); }
#error "-msse3 should not be set for this test"
#endif
-__m128d sse3_hsubpd (__m128d a, __m128d b) __attribute__((__option__("sse3")));
+__m128d sse3_hsubpd (__m128d a, __m128d b) __attribute__((__target__("sse3")));
__m128d generic_hsubpd (__m128d a, __m128d b);
__m128d
#error "-mssse3 should not be set for this test"
#endif
-__m128w ssse3_psignd128 (__m128w a, __m128w b) __attribute__((__option__("ssse3")));
+__m128w ssse3_psignd128 (__m128w a, __m128w b) __attribute__((__target__("ssse3")));
__m128w generic_psignd (__m128w ab, __m128w b);
__m128w
#error "-msse4.1 should not be set for this test"
#endif
-__m128d sse4_1_blendvpd (__m128d a, __m128d b, __m128d c) __attribute__((__option__("sse4.1")));
+__m128d sse4_1_blendvpd (__m128d a, __m128d b, __m128d c) __attribute__((__target__("sse4.1")));
__m128d generic_blendvpd (__m128d a, __m128d b, __m128d c);
__m128d
#error "-msse4.2 should not be set for this test"
#endif
-__m128i sse4_2_pcmpgtq (__m128i a, __m128i b) __attribute__((__option__("sse4.2")));
+__m128i sse4_2_pcmpgtq (__m128i a, __m128i b) __attribute__((__target__("sse4.2")));
__m128i generic_pcmpgtq (__m128i ab, __m128i b);
__m128i
#error "-msse4a should not be set for this test"
#endif
-__m128i sse4_2_insertq (__m128i a, __m128i b) __attribute__((__option__("sse4a")));
+__m128i sse4_2_insertq (__m128i a, __m128i b) __attribute__((__target__("sse4a")));
__m128i generic_insertq (__m128i ab, __m128i b);
__m128i
#error "-msse5 should not be set for this test"
#endif
-__m128d sse5_fmaddpd (__m128d a, __m128d b, __m128d c) __attribute__((__option__("sse5")));
+__m128d sse5_fmaddpd (__m128d a, __m128d b, __m128d c) __attribute__((__target__("sse5")));
__m128d generic_fmaddpd (__m128d a, __m128d b, __m128d c);
__m128d
#error "-maes should not be set for this test"
#endif
-__m128i aes_aesimc128 (__m128i a) __attribute__((__option__("aes")));
+__m128i aes_aesimc128 (__m128i a) __attribute__((__target__("aes")));
__m128i generic_aesimc128 (__m128i a);
__m128i
#error "-mpclmul should not be set for this test"
#endif
-__m128i pclmul_pclmulqdq128 (__m128i a, __m128i b) __attribute__((__option__("pclmul")));
+__m128i pclmul_pclmulqdq128 (__m128i a, __m128i b) __attribute__((__target__("pclmul")));
__m128i generic_pclmulqdq128 (__m128i a, __m128i b);
__m128i
extern void exit (int);
#ifdef __SSE5__
-#warning "__SSE5__ should not be defined before #pragma GCC option."
+#warning "__SSE5__ should not be defined before #pragma GCC target."
#endif
-#pragma GCC option (push)
-#pragma GCC option ("sse5,fused-madd")
+#pragma GCC push_options
+#pragma GCC target ("sse5,fused-madd")
#ifndef __SSE5__
-#warning "__SSE5__ should have be defined after #pragma GCC option."
+#warning "__SSE5__ should have be defined after #pragma GCC target."
#endif
float
return (a * b) + c;
}
-#pragma GCC option (pop)
+#pragma GCC pop_options
#ifdef __SSE5__
-#warning "__SSE5__ should not be defined after #pragma GCC pop option."
+#warning "__SSE5__ should not be defined after #pragma GCC pop target."
#endif
double
+++ /dev/null
-/* Test whether using attribute((hot)) really turns on -O3. Do this test
- by checking whether we vectorize a simple loop. */
-/* { dg-do compile } */
-/* { dg-options "-O1 -msse2 -mfpmath=sse -march=k8" } */
-/* { dg-final { scan-assembler "addps" } } */
-/* { dg-final { scan-assembler "subss" } } */
-
-#define SIZE 1024
-float a[SIZE] __attribute__((__aligned__(32)));
-float b[SIZE] __attribute__((__aligned__(32)));
-float c[SIZE] __attribute__((__aligned__(32)));
-
-/* This should vectorize. */
-void hot (void) __attribute__((__hot__));
-
-void
-hot (void)
-{
- int i;
-
- for (i = 0; i < SIZE; i++)
- a[i] = b[i] + c[i];
-}
-
-/* This should not vectorize. */
-void
-not_hot (void)
-{
- int i;
-
- for (i = 0; i < SIZE; i++)
- a[i] = b[i] - c[i];
-}
float c[SIZE] __attribute__((__aligned__(32)));
/* This should vectorize. */
-#pragma GCC optimize push
+#pragma GCC push_options
#pragma GCC optimize (3, "unroll-all-loops", "-fprefetch-loop-arrays")
void
a[i] = b[i] + c[i];
}
-#pragma GCC optimize pop
+#pragma GCC pop_options
/* This should not vectorize. */
void
#ifndef DIFFERENT_PRAGMAS
-#pragma GCC option ("mmx,3dnow,sse,sse2,sse3,ssse3,sse4.1,sse4.2,sse5,aes,pclmul")
+#pragma GCC target ("mmx,3dnow,sse,sse2,sse3,ssse3,sse4.1,sse4.2,sse5,aes,pclmul")
#endif
/* Following intrinsics require immediate arguments. They
/* mmintrin.h (MMX). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("mmx")
+#pragma GCC target ("mmx")
#endif
#include <mmintrin.h>
/* mm3dnow.h (3DNOW). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("3dnow")
+#pragma GCC target ("3dnow")
#endif
#include <mm3dnow.h>
/* xmmintrin.h (SSE). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("sse")
+#pragma GCC target ("sse")
#endif
#include <xmmintrin.h>
test_2 (_mm_shuffle_ps, __m128, __m128, __m128, 1)
/* emmintrin.h (SSE2). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("sse2")
+#pragma GCC target ("sse2")
#endif
#include <emmintrin.h>
test_2 (_mm_shuffle_pd, __m128d, __m128d, __m128d, 1)
/* pmmintrin.h (SSE3). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("sse3")
+#pragma GCC target ("sse3")
#endif
#include <pmmintrin.h>
/* tmmintrin.h (SSSE3). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("ssse3")
+#pragma GCC target ("ssse3")
#endif
#include <tmmintrin.h>
test_2 (_mm_alignr_epi8, __m128i, __m128i, __m128i, 1)
/* ammintrin.h (SSE4A). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("sse4a")
+#pragma GCC target ("sse4a")
#endif
#include <ammintrin.h>
test_1x (_mm_extracti_si64, __m128i, __m128i, 1, 1)
/* Note, nmmintrin.h includes smmintrin.h, and smmintrin.h checks for the
#ifdef. So just set the option to SSE4.2. */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("sse4.2")
+#pragma GCC target ("sse4.2")
#endif
#include <nmmintrin.h>
test_2 (_mm_blend_epi16, __m128i, __m128i, __m128i, 1)
/* bmmintrin.h (SSE5). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("sse5")
+#pragma GCC target ("sse5")
#endif
#include <bmmintrin.h>
test_1 (_mm_roti_epi8, __m128i, __m128i, 1)
/* wmmintrin.h (AES/PCLMUL). */
#ifdef DIFFERENT_PRAGMAS
-#pragma GCC option ("aes,pclmul")
+#pragma GCC target ("aes,pclmul")
#endif
#include <wmmintrin.h>
test_1 (_mm_aeskeygenassist_si128, __m128i, __m128i, 1)
#define __builtin_ia32_protqi(A, B) __builtin_ia32_protqi(A,1)
-#pragma GCC option ("3dnow,sse4,sse5,aes,pclmul")
+#pragma GCC target ("3dnow,sse4,sse5,aes,pclmul")
#include <wmmintrin.h>
#include <bmmintrin.h>
#include <smmintrin.h>
bool
tree_can_inline_p (tree caller, tree callee)
{
+#if 0
+ /* This causes a regression in SPEC in that it prevents a cold function from
+ inlining a hot function. Perhaps this should only apply to functions
+ that the user declares hot/cold/optimize explicitly. */
+
/* Don't inline a function with a higher optimization level than the
caller, or with different space constraints (hot/cold functions). */
tree caller_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (caller);
|| (caller_opt->optimize_size != callee_opt->optimize_size))
return false;
}
+#endif
/* Allow the backend to decide if inlining is ok. */
return targetm.target_option.can_inline_p (caller, callee);
TI_OPTIMIZATION_DEFAULT,
TI_OPTIMIZATION_CURRENT,
- TI_OPTIMIZATION_COLD,
- TI_OPTIMIZATION_HOT,
TI_TARGET_OPTION_DEFAULT,
TI_TARGET_OPTION_CURRENT,
- TI_CURRENT_OPTION_PRAGMA,
+ TI_CURRENT_TARGET_PRAGMA,
TI_CURRENT_OPTIMIZE_PRAGMA,
TI_MAX
#define main_identifier_node global_trees[TI_MAIN_IDENTIFIER]
#define MAIN_NAME_P(NODE) (IDENTIFIER_NODE_CHECK (NODE) == main_identifier_node)
-/* Optimization options (OPTIMIZATION_NODE) to use for default, current, cold,
- and hot functions. */
+/* Optimization options (OPTIMIZATION_NODE) to use for default and current
+ functions. */
#define optimization_default_node global_trees[TI_OPTIMIZATION_DEFAULT]
#define optimization_current_node global_trees[TI_OPTIMIZATION_CURRENT]
-#define optimization_cold_node global_trees[TI_OPTIMIZATION_COLD]
-#define optimization_hot_node global_trees[TI_OPTIMIZATION_HOT]
/* Default/current target options (TARGET_OPTION_NODE). */
#define target_option_default_node global_trees[TI_TARGET_OPTION_DEFAULT]
/* Default tree list option(), optimize() pragmas to be linked into the
attribute list. */
-#define current_option_pragma global_trees[TI_CURRENT_OPTION_PRAGMA]
+#define current_target_pragma global_trees[TI_CURRENT_TARGET_PRAGMA]
#define current_optimize_pragma global_trees[TI_CURRENT_OPTIMIZE_PRAGMA]
/* An enumeration of the standard C integer types. These must be