[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