After Jakub changed i?386/x86_64 to use SWITCHABLE_TARGET, he asked me to look at changing rs6000 too. Here's the rs6000 patch, which is basically identical to the i386.[hc] change Jakub made. This passed bootstrap and regtesting on powerpc64-linux with no regressions. Ok for mainline?
Peter * config/rs6000/rs6000.h (SWITCHABLE_TARGET): Define. * config/rs6000/rs6000.c: Include target-globals.h. (rs6000_set_current_function): Instead of doing target_reinit unconditionally, use save_target_globals_default_opts and restore_target_globals. Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 206526) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -892,6 +892,9 @@ enum data_align { align_abi, align_opt, && (ALIGN) < 32) \ || (VECTOR_MODE_P ((MODE)) && (((int)(ALIGN)) < VECTOR_ALIGN (MODE)))) +/* For switching between functions with different target attributes. */ +#define SWITCHABLE_TARGET 1 + /* Standard register usage. */ Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 206526) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -78,6 +78,7 @@ #include "tree-vectorizer.h" #include "dumpfile.h" #include "cgraph.h" +#include "target-globals.h" #if TARGET_XCOFF #include "xcoffout.h" /* get declarations of xcoff_*_section_name */ #endif @@ -31199,16 +31200,25 @@ rs6000_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 (); } } }