[PATCH, function-specific-branch, committed] Rename target specific -> function specific

Michael Meissner michael.meissner@amd.com
Fri Jun 6 03:06:00 GMT 2008


We did a code review within AMD, and it was decided to change target specific
back to function specific as it is closer to the intent of the changes.  Also,
the file target-specific.c is deleted, and parts moved to c-common.c and
targhooks.c so that like functions are grouped together.

-- 
Michael Meissner, AMD
90 Central Street, MS 83-29, Boxborough, MA, 01719, USA
michael.meissner@amd.com
-------------- next part --------------
2008-06-05  Michael Meissner  <michael.meissner@amd.com>

	* targhooks.c (default_can_inline_p): Move default hook here from
	target-specific.c and rename it.

	* targhooks.h (default_can_inline_p): Rename from
	default_target_specific_can_inline_p.

	* tree.h (DECL_FUNCTION_SPECIFIC): Rename from
	DECL_TARGET_SPECIFIC.
	(struct tree_function_decl): Rename target_specific field to
	function_specific.
	(handle_option_attribute): Delete declaration.

	* target.h (struct target_specific_hooks): Delete.
	(struct gcc_target): Replace target_specific hook with
	valid_option_attribute_p and can_inline_p hooks.  Change calling
	sequence on valid_option_attribute_p to more closely match the
	attribute calling sequence.

	* target-specific.c: Delete file, move functions to targhooks.c
	and c-common.c.

	* ipa-inline.c (cgraph_decide_inlining_of_small_function): Change
	tree_target_specific_can_inline_p to tree_can_inline_p.
	(cgraph_decide_inlining): Ditto.
	(cgraph_decide_inlining_incrementally): Ditto.

	* c-decl.c (merge_decls): Rename DECL_TARGET_SPECIFIC to
	DECL_FUNCTION_SPECIFIC. 

	* coretypes.h (struct function_specific_data): Rename from
	target_specific_data.

	* print-tree.c (print_node): Rename DECL_TARGET_SPECIFIC to
	DECL_FUNCTION_SPECIFIC.

	* target-def.h (TARGET_VALID_OPTION_ATTRIBUTE_P): Rename from
	TARGET_TARGET_SPECIFIC_VALIDATE.
	(TARGET_CAN_INLINE_P): Rename from
	TARGET_TARGET_SPECIFIC_CAN_INLINE_P.
	(TARGET_TARGET_SPECIFIC): Delete.
	(TARGET_INITIALIZER): Delete TARGET_TARGET_SPECIFIC, use
	TARGET_VALID_OPTION_ATTRIBUTE_P and TARGET_CAN_INLINE_P.

	* tree-inline.c (tree_can_inline_p): Rename from
	tree_target_specific_can_inline_p.

	* tree-inline.h (tree_can_inline_p): Rename from
	tree_target_specific_can_inline_p.

	* c-common.c (c_common_attribute_table): Remove FIXME comment on
	"option" attribute, and move it to the end.
	(handle_option_attribute): Move this here from target-specific.c
	and change the calling sequence of the backend hook.

	* Makefile.in (OBJS-common): Delete target-specific.o.
	(target-specific.o): Delete.

	* config/i386/i386.h (TARGET_VALID_OPTION_ATTRIBUTE_P): Rename
	from TARGET_TARGET_SPECIFIC_VALIDATE.
	(TARGET_CAN_INLINE_P): Rename from
	TARGET_TARGET_SPECIFIC_CAN_INLINE_P.
	(struct function_specific_data): Rename from
	target_specific_data.

	* config/i386/i386.c (ix86_function_specific_save): Rename from
	ix86_target_specific_save.  Change callers.
	(ix86_function_specific_restore): Rename from
	ix86_target_specific_save.  Change callers.
	(ix86_can_inline_p): Rename from
	ix86_target_specific_can_inline_p.
	(ix86_valid_option_attribute_p): New function that is called from
	handle_option_attribute, and has the new calling sequence.
	(ix86_valid_option_attribute_inner_p): Rename from
	ix86_target_specific_validate.  Change DECL_TARGET_SPECIFIC to
	DECL_FUNCTION_SPECIFIC.
	(ix86_option_count_args): Move from target-specific.c and rename
	from target_specific_count_args.
	(ix86_option_build_args): Move from target-specific.c and rename
	from target_specific_build_args.
	(ix86_can_inline_p): Rename from ix86_target_specific_can_inline_p
	and change other target specific -> function specific references.

Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 136417)
+++ gcc/targhooks.c	(working copy)
@@ -697,4 +697,33 @@ default_builtin_vector_alignment_reachab
   return true;
 }
 
