diff options
author | Michael Meissner <gnu@the-meissners.org> | 2008-08-30 23:50:40 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 2008-08-30 23:50:40 +0000 |
commit | 5779e7133d84c5873249bb643d9852f314022f0b (patch) | |
tree | b3ee120a2ecf25d00fba24415c8566f83135a110 /gcc/c-pragma.c | |
parent | 0257eee5bd4700647061f61b13a2f89b2a4b4f28 (diff) | |
download | gcc-5779e7133d84c5873249bb643d9852f314022f0b.zip gcc-5779e7133d84c5873249bb643d9852f314022f0b.tar.gz gcc-5779e7133d84c5873249bb643d9852f314022f0b.tar.bz2 |
Change attribute((option(...))) to attribute((target(...))); Do not allocate tree nodes on x86 for builtins until we generate code for the ISA; Delete hot/cold functions changing optimization; Make C++ support target specific functions; Add #pragma GCC {push_options,pop_options,reset_options} instead of #pragma GCC {target,optimize} {push,reset,pop}
From-SVN: r139812
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r-- | gcc/c-pragma.c | 323 |
1 files changed, 143 insertions, 180 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c index 63c0acb..2f2095e 100644 --- a/gcc/c-pragma.c +++ b/gcc/c-pragma.c @@ -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); |