summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-09 18:25:19 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2014-01-09 18:25:19 +0000
commit6e5c480bff2a16e3e1632043eb201e4743061dbd (patch)
tree37c967d0243784a67a421818ebbbd738909d5f3c
parent9071f223bea07fd5b5cec3b5ad48cad8c25bf9db (diff)
downloadlinaro-gcc-6e5c480bff2a16e3e1632043eb201e4743061dbd.tar.gz
linaro-gcc-6e5c480bff2a16e3e1632043eb201e4743061dbd.tar.bz2
linaro-gcc-6e5c480bff2a16e3e1632043eb201e4743061dbd.zip
PR target/58115
* tree-core.h (struct target_globals): New forward declaration. (struct tree_target_option): Add globals field. * tree.h (TREE_TARGET_GLOBALS): Define. (prepare_target_option_nodes_for_pch): New prototype. * target-globals.h (struct target_globals): Define even if !SWITCHABLE_TARGET. * tree.c (prepare_target_option_node_for_pch, prepare_target_option_nodes_for_pch): New functions. * config/i386/i386.h (SWITCHABLE_TARGET): Define. * config/i386/i386.c: Include target-globals.h. (ix86_set_current_function): Instead of doing target_reinit unconditionally, use save_target_globals_default_opts and restore_target_globals. c-family/ * c-pch.c (c_common_write_pch): Call prepare_target_option_nodes_for_pch. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206478 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-pch.c2
-rw-r--r--gcc/config/i386/i386.c22
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/target-globals.h2
-rw-r--r--gcc/tree-core.h7
-rw-r--r--gcc/tree.c22
-rw-r--r--gcc/tree.h5
9 files changed, 80 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6f2f19d1a6f..dd9f87579d3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58115
+ * tree-core.h (struct target_globals): New forward declaration.
+ (struct tree_target_option): Add globals field.
+ * tree.h (TREE_TARGET_GLOBALS): Define.
+ (prepare_target_option_nodes_for_pch): New prototype.
+ * target-globals.h (struct target_globals): Define even if
+ !SWITCHABLE_TARGET.
+ * tree.c (prepare_target_option_node_for_pch,
+ prepare_target_option_nodes_for_pch): New functions.
+ * config/i386/i386.h (SWITCHABLE_TARGET): Define.
+ * config/i386/i386.c: Include target-globals.h.
+ (ix86_set_current_function): Instead of doing target_reinit
+ unconditionally, use save_target_globals_default_opts and
+ restore_target_globals.
+
2014-01-09 Richard Biener <rguenther@suse.de>
PR tree-optimization/59715
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index defc0030a64..d9b69b32c41 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2014-01-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58115
+ * c-pch.c (c_common_write_pch): Call
+ prepare_target_option_nodes_for_pch.
+
2014-01-02 Richard Sandiford <rdsandiford@googlemail.com>
Update copyright years
diff --git a/gcc/c-family/c-pch.c b/gcc/c-family/c-pch.c
index e51d5b9409e..93609b610ff 100644
--- a/gcc/c-family/c-pch.c
+++ b/gcc/c-family/c-pch.c
@@ -180,6 +180,8 @@ c_common_write_pch (void)
(*debug_hooks->handle_pch) (1);
+ prepare_target_option_nodes_for_pch ();
+
cpp_write_pch_deps (parse_in, pch_outfile);
gt_pch_save (pch_outfile);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 32b6418320f..52ad5c13ae3 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -80,6 +80,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "context.h"
#include "pass_manager.h"
+#include "target-globals.h"
static rtx legitimize_dllimport_symbol (rtx, bool);
static rtx legitimize_pe_coff_extern_decl (rtx, bool);
@@ -4868,16 +4869,25 @@ ix86_set_current_function (tree fndecl)
{
cl_target_option_restore (&global_options,
TREE_TARGET_OPTION (new_tree));
- target_reinit ();
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
}
else if (old_tree)
{
- struct cl_target_option *def
- = TREE_TARGET_OPTION (target_option_current_node);
-
- cl_target_option_restore (&global_options, def);
- target_reinit ();
+ new_tree = target_option_current_node;
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
}
}
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index ab7489a0c1b..27151f60ffa 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2510,6 +2510,9 @@ extern void debug_dispatch_window (int);
#define IX86_HLE_ACQUIRE (1 << 16)
#define IX86_HLE_RELEASE (1 << 17)
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
/*
Local variables:
version-control: t
diff --git a/gcc/target-globals.h b/gcc/target-globals.h
index b84d2902d9c..cc7eeff1d21 100644
--- a/gcc/target-globals.h
+++ b/gcc/target-globals.h
@@ -37,6 +37,7 @@ extern struct target_builtins *this_target_builtins;
extern struct target_gcse *this_target_gcse;
extern struct target_bb_reorder *this_target_bb_reorder;
extern struct target_lower_subreg *this_target_lower_subreg;
+#endif
struct GTY(()) target_globals {
struct target_flag_state *GTY((skip)) flag_state;
@@ -57,6 +58,7 @@ struct GTY(()) target_globals {
struct target_lower_subreg *GTY((skip)) lower_subreg;
};
+#if SWITCHABLE_TARGET
extern struct target_globals default_target_globals;
extern struct target_globals *save_target_globals (void);
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 361fd907209..e548a0dd37d 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -1557,11 +1557,18 @@ struct GTY(()) tree_optimization_option {
struct target_optabs *GTY ((skip)) base_optabs;
};
+/* Forward declaration, defined in target-globals.h. */
+
+struct GTY(()) target_globals;
+
/* Target options used by a function. */
struct GTY(()) tree_target_option {
struct tree_common common;
+ /* Target globals for the corresponding target option. */
+ struct target_globals *globals;
+
/* The optimization options used by the user. */
struct cl_target_option opts;
};
diff --git a/gcc/tree.c b/gcc/tree.c
index e4e289ad201..37a7ed4b3a0 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -11527,6 +11527,28 @@ build_target_option_node (struct gcc_options *opts)
return t;
}
+/* Reset TREE_TARGET_GLOBALS cache for TARGET_OPTION_NODE.
+ Called through htab_traverse. */
+
+static int
+prepare_target_option_node_for_pch (void **slot, void *)
+{
+ tree node = (tree) *slot;
+ if (TREE_CODE (node) == TARGET_OPTION_NODE)
+ TREE_TARGET_GLOBALS (node) = NULL;
+ return 1;
+}
+
+/* Clear TREE_TARGET_GLOBALS of all TARGET_OPTION_NODE trees,
+ so that they aren't saved during PCH writing. */
+
+void
+prepare_target_option_nodes_for_pch (void)
+{
+ htab_traverse (cl_option_hash_table, prepare_target_option_node_for_pch,
+ NULL);
+}
+
/* Determine the "ultimate origin" of a block. The block may be an inlined
instance of an inlined instance of a block which is local to an inline
function, so we have to trace all of the way back through the origin chain
diff --git a/gcc/tree.h b/gcc/tree.h
index fa79b6fc4a9..8006b5ad294 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2695,9 +2695,14 @@ extern tree build_optimization_node (struct gcc_options *opts);
#define TREE_TARGET_OPTION(NODE) \
(&TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts)
+#define TREE_TARGET_GLOBALS(NODE) \
+ (TARGET_OPTION_NODE_CHECK (NODE)->target_option.globals)
+
/* Return a tree node that encapsulates the target options in OPTS. */
extern tree build_target_option_node (struct gcc_options *opts);
+extern void prepare_target_option_nodes_for_pch (void);
+
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
inline tree