+/* Determine whether a function FN can be inlined.  Be conservative, and assume
+   any function with different target specific options cannot be inlined.  */
+
+bool
+default_can_inline_p (tree caller, tree callee)
+{
+  bool ret = false;
+  struct function_specific_data *callee_opts = DECL_FUNCTION_SPECIFIC (callee);
+  struct function_specific_data *caller_opts = DECL_FUNCTION_SPECIFIC (caller);
+
+  /* If callee has no option attributes, then it is ok to inline */
+  if (!callee_opts)
+    ret = true;
+
+  /* If caller has no option attributes, but callee does then it is not ok to
+     inline */
+  else if (!caller_opts)
+    ret = false;
+
+  /* Both caller and callee have attributes.  Because we don't know anything
+     about target specific options, assume if we get here the port hashes the
+     target specific information to a common pointer, and if the pointers are
+     the same, then they are the same target.  */
+  else
+    ret = (callee_opts == caller_opts);
+
+  return ret;
+}
+
 #include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 136417)
+++ gcc/targhooks.h	(working copy)
@@ -96,4 +96,4 @@ extern int default_reloc_rw_mask (void);
 extern tree default_mangle_decl_assembler_name (tree, tree);
 extern tree default_emutls_var_fields (tree, tree *);
 extern tree default_emutls_var_init (tree, tree, tree);
-extern bool default_target_specific_can_inline_p (tree, tree);
+extern bool default_can_inline_p (tree, tree);
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 136417)
+++ gcc/tree.h	(working copy)
@@ -3366,10 +3366,10 @@ struct tree_decl_non_common GTY(())
 #define DECL_ARGUMENTS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.arguments)
 #define DECL_ARGUMENT_FLD(NODE) (DECL_NON_COMMON_CHECK (NODE)->decl_non_common.arguments)
 
-/* In FUNCTION_DECL, the target specific options to use when compiling this
+/* In FUNCTION_DECL, the function specific options to use when compiling this
    function.  */
-#define DECL_TARGET_SPECIFIC(NODE) \
-   (FUNCTION_DECL_CHECK (NODE)->function_decl.target_specific)
+#define DECL_FUNCTION_SPECIFIC(NODE) \
+   (FUNCTION_DECL_CHECK (NODE)->function_decl.function_specific)
 
 /* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the
    arguments/result/saved_tree fields by front ends.   It was either inherit
@@ -3382,8 +3382,8 @@ struct tree_function_decl GTY(())
 
   struct function *f;
 
-  /* Target specific options that are used by this function.  */
-  struct target_specific_data * GTY((maybe_undef)) target_specific;
+  /* Function specific options that are used by this function.  */
+  struct function_specific_data * GTY((maybe_undef)) function_specific;
 
   /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
      DECL_FUNCTION_CODE.  Otherwise unused.
@@ -5108,9 +5108,6 @@ extern void gimplify_function_tree (tree
 extern const char *get_name (const_tree);
 extern tree unshare_expr (tree);
 extern void sort_case_labels (tree);
-
-/* In target-specific.c */
-extern tree handle_option_attribute (tree *, tree, tree, int, bool *);
 
 /* Interface of the DWARF2 unwind info support.  */
 
Index: gcc/target.h
===================================================================
--- gcc/target.h	(revision 136417)
+++ gcc/target.h	(working copy)
@@ -950,13 +950,13 @@ struct gcc_target
     bool debug_form_tls_address;
   } emutls;  
 
