Change attribute((option(...))) to attribute((target(...))); Do not allocate tree...
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Aug 2008 23:50:40 +0000 (23:50 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 30 Aug 2008 23:50:40 +0000 (23:50 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139812 138bc75d-0d04-0410-961f-82ee72b054a4

45 files changed:
gcc/ChangeLog
gcc/attribs.c
gcc/c-common.c
gcc/c-decl.c
gcc/c-objc-common.h
gcc/c-pragma.c
gcc/c-tree.h
gcc/config/i386/i386-c.c
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/ia64/ia64.c
gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.h
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/doc/extend.texi
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/opt-functions.awk
gcc/opts.h
gcc/target-def.h
gcc/target.h
gcc/targhooks.c
gcc/targhooks.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr36997.c
gcc/testsuite/gcc.target/i386/cold-1.c [deleted file]
gcc/testsuite/gcc.target/i386/funcspec-1.c
gcc/testsuite/gcc.target/i386/funcspec-10.c
gcc/testsuite/gcc.target/i386/funcspec-11.c
gcc/testsuite/gcc.target/i386/funcspec-2.c
gcc/testsuite/gcc.target/i386/funcspec-3.c
gcc/testsuite/gcc.target/i386/funcspec-4.c
gcc/testsuite/gcc.target/i386/funcspec-5.c
gcc/testsuite/gcc.target/i386/funcspec-6.c
gcc/testsuite/gcc.target/i386/funcspec-7.c
gcc/testsuite/gcc.target/i386/funcspec-8.c
gcc/testsuite/gcc.target/i386/funcspec-9.c
gcc/testsuite/gcc.target/i386/hot-1.c [deleted file]
gcc/testsuite/gcc.target/i386/opt-2.c
gcc/testsuite/gcc.target/i386/sse-22.c
gcc/testsuite/gcc.target/i386/sse-23.c
gcc/tree-inline.c
gcc/tree.h

index 868a541..5b5c833 100644 (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
index ba6a9e2..dbce181 100644 (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));
     }
index 4493a4b..748ab52 100644 (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;
index ee04d9a..5a60063 100644 (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;
+}
 \f
 /* Called when a declaration is seen that contains no names to declare.
    If its type is a reference to a structure, union or enum inherited
index c48838c..9c73fdd 100644 (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
index 63c0acb..2f2095e 100644 (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)
-    {
-      bool call_pragma_parse_p = false;
-      bool ok_p;
-
-      name = IDENTIFIER_POINTER (x);
-      if (strcmp (name, "reset") == 0)
-       {
-         current_option_pragma = NULL_TREE;
-         call_pragma_parse_p = true;
-       }
-
-      else if (strcmp (name, "push") == 0)
-       VEC_safe_push (tree, gc, option_stack,
-                      copy_list (current_option_pragma));
-
-      else if (strcmp (name, "pop") == 0)
-       {
-         int len = VEC_length (tree, option_stack);
-         if (len == 0)
-           {
-             GCC_BAD ("%<#pragma GCC option pop%> without a %<#pragma GCC "
-                      "option push%>");
-             return;
-           }
-         else
-           {
-             VEC_truncate (tree, option_stack, len-1);
-             current_option_pragma = ((len > 1)
-                                      ? VEC_last (tree, option_stack)
-                                      : NULL_TREE);
-
-             call_pragma_parse_p = true;
-           }
-       }
-
-      else
-       {
-         GCC_BAD ("%<#pragma GCC option%> is not a string or "
-                  "push/pop/reset");
-         return;
-       }
-
-      token = pragma_lex (&x);
-      if (close_paren_needed_p)
-       {
-         if (token == CPP_CLOSE_PAREN)
-           token = pragma_lex (&x);
-         else
-           GCC_BAD ("%<#pragma GCC option ([push|pop|reset])%> does not "
-                    "have a final %<)%>.");
-       }
-
-      if (token != CPP_EOF)
-       {
-         GCC_BAD ("%<#pragma GCC option [push|pop|reset]%> is badly "
-                  "formed");
-         return;
-       }
-
-      /* See if we need to call the pragma_parse hook.  This must occur at the
-        end after processing all of the tokens, or we may get spurious errors
-        when we define or undef macros.  */
-      ok_p = targetm.target_option.pragma_parse (current_option_pragma);
-      gcc_assert (ok_p);
-    }
-
-  else if (token != CPP_STRING)
+  if (token != CPP_STRING)
     {
-      GCC_BAD ("%<#pragma GCC option%> is not a string or push/pop/reset");
+      GCC_BAD ("%<#pragma GCC option%> is not a string");
       return;
     }
 
@@ -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);
index 539254e..ab8b36b 100644 (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);
index 411c28d..3d17c10 100644 (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,
 }
 
 \f
