Change attribute((option(...))) to attribute((target(...))); Do not allocate tree nodes on x86 for builtins until we generate code for the ISA; Delete hot/cold functions changing optimization; Make C++ support target specific functions; Add #pragma GCC {push_options,pop_options,reset_options} instead of #pragma GCC {target,optimize} {push,reset,pop}

From-SVN: r139812
This commit is contained in:
Michael Meissner 2008-08-30 23:50:40 +00:00 committed by Michael Meissner
parent 0257eee5bd
commit 5779e7133d
45 changed files with 938 additions and 711 deletions

View File

@ -5,6 +5,151 @@
* 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

View File

@ -252,18 +252,18 @@ decl_attributes (tree *node, tree attributes, int flags)
&& !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));
}

View File

@ -571,7 +571,7 @@ static tree handle_warn_unused_result_attribute (tree *, tree, tree, int,
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 *);
@ -856,8 +856,8 @@ const struct attribute_spec c_common_attribute_table[] =
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 }
@ -5260,34 +5260,8 @@ handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
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 (&current_options);
decode_options (2, os_argv);
optimization_hot_node = build_optimization_node ();
cl_optimization_restore (&current_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
{
@ -5312,34 +5286,8 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
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 (&current_options);
decode_options (2, os_argv);
optimization_cold_node = build_optimization_node ();
cl_optimization_restore (&current_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
{
@ -7038,11 +6986,10 @@ handle_type_generic_attribute (tree *node, tree ARG_UNUSED (name),
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. */
@ -7051,14 +6998,6 @@ handle_option_attribute (tree *node, tree name, tree args, int flags,
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;

View File

@ -2843,6 +2843,31 @@ c_builtin_function (tree decl)
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;
}
/* 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

View File

@ -69,6 +69,8 @@ extern void c_initialize_diagnostics (diagnostic_context *);
#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

View File

@ -866,15 +866,11 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy))
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;
@ -884,12 +880,6 @@ handle_pragma_option(cpp_reader *ARG_UNUSED(dummy))
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)
{
@ -897,76 +887,9 @@ handle_pragma_option(cpp_reader *ARG_UNUSED(dummy))
token = pragma_lex (&x);
}
if (token == CPP_NAME)
if (token != CPP_STRING)
{
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)
{
GCC_BAD ("%<#pragma GCC option%> is not a string or push/pop/reset");
GCC_BAD ("%<#pragma GCC option%> is not a string");
return;
}
@ -993,34 +916,29 @@ handle_pragma_option(cpp_reader *ARG_UNUSED(dummy))
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;
@ -1038,95 +956,9 @@ handle_pragma_optimize(cpp_reader *ARG_UNUSED(dummy))
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;
}
@ -1166,6 +998,7 @@ handle_pragma_optimize(cpp_reader *ARG_UNUSED(dummy))
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,
@ -1173,6 +1006,133 @@ handle_pragma_optimize(cpp_reader *ARG_UNUSED(dummy))
}
}
/* 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
@ -1368,8 +1328,11 @@ init_pragma (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);

View File

@ -488,6 +488,7 @@ extern void push_parm_decl (const struct c_parm *);
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);

View File

@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see
#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 *));
@ -232,11 +232,12 @@ ix86_target_macros_internal (int isa_flag,
}
/* 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;
@ -252,12 +253,14 @@ ix86_pragma_option_parse (tree args)
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;
}
@ -339,8 +342,8 @@ ix86_target_macros (void)
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 ();

View File

@ -204,7 +204,7 @@ extern int ix86_constant_alignment (tree, int);
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);

View File

@ -1793,6 +1793,7 @@ static int ix86_function_regparm (const_tree, const_tree);
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
{
@ -1809,8 +1810,8 @@ static void ix86_function_specific_save (struct cl_target_option *);
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);
@ -2583,7 +2584,7 @@ override_options (bool main_args_p)
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";
@ -3366,12 +3367,12 @@ ix86_function_specific_print (FILE *file, int indent,
}
/* 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;
@ -3462,7 +3463,7 @@ ix86_valid_option_attribute_inner_p (tree args, char *p_strings[])
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;
@ -3531,7 +3532,7 @@ ix86_valid_option_attribute_inner_p (tree args, char *p_strings[])
/* 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;
}
@ -3570,7 +3571,7 @@ ix86_valid_option_attribute_inner_p (tree args, char *p_strings[])
/* 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;
@ -3584,7 +3585,7 @@ ix86_valid_option_attribute_tree (tree args)
= 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,
@ -3617,6 +3618,9 @@ ix86_valid_option_attribute_tree (tree args)
/* 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 ();
@ -3634,27 +3638,47 @@ ix86_valid_option_attribute_tree (tree args)
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;
tree old_optimize = build_optimization_node ();
tree new_target, new_optimize;
tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
cl_target_option_save (&cur_opts);
new_opts = ix86_valid_option_attribute_tree (args);
if (!new_opts)
/* 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;
}
@ -19535,6 +19559,7 @@ enum ix86_builtins
IX86_BUILTIN_FNMSUBSD,
IX86_BUILTIN_FNMSUBPS,
IX86_BUILTIN_FNMSUBPD,
IX86_BUILTIN_PCMOV,
IX86_BUILTIN_PCMOV_V2DI,
IX86_BUILTIN_PCMOV_V4SI,
IX86_BUILTIN_PCMOV_V8HI,
@ -19734,17 +19759,35 @@ enum ix86_builtins
/* 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)
@ -19753,10 +19796,25 @@ 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;
@ -19771,9 +19829,40 @@ def_builtin_const (int mask, const char *name, tree type,
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
@ -20787,7 +20876,7 @@ static const struct builtin_description bdesc_multi_arg[] =
{ 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 },
@ -23986,10 +24075,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
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)
@ -29026,7 +29115,7 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#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
@ -29040,12 +29129,6 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#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;
#include "gt-i386.h"

View File

@ -493,12 +493,6 @@ static const struct attribute_spec ia64_attribute_table[] =
#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;
typedef enum

View File

@ -1,3 +1,19 @@
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

View File

@ -86,6 +86,8 @@ extern tree objcp_tsubst_copy_and_build (tree, tree, tsubst_flags_t,
#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

View File

@ -4364,6 +4364,7 @@ extern tree register_dtor_fn (tree);
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);

View File

@ -66,7 +66,7 @@ static tree grok_reference_init (tree, tree, tree, 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,
@ -1764,6 +1764,20 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
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)
@ -3497,7 +3511,7 @@ cp_make_fname_decl (tree id, int type_dep)
}
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);
@ -3518,7 +3532,10 @@ builtin_function_1 (tree decl, tree context)
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
@ -3551,11 +3568,36 @@ cxx_builtin_function (tree decl)
{
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);
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, true);
}
/* Generate a FUNCTION_DECL with the typical flags for a runtime library

View File

@ -2665,19 +2665,19 @@ take function pointer arguments. The @code{nothrow} attribute is not
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
@ -2687,8 +2687,8 @@ supports the particular ISA it was compiled for (for example by using
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:
@ -2696,132 +2696,132 @@ 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
@ -2831,10 +2831,10 @@ options, or you can separate the option with a comma (@code{,}).
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
@ -2853,17 +2853,7 @@ that affect more than one function.
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
@ -2903,10 +2893,6 @@ are automatically detected and this attribute is ignored.
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
@ -2924,10 +2910,6 @@ are automatically detected and this attribute is ignored.
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
@ -11834,41 +11816,22 @@ push_macro} and restored by @code{#pragma pop_macro}.
@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.
386 and x86_64 backends.
@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.
@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
@ -11886,22 +11849,31 @@ versions earlier than 4.4.
@end table
@table @code
@item #pragma GCC optimize (push)
@itemx #pragma GCC optimize (pop)
@cindex pragma GCC optimize
@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 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.
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

View File

@ -112,6 +112,7 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
#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
@ -272,6 +273,7 @@ extern tree lhd_make_node (enum tree_code);
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, \
}

View File

@ -540,13 +540,16 @@ lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *c ATTRIBUTE_UNUSED,
{
}
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);
@ -571,10 +574,45 @@ add_builtin_function (const char *name,
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
lhd_builtin_function (tree decl)
{

View File

@ -410,6 +410,14 @@ struct lang_hooks
/* 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);
@ -429,4 +437,10 @@ extern tree add_builtin_function (const char *name, tree type,
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 */

View File

@ -71,6 +71,7 @@ function switch_flags (flags)
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") \

View File

@ -65,13 +65,14 @@ extern const unsigned int cl_options_count;
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.

View File

@ -766,7 +766,8 @@
/* 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
@ -782,21 +783,13 @@
#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, \
@ -805,8 +798,6 @@
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. */

View File

@ -991,19 +991,13 @@ struct gcc_target
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

View File

@ -715,6 +715,19 @@ default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl),
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;
}

View File

@ -99,4 +99,5 @@ extern tree default_emutls_var_fields (tree, tree *);
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);

View File

@ -1,3 +1,31 @@
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.

View File

@ -1,5 +1,5 @@
/* { 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)

View File

@ -1,13 +0,0 @@
/* 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");
}

View File

@ -15,7 +15,7 @@ static float a[SIZE] __attribute__((__aligned__(16)));
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)

View File

@ -4,7 +4,7 @@
/* { 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)

View File

@ -4,7 +4,7 @@
/* { 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)

View File

@ -5,7 +5,7 @@
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;

View File

@ -7,8 +7,8 @@
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;

View File

@ -2,13 +2,13 @@
/* { 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" } */

View File

@ -3,123 +3,123 @@
/* { 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")));

View File

@ -3,69 +3,69 @@
/* { 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")));

View File

@ -3,7 +3,7 @@
/* { 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); }

View File

@ -12,7 +12,7 @@ typedef long long __m128i __attribute__ ((__vector_size__ (16), __may_alias__));
#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
@ -31,7 +31,7 @@ generic_hsubpd (__m128d a, __m128d b)
#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
@ -50,7 +50,7 @@ generic_psignd128 (__m128w a, __m128w b)
#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
@ -69,7 +69,7 @@ generic_blendvpd (__m128d a, __m128d b, __m128d c)
#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
@ -88,7 +88,7 @@ generic_pcmpgtq (__m128i a, __m128i b)
#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
@ -107,7 +107,7 @@ generic_insertq (__m128i a, __m128i b)
#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
@ -126,7 +126,7 @@ generic_fmaddpd (__m128d a, __m128d b, __m128d c)
#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
@ -145,7 +145,7 @@ generic_aesimc128 (__m128i a)
#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

View File

@ -5,14 +5,14 @@
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
@ -21,9 +21,9 @@ flt_mul_add (float a, float b, float c)
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

View File

@ -1,33 +0,0 @@
/* 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];
}

View File

@ -12,7 +12,7 @@ float b[SIZE] __attribute__((__aligned__(32)));
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
@ -24,7 +24,7 @@ opt3 (void)
a[i] = b[i] + c[i];
}
#pragma GCC optimize pop
#pragma GCC pop_options
/* This should not vectorize. */
void

View File

@ -37,7 +37,7 @@
#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
@ -45,19 +45,19 @@
/* 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)
@ -71,7 +71,7 @@ test_1 (_mm_prefetch, void, void *, _MM_HINT_NTA)
/* 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)
@ -85,13 +85,13 @@ test_1 (_mm_shuffle_epi32, __m128i, __m128i, 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)
@ -99,7 +99,7 @@ test_2 (_mm_alignr_pi8, __m64, __m64, __m64, 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)
@ -110,7 +110,7 @@ test_2x (_mm_inserti_si64, __m128i, __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)
@ -148,7 +148,7 @@ test_4 (_mm_cmpestrz, int, __m128i, int, __m128i, int, 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)
@ -158,7 +158,7 @@ test_1 (_mm_roti_epi64, __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)

View File

@ -101,7 +101,7 @@
#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>

View File

@ -4369,6 +4369,11 @@ build_duplicate_type (tree type)
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);
@ -4390,6 +4395,7 @@ tree_can_inline_p (tree caller, tree callee)
|| (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);

View File

@ -3591,11 +3591,9 @@ enum tree_index
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
@ -3765,12 +3763,10 @@ extern GTY(()) tree global_trees[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]
@ -3778,7 +3774,7 @@ extern GTY(()) tree global_trees[TI_MAX];
/* 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