-  /* Functions and data for target specific option support.  */
-  struct target_specific_hooks {
-    /* Function to validate a target specific option stream */
-    bool (*validate) (int, const char **, tree);
-    /* Function to decide whether a function can be inlined.  */
-    bool (*can_inline_p) (tree, tree);
-  } target_specific;
+  /* Function to validate the attribute((option(...))) strings or NULL.  If the
+     option is validated, it is assumed that DECL_FUNCTION_SPECIFIC will be
+     filled in in the function decl node.  */
+  bool (*valid_option_attribute_p) (tree, tree, tree, int);
+
+  /* Function to determine if one function can inline another function.  */
+  bool (*can_inline_p) (tree, tree);
 
   /* For targets that need to mark extra registers as live on entry to
      the function, they should define this target hook and set their
Index: gcc/target-specific.c
===================================================================
--- gcc/target-specific.c	(revision 136417)
+++ gcc/target-specific.c	(working copy)
@@ -1,170 +0,0 @@
-/* Tree Options.
-   Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
-   Contributed by Karthik Kumar
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "tree.h"
-#include "function.h"
-#include "flags.h"
-#include "toplev.h"
-#include "ggc.h"
-#include "output.h"
-#include "tm_p.h"
-#include "target.h"
-#include "targhooks.h"
-#include "tree-pass.h"
-#include "diagnostic.h"
-#include "opts.h"
-
-static int target_specific_count_args (tree args);
-static void target_specific_build_args (tree args,
-					int *p_argc,
-					int max_argc,
-					const char *argv[]);
-
-/* Count how many target specific options there are in ARGS.
-
-   The ARGS argument is either a TREE_LIST that points to STRING_CST nodes
-   (when we are called from handle_option_attribute to valid the attributes),
-   or a TREE_LIST that points to a TREE_LIST which in turn points to STRING_CST
-   nodes (when we use the result of lookup_attribute ("option")).  */
-
-static int
-target_specific_count_args (tree args)
-{
-  int ret = 0;
-
-  if (TREE_CODE (args) == TREE_LIST)
-    {
-      for (; args; args = TREE_CHAIN (args))
-	if (TREE_VALUE (args))
-	  ret += target_specific_count_args (TREE_VALUE (args));
-    }
-
-  else if (TREE_CODE (args) == STRING_CST)
-    ret++;
-
-  else
-    gcc_unreachable ();
-
-  return ret;
-}
-
-/* Build the argument vector from the attribute list of ARGS, updating the
-   current argument count in the int pointed to by P_ARGC, with a maximum count
-   of MAX_ARGC, and the vector in ARGV.  */
-
-static void
-target_specific_build_args (tree args, int *p_argc, int max_argc,
-			    const char *argv[])
-{
-  if (TREE_CODE (args) == TREE_LIST)
-    {
-      for (; args; args = TREE_CHAIN (args))
-	if (TREE_VALUE (args))
-	  target_specific_build_args (TREE_VALUE (args), p_argc, max_argc,
-				      argv);
-    }
-
-  else if (TREE_CODE (args) == STRING_CST)
-    {
-      gcc_assert (*p_argc < max_argc);
-      argv[*p_argc] = TREE_STRING_POINTER (args);
-      (*p_argc)++;
-    }
-
-  else
-    gcc_unreachable ();
-}
-
-
-/* For handling "option" attribute. arguments as in
-   struct attribute_spec.handler.  */
-
-tree
-handle_option_attribute (tree *node,
-			 tree ARG_UNUSED (name),
-			 tree args,
-			 int ARG_UNUSED (flags),
-			 bool *no_add_attrs)
-{
-  if (TREE_CODE (*node) != FUNCTION_DECL)
-    {
-      warning (OPT_Wattributes, "option attribute ignored");
-      *no_add_attrs = true;
-    }
-  else if (! targetm.target_specific.validate)
-    {
-      error ("option attribute is not supported on this machine");
-      *no_add_attrs = true;
-    }
-  else
-    {
-      int max_argc = target_specific_count_args (args);
-
-      if (max_argc > 0)
-	{
-	  int argc = 0;
-	  const char **argv = alloca ((max_argc + 1) * sizeof (char *));
-
-	  target_specific_build_args (args, &argc, max_argc, argv);
-	  argv[max_argc] = NULL;
-	  if (targetm.target_specific.validate (argc, argv, *node))
-	    *no_add_attrs = true;
-	}
-    }
-
-  return NULL_TREE;
-}
-
-
-/* Determine whether a function FN can be inlined.  Be conservative, and assume
-   any function with different target specific options cannot be inlined.
-
-   Backends should really provide their own hook, as this function will be slow
-   since it has to do a lot of string comparison and copies to determine if two
-   functions have the same target specific options.
-*/
-
-bool
-default_target_specific_can_inline_p (tree caller, tree callee)
-{
-  bool ret = false;
-  struct target_specific_data *callee_opts = DECL_TARGET_SPECIFIC (callee);
-  struct target_specific_data *caller_opts = DECL_TARGET_SPECIFIC (caller);
-
-  /* If callee has no option attributes, then it is ok to inline */
-  if (!callee_opts)
-    ret = true;
-
-  /* If caller has no option attributes, but callee does then it is not ok to
-     inline */
-  else if (!caller_opts)
-    ret = false;
-
-  /* Both caller and callee have attributes, see if they are the same */
-  else
-    ret = (callee_opts == caller_opts);
-
-  return ret;
-}
Index: gcc/ipa-inline.c
===================================================================
--- gcc/ipa-inline.c	(revision 136417)
+++ gcc/ipa-inline.c	(working copy)
@@ -954,8 +954,7 @@ cgraph_decide_inlining_of_small_function
 	    }
 	  continue;
 	}