-/* Hook to validate the current #pragma option and set the state, and update
-   the macros based on what was changed.  */
+/* Hook to validate the current #pragma GCC target and set the state, and
+   update the macros based on what was changed.  If ARGS is NULL, then
+   POP_TARGET is used to reset the options.  */
 
 static bool
-ix86_pragma_option_parse (tree args)
+ix86_pragma_target_parse (tree args, tree pop_target)
 {
   tree prev_tree = build_target_option_node ();
   tree cur_tree;
@@ -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 ();
index 5f055ab..de02458 100644 (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);
index 002a9a7..b240b7d 100644 (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,
 }
 
 \f
-/* Inner function to process the attribute((option(...))), take an argument and
+/* Inner function to process the attribute((target(...))), take an argument and
    set the current options from the argument. If we have a list, recursively go
    over the list.  */
 
 static bool
-ix86_valid_option_attribute_inner_p (tree args, char *p_strings[])
+ix86_valid_target_attribute_inner_p (tree args, char *p_strings[])
 {
   char *next_optstr;
   bool ret = true;
@@ -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;
-
-  cl_target_option_save (&cur_opts);
-  new_opts = ix86_valid_option_attribute_tree (args);
-  if (!new_opts)
+  tree old_optimize = build_optimization_node ();
+  tree new_target, new_optimize;
+  tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+
+  /* If the function changed the optimization levels as well as setting target
+     options, start with the optimizations specified.  */
+  if (func_optimize && func_optimize != old_optimize)
+    cl_optimization_restore (TREE_OPTIMIZATION (func_optimize));
+
+  /* The target attributes may also change some optimization flags, so update
+     the optimization options if necessary.  */
+  cl_target_option_save (&cur_target);
+  new_target = ix86_valid_target_attribute_tree (args);
+  new_optimize = build_optimization_node ();
+
+  if (!new_target)
     ret = false;
 
   else if (fndecl)
-    DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_opts;
+    {
+      DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
+
+      if (old_optimize != new_optimize)
+       DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+    }
+
+  cl_target_option_restore (&cur_target);
+
+  if (old_optimize != new_optimize)
+    cl_optimization_restore (TREE_OPTIMIZATION (old_optimize));
 
-  cl_target_option_restore (&cur_opts);
   return ret;
 }
 
@@ -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;
 \f
 #include "gt-i386.h"
index e8a853b..d9100e8 100644 (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;
 \f
 typedef enum
index 7802e7e..30c6aa6 100644 (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
index 1121eb0..a7d4f89 100644 (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
index 72963f0..37bed91 100644 (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);
index 0d4dced..5a5a41f 100644 (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, false);
+}
+
+/* Like cxx_builtin_function, but guarantee the function is added to the global
+   scope.  This is to allow function specific options to add new machine
+   dependent builtins when the target ISA changes via attribute((target(...)))
+   which saves space on program startup if the program does not use non-generic
+   ISAs.  */
+
+tree
+cxx_builtin_function_ext_scope (tree decl)
+{
+
+  tree          id = DECL_NAME (decl);
+  const char *name = IDENTIFIER_POINTER (id);
+  /* All builtins that don't begin with an '_' should additionally
+     go in the 'std' namespace.  */
+  if (name[0] != '_')
+    {
+      tree decl2 = copy_node(decl);
+      push_namespace (std_identifier);
+      builtin_function_1 (decl2, std_node, true);
       pop_namespace ();
     }
 
-  return builtin_function_1 (decl, NULL_TREE);
+  return builtin_function_1 (decl, NULL_TREE, true);
 }
 
 /* Generate a FUNCTION_DECL with the typical flags for a runtime library
index 760c128..05203dd 100644 (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,42 +11816,23 @@ 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.
-@end table
-
-@table @code
-@item #pragma GCC option (push)
-@itemx #pragma GCC option (pop)
-@cindex pragma GCC option
-
-These pragmas maintain a stack of the current options.  It is
-intended for include files where you temporarily want to switch to
-using a different @samp{#pragma GCC option} and then to pop back to
-the previous options.
+386 and x86_64 backends.
 @end table
 
 @table @code
-@item #pragma GCC option (reset)
-@cindex pragma, target option
-@cindex pragma GCC option
-
-This pragma clears the current @code{#pragma GCC options} to use the
-default switches as specified on the command line.
-@end table
-@table @code
 @item #pragma GCC optimize (@var{"string"}...)
 @cindex pragma GCC optimize
 
@@ -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
-
-These pragmas maintain a stack of the current optimization options.
-It is intended for include files where you temporarily want to switch
-to using a different @code{#pragma GCC optimize} and then to pop back
-to the previous optimizations.
+@item #pragma GCC push_options
+@itemx #pragma GCC pop_options
+@cindex pragma GCC push_options
+@cindex pragma GCC pop_options
+
+These pragmas maintain a stack of the current target and optimization
+options.  It is intended for include files where you temporarily want
+to switch to using a different @samp{#pragma GCC target} or
+@samp{#pragma GCC optimize} and then to pop back to the previous
+options.
+
+The @samp{#pragma GCC push_options} and @samp{#pragma GCC pop_options}
+pragmas are not implemented in GCC versions earlier than 4.4.
 @end table
 
 @table @code
-@item #pragma GCC optimize reset
-@cindex pragma GCC optimize
+@item #pragma GCC reset_options
+@cindex pragma GCC reset_options
 
-This pragma clears the current @code{#pragma GCC optimize} to use the
-default switches as specified on the command line.
+This pragma clears the current @code{#pragma GCC target} and
+@code{#pragma GCC optimize} to use the default switches as specified
+on the command line.
+
+The @samp{#pragma GCC reset_options} pragma is not implemented in GCC
+versions earlier than 4.4.
 @end table
 
 @node Unnamed Fields
index 4cab70b..7f8de5b 100644 (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, \
 }
index 30e5bfa..4d44102 100644 (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,8 +574,43 @@ 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
index 6a23a31..a10ce48 100644 (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 */
index a14b8c2..574379b 100644 (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") \
index 62ad89a..7a51a0e 100644 (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.
index 18b0eb5..817cae4 100644 (file)
 
 /* Function specific option attribute support.  */
 #ifndef TARGET_OPTION_VALID_ATTRIBUTE_P
-#define TARGET_OPTION_VALID_ATTRIBUTE_P NULL
+#define TARGET_OPTION_VALID_ATTRIBUTE_P \
+  default_target_option_valid_attribute_p
 #endif
 
 #ifndef TARGET_OPTION_SAVE
 #endif
 
 #ifndef TARGET_OPTION_PRAGMA_PARSE
-#define TARGET_OPTION_PRAGMA_PARSE NULL
+#define TARGET_OPTION_PRAGMA_PARSE default_target_option_pragma_parse
 #endif
 
 #ifndef TARGET_OPTION_CAN_INLINE_P
 #define TARGET_OPTION_CAN_INLINE_P default_target_option_can_inline_p
 #endif
 
-#ifndef TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION false
-#endif
-
-#ifndef TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION
-#define TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION false
-#endif
-
 #define TARGET_OPTION_HOOKS                    \
   {                                            \
     TARGET_OPTION_VALID_ATTRIBUTE_P,           \
     TARGET_OPTION_PRINT,                       \
     TARGET_OPTION_PRAGMA_PARSE,                        \
     TARGET_OPTION_CAN_INLINE_P,                        \
-    TARGET_OPTION_COLD_ATTRIBUTE_SETS_OPTIMIZATION, \
-    TARGET_OPTION_HOT_ATTRIBUTE_SETS_OPTIMIZATION, \
   }
 
 /* The whole shebang.  */
index 610d765..a44eb92 100644 (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
index 4e9b9ad..8edfcfc 100644 (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;
 }
 
index efb487c..f8d75e8 100644 (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);
index 41185be..4fe45de 100644 (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.
index 34ee54a..b7b892d 100644 (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)
diff --git a/gcc/testsuite/gcc.target/i386/cold-1.c b/gcc/testsuite/gcc.target/i386/cold-1.c
deleted file mode 100644 (file)
index bcdc471..0000000
+++ /dev/null
@@ -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");
-}
index 1ee43a0..1416c75 100644 (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)
index 9446cdf..9526e7d 100644 (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)
index ec32e0c..065ca3c 100644 (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)
index eb6f48b..e3628e3 100644 (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;
index 80ec23d..62748be 100644 (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;
index 71251c3..98f545a 100644 (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" } */
index d4204bb..378dca5 100644 (file)
 /* { 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")));
index 0c91597..6b526c2 100644 (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")));
index a65ae25..56b5490 100644 (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); }
index 115f608..2478c67 100644 (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
index e6d1901..1a7fc1b 100644 (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
diff --git a/gcc/testsuite/gcc.target/i386/hot-1.c b/gcc/testsuite/gcc.target/i386/hot-1.c
deleted file mode 100644 (file)
index 608f52f..0000000
+++ /dev/null
@@ -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];
-}
index 8d6ba6f..d2791e0 100644 (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
index a9b1033..f530e54 100644 (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
 
 /* 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)
index 27b6014..4488568 100644 (file)
 #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>
index 0f59d16..e38ef3a 100644 (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);
index 775d281..40cd456 100644 (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