-      if (!tree_target_specific_can_inline_p (edge->caller->decl,
-					      edge->callee->decl))
+      if (!tree_can_inline_p (edge->caller->decl, edge->callee->decl))
 	{
 	  CALL_STMT_CANNOT_INLINE_P (edge->call_stmt) = true;
 	  edge->inline_failed = N_("target specific option mismatch");
@@ -1107,8 +1106,7 @@ cgraph_decide_inlining (void)
 	  if (cgraph_recursive_inlining_p (e->caller, e->callee,
 				  	   &e->inline_failed))
 	    continue;
-	  if (!tree_target_specific_can_inline_p (e->caller->decl,
-						  e->callee->decl))
+	  if (!tree_can_inline_p (e->caller->decl, e->callee->decl))
 	    {
 	      CALL_STMT_CANNOT_INLINE_P (e->call_stmt) = true;
 	      continue;
@@ -1337,7 +1335,7 @@ cgraph_decide_inlining_incrementally (st
 	    }
 	  continue;
 	}
-      if (!tree_target_specific_can_inline_p (node->decl, e->callee->decl))
+      if (!tree_can_inline_p (node->decl, e->callee->decl))
 	{
 	  CALL_STMT_CANNOT_INLINE_P (e->call_stmt) = true;
 	  if (dump_file)
@@ -1444,7 +1442,7 @@ cgraph_decide_inlining_incrementally (st
 	      }
 	    continue;
 	  }
-	if (!tree_target_specific_can_inline_p (node->decl, e->callee->decl))
+	if (!tree_can_inline_p (node->decl, e->callee->decl))
 	  {
 	    CALL_STMT_CANNOT_INLINE_P (e->call_stmt) = true;
 	    if (dump_file)
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 136417)
+++ gcc/c-decl.c	(working copy)
@@ -1836,8 +1836,9 @@ merge_decls (tree newdecl, tree olddecl,
 	}
 
       /* Preserve target specific options */
-      if (DECL_TARGET_SPECIFIC (olddecl) && !DECL_TARGET_SPECIFIC (newdecl))
-	DECL_TARGET_SPECIFIC (newdecl) = DECL_TARGET_SPECIFIC (olddecl);
+      if (DECL_FUNCTION_SPECIFIC (olddecl)
+	  && !DECL_FUNCTION_SPECIFIC (newdecl))
+	DECL_FUNCTION_SPECIFIC (newdecl) = DECL_FUNCTION_SPECIFIC (olddecl);
 
       /* Also preserve various other info from the definition.  */
       if (!new_is_definition)
Index: gcc/coretypes.h
===================================================================
--- gcc/coretypes.h	(revision 136417)
+++ gcc/coretypes.h	(working copy)
@@ -51,7 +51,7 @@ typedef const union tree_node *const_tre
 union section;
 typedef union section section;
 struct cl_option_save;
-struct target_specific_data;
+struct function_specific_data;
 
 /* The major intermediate representations of GCC.  */
 enum ir_type {
Index: gcc/print-tree.c
===================================================================
--- gcc/print-tree.c	(revision 136417)
+++ gcc/print-tree.c	(working copy)
@@ -369,8 +369,8 @@ print_node (FILE *file, const char *pref
       if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
 	fputs (" suppress-debug", file);
 
-      if (TREE_CODE (node) == FUNCTION_DECL && DECL_TARGET_SPECIFIC (node))
-	fputs (" target-specific", file);
+      if (TREE_CODE (node) == FUNCTION_DECL && DECL_FUNCTION_SPECIFIC (node))
+	fputs (" function-specific", file);
       if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
 	fputs (DECL_DECLARED_INLINE_P (node) ? " inline" : " autoinline", file);
       if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h	(revision 136417)
+++ gcc/target-def.h	(working copy)
@@ -751,22 +751,15 @@
     TARGET_EMUTLS_DEBUG_FORM_TLS_ADDRESS	\
   }
 
-/* Target specific option attribute support.  */
-#ifndef TARGET_TARGET_SPECIFIC_VALIDATE
-#define TARGET_TARGET_SPECIFIC_VALIDATE NULL
+/* Function specific option attribute support.  */
+#ifndef TARGET_VALID_OPTION_ATTRIBUTE_P
+#define TARGET_VALID_OPTION_ATTRIBUTE_P NULL
 #endif
 
-#ifndef TARGET_TARGET_SPECIFIC_CAN_INLINE_P
-#define TARGET_TARGET_SPECIFIC_CAN_INLINE_P \
-  default_target_specific_can_inline_p
+#ifndef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P default_can_inline_p
 #endif
 
-#define TARGET_TARGET_SPECIFIC			\
-  {						\
-    TARGET_TARGET_SPECIFIC_VALIDATE,		\
-    TARGET_TARGET_SPECIFIC_CAN_INLINE_P		\
-  }
-
 /* The whole shebang.  */
 #define TARGET_INITIALIZER			\
 {						\
@@ -859,7 +852,8 @@
   TARGET_C,					\
   TARGET_CXX,					\
   TARGET_EMUTLS,				\
-  TARGET_TARGET_SPECIFIC,			\
+  TARGET_VALID_OPTION_ATTRIBUTE_P,		\
+  TARGET_CAN_INLINE_P,				\
   TARGET_EXTRA_LIVE_ON_ENTRY,			\
   TARGET_UNWIND_TABLES_DEFAULT,			\
   TARGET_HAVE_NAMED_SECTIONS,			\
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c	(revision 136417)
+++ gcc/tree-inline.c	(working copy)
@@ -3681,7 +3681,7 @@ build_duplicate_type (tree type)
 /* Return whether it is safe to inline a function because it used different
    target specific options.  */
 bool
-tree_target_specific_can_inline_p (tree caller, tree callee)
+tree_can_inline_p (tree caller, tree callee)
 {
-  return targetm.target_specific.can_inline_p (caller, callee);
+  return targetm.can_inline_p (caller, callee);
 }
Index: gcc/tree-inline.h
===================================================================
--- gcc/tree-inline.h	(revision 136417)
+++ gcc/tree-inline.h	(working copy)
@@ -150,7 +150,7 @@ int estimate_move_cost (tree type);
 int estimate_num_insns (tree expr, eni_weights *);
 bool tree_versionable_function_p (tree);
 void tree_function_versioning (tree, tree, varray_type, bool);
-bool tree_target_specific_can_inline_p (tree, tree);
+bool tree_can_inline_p (tree, tree);
 
 extern tree remap_decl (tree decl, copy_body_data *id);
 extern tree remap_type (tree type, copy_body_data *id);
Index: gcc/c-common.c
===================================================================
--- gcc/c-common.c	(revision 136417)
+++ gcc/c-common.c	(working copy)
@@ -574,6 +574,7 @@ static tree handle_warn_unused_result_at
 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 void check_function_nonnull (tree, int, tree *);
 static void check_nonnull_arg (void *, tree, unsigned HOST_WIDE_INT);
@@ -616,9 +617,6 @@ const struct attribute_spec c_common_att
 			      handle_unused_attribute },
   { "externally_visible",     0, 0, true,  false, false,
 			      handle_externally_visible_attribute },
-  /* For handling options specific to a specific function.  */
-  { "option",                 1, -1, true, false, false, /* XXX FIXME */
-			      handle_option_attribute },
   /* The same comments as for noreturn attributes apply to const ones.  */
   { "const",                  0, 0, true,  false, false,
 			      handle_const_attribute },
@@ -687,6 +685,8 @@ const struct attribute_spec c_common_att
 			      handle_error_attribute },
   { "error",		      1, 1, true,  false, false,
 			      handle_error_attribute },
+  { "option",                 1, -1, true, false, false,
+			      handle_option_attribute },
   { NULL,                     0, 0, false, false, false, NULL }
 };
 
@@ -6533,6 +6533,32 @@ handle_type_generic_attribute (tree *nod
 
   return NULL_TREE;
 }
+
+/* For handling "option" attribute. arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_option_attribute (tree *node, tree name, tree args, int flags,
+			 bool *no_add_attrs)
+{
+  /* Ensure we have a function type.  */
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+  else if (! targetm.valid_option_attribute_p)
+    {
+      warning (OPT_Wattributes,
+	       "%qE attribute is not supported on this machine",
+	       name);
+      *no_add_attrs = true;
+    }
+  else if (! targetm.valid_option_attribute_p (*node, name, args, flags))
+    *no_add_attrs = true;
+
+  return NULL_TREE;
+}
 
 /* Check for valid arguments being passed to a function.
    ATTRS is a list of attributes.  There are NARGS arguments in the array
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 136417)
+++ gcc/Makefile.in	(working copy)
@@ -1139,7 +1139,6 @@ OBJS-common = \
 	stor-layout.o \
 	stringpool.o \
 	targhooks.o \
-	target-specific.o \
 	timevar.o \
 	toplev.o \
 	tracer.o \
@@ -2647,10 +2646,6 @@ profile.o : profile.c $(CONFIG_H) $(SYST
    $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \
    toplev.h $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
    $(CFGLOOP_H) $(TIMEVAR_H) tree-pass.h
-target-specific.o : target-specific.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-   $(TM_H) $(RTL_H) $(TREE_H) $(FUNCTION_H) flags.h toplev.h $(TREE_PASS_H) \
-   $(GGC_H) output.h $(TM_P_H) $(TARGET_H) $(DIAGNOSTIC_H) opts.h \
-   gt-targhooks.h
 tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \
    $(FUNCTION_H) toplev.h $(COVERAGE_H) $(TREE_H) value-prof.h $(TREE_DUMP_H) \
Index: gcc/config/i386/i386.h
===================================================================
--- gcc/config/i386/i386.h	(revision 136417)
+++ gcc/config/i386/i386.h	(working copy)
@@ -462,10 +462,10 @@ extern tree x86_mfence;
 #define OVERRIDE_OPTIONS override_options (true)
 
 /* Validate the attribute(option(...)) list.  */
-#define TARGET_TARGET_SPECIFIC_VALIDATE ix86_target_specific_validate
+#define TARGET_VALID_OPTION_ATTRIBUTE_P ix86_valid_option_attribute_p
 
 /* Determine whether one function can inline another */
-#define TARGET_TARGET_SPECIFIC_CAN_INLINE_P ix86_target_specific_can_inline_p
+#define TARGET_CAN_INLINE_P ix86_can_inline_p
 
 /* Establish appropriate back-end context for processing the function
    FNDECL.  The argument might be NULL to indicate processing at top
@@ -2475,7 +2475,7 @@ struct machine_function GTY(())
   int tls_descriptor_call_expanded_p;
 };
 
-/* target options that we save away if the user used target specific
+/* target options that we save away if the user used function specific
    options.  */
 struct machine_option_attr GTY(())
 {
@@ -2487,9 +2487,9 @@ struct machine_option_attr GTY(())
   unsigned char arch_specified;		/* whether -march was specified */
 };
 
-/* Combination of the target specific options generated by the .opt files
+/* Combination of the function specific options generated by the .opt files
    and by the x86 specific data.  */
-struct target_specific_data GTY(())
+struct function_specific_data GTY(())
 {
   struct cl_option_save options;		/* option data */
   struct machine_option_attr machine;		/* machine data */
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 136417)
+++ gcc/config/i386/i386.c	(working copy)
@@ -1765,13 +1765,17 @@ static bool ix86_expand_vector_init_one_
 						 rtx, rtx, int);
 static char *ix86_target_string (void);
 static void ix86_debug_options (void) ATTRIBUTE_UNUSED;
-static void ix86_target_specific_save (struct target_specific_data *);
-static void ix86_target_specific_restore (struct target_specific_data *);
-static bool ix86_target_specific_validate (int, const char **, tree);
-static bool ix86_target_specific_can_inline_p (tree, tree);
+static void ix86_function_specific_save (struct function_specific_data *);
+static void ix86_function_specific_restore (struct function_specific_data *);
+static bool ix86_valid_option_attribute_p (tree, tree, tree, int);
+static bool ix86_valid_option_attribute_inner_p (int, const char **, tree);
+static int ix86_option_count_args (tree);
+static void ix86_option_build_args (tree, int *, int, const char **);
+
+static bool ix86_can_inline_p (tree, tree);
 static void ix86_set_current_function (tree);
 
-static GTY(()) struct target_specific_data *ix86_initial_options;
+static GTY(()) struct function_specific_data *ix86_initial_options;
 
 
 
@@ -2979,20 +2983,21 @@ override_options (bool main_args_p)
     target_flags |= MASK_CLD & ~target_flags_explicit;
 #endif
 
-  /* Save the initial options in case the user does target specific options */
+  /* Save the initial options in case the user does function specific options */
   if (main_args_p)
     {
-      ix86_initial_options = ggc_alloc (sizeof (struct target_specific_data));
-      ix86_target_specific_save (ix86_initial_options);
+      ix86_initial_options
+	= ggc_alloc (sizeof (struct function_specific_data));
+      ix86_function_specific_save (ix86_initial_options);
     }
 }
 
 /* Save the current options */
 
 static void
-ix86_target_specific_save (struct target_specific_data *ptr)
+ix86_function_specific_save (struct function_specific_data *ptr)
 {
-  memset (ptr, '\0', sizeof (struct target_specific_data));
+  memset (ptr, '\0', sizeof (struct function_specific_data));
   cl_options_save (&ptr->options);
   ptr->machine.arch = ix86_arch;
   ptr->machine.tune = ix86_tune;
@@ -3005,7 +3010,7 @@ ix86_target_specific_save (struct target
 /* Restore the current options */
 
 static void
-ix86_target_specific_restore (struct target_specific_data *ptr)
+ix86_function_specific_restore (struct function_specific_data *ptr)
 {
   unsigned int ix86_arch_mask, ix86_tune_mask;
   int i;
@@ -3028,10 +3033,10 @@ ix86_target_specific_restore (struct tar
 }
 
 
-/* Hook to validate the target specific options */
+/* Hook to validate the function specific options */
 
 static bool
-ix86_target_specific_validate (int argc, const char **argv, tree fndecl)
+ix86_valid_option_attribute_inner_p (int argc, const char **argv, tree fndecl)
 {
   int i;
   unsigned j;
@@ -3062,11 +3067,11 @@ ix86_target_specific_validate (int argc,
   };
 
   /* If we've already figured out the options, quit now */
-  if (DECL_TARGET_SPECIFIC (fndecl))
+  if (DECL_FUNCTION_SPECIFIC (fndecl))
     return ret;
 
   /* Make sure we start with clean options */
-  ix86_target_specific_restore (ix86_initial_options);
+  ix86_function_specific_restore (ix86_initial_options);
 
   for (i = 0; i < argc; i++)
     {
@@ -3134,7 +3139,7 @@ ix86_target_specific_validate (int argc,
       || ix86_tune_string != orig_tune_string
       || ix86_fpmath_string != orig_fpmath_string)
     {
-      struct target_specific_data *p;
+      struct function_specific_data *p;
 
       /* If we are using the default tune= or arch=, undo the string assigned,
 	 and use the default.  */
@@ -3152,12 +3157,12 @@ ix86_target_specific_validate (int argc,
       override_options (false);
 
       /* Save the current options */
-      p = ggc_alloc (sizeof (struct target_specific_data));
-      DECL_TARGET_SPECIFIC (fndecl) = p;
-      ix86_target_specific_save (p);
+      p = ggc_alloc (sizeof (struct function_specific_data));
+      DECL_FUNCTION_SPECIFIC (fndecl) = p;
+      ix86_function_specific_save (p);
 
       /* Restore options */
-      ix86_target_specific_restore (ix86_initial_options);
+      ix86_function_specific_restore (ix86_initial_options);
       ix86_arch_string = orig_arch_string;
       ix86_tune_string = orig_tune_string;
       ix86_fpmath_string = orig_fpmath_string;
@@ -3166,15 +3171,90 @@ ix86_target_specific_validate (int argc,
   return ret;
 }
 
+/* Count how many function specific options there are in ARGS.
+
+   The ARGS argument is a TREE_LIST that points to STRING_CST nodes.  */
+
+static int
+ix86_option_count_args (tree args)
+{
+  int ret = 0;
+
+  if (TREE_CODE (args) == TREE_LIST)
+    {
+      for (; args; args = TREE_CHAIN (args))
+	if (TREE_VALUE (args))
+	  ret += ix86_option_count_args (TREE_VALUE (args));
+    }
+
+  else if (TREE_CODE (args) == STRING_CST)
+    ret++;
+
+  else
+    gcc_unreachable ();
+
+  return ret;
+}
+
+/* Build the argument vector from the attribute list of ARGS, updating the
+   current argument count in the int pointed to by P_ARGC, with a maximum count
+   of MAX_ARGC, and the vector in ARGV.  */
+
+static void
+ix86_option_build_args (tree args, int *p_argc, int max_argc,
+			const char *argv[])
+{
+  if (TREE_CODE (args) == TREE_LIST)
+    {
+      for (; args; args = TREE_CHAIN (args))
+	if (TREE_VALUE (args))
+	  ix86_option_build_args (TREE_VALUE (args), p_argc, max_argc, argv);
+    }
+
+  else if (TREE_CODE (args) == STRING_CST)
+    {
+      gcc_assert (*p_argc < max_argc);
+      argv[*p_argc] = TREE_STRING_POINTER (args);
+      (*p_argc)++;
+    }
+
+  else
+    gcc_unreachable ();
+}
+
+/* Validate attribute((option("string"))).  */
+
+static bool
+ix86_valid_option_attribute_p (tree fndecl,
+			       tree ARG_UNUSED (name),
+			       tree args,
+			       int ARG_UNUSED (flags))
+{
+  int max_argc = ix86_option_count_args (args);
+  bool ret = true;
+
+  if (max_argc > 0)
+    {
+      int argc = 0;
+      const char **argv = alloca ((max_argc + 1) * sizeof (char *));
+
+      ix86_option_build_args (args, &argc, max_argc, argv);
+      argv[max_argc] = NULL;
+      ret = ix86_valid_option_attribute_inner_p (argc, argv, fndecl);
+    }
+
+  return ret;
+}
+
 
 /* Hook to determine if one function can safely inline another */
 
 static bool
-ix86_target_specific_can_inline_p (tree caller, tree callee)
+ix86_can_inline_p (tree caller, tree callee)
 {
   bool ret = false;
-  struct target_specific_data *caller_opts = DECL_TARGET_SPECIFIC (caller);
-  struct target_specific_data *callee_opts = DECL_TARGET_SPECIFIC (callee);
+  struct function_specific_data *caller_opts = DECL_FUNCTION_SPECIFIC (caller);
+  struct function_specific_data *callee_opts = DECL_FUNCTION_SPECIFIC (callee);
 
   /* If callee has no option attributes, then it is ok to inline */
   if (!callee_opts)
@@ -3227,11 +3307,11 @@ ix86_set_current_function (tree fndecl)
      slow things down too much or call target_reinit when it isn't safe.  */
   if (fndecl && fndecl != previous_fndecl)
     {
-      struct target_specific_data *old_p
-	= (previous_fndecl ? DECL_TARGET_SPECIFIC (previous_fndecl) : NULL);
+      struct function_specific_data *old_p
+	= (previous_fndecl ? DECL_FUNCTION_SPECIFIC (previous_fndecl) : NULL);
 
-      struct target_specific_data *cur_p
-	= (fndecl ? DECL_TARGET_SPECIFIC (fndecl) : NULL);
+      struct function_specific_data *cur_p
+	= (fndecl ? DECL_FUNCTION_SPECIFIC (fndecl) : NULL);
 
       previous_fndecl = fndecl;
       if (cur_p == old_p)
@@ -3239,13 +3319,13 @@ ix86_set_current_function (tree fndecl)
 
       else if (cur_p)
 	{
-	  ix86_target_specific_restore (cur_p);
+	  ix86_function_specific_restore (cur_p);
 	  target_reinit ();
 	}
 
       else if (old_p)
 	{
-	  ix86_target_specific_restore (ix86_initial_options);
+	  ix86_function_specific_restore (ix86_initial_options);
 	  target_reinit ();
 	}
     }


More information about the Gcc-patches mailing list