diff options
author | Roger Sayle <roger@eyesopen.com> | 2003-07-24 21:04:12 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2003-07-24 21:04:12 +0000 |
commit | 868b8cda7b2c89629d7c642db03dae1e913fdd3c (patch) | |
tree | b05c49149bd1ed00301b62af2657b2f3d047bc0d /gcc/c-common.c | |
parent | 2a868ea448b0730a00817462c13182b1c1d52c22 (diff) | |
download | gcc-868b8cda7b2c89629d7c642db03dae1e913fdd3c.zip gcc-868b8cda7b2c89629d7c642db03dae1e913fdd3c.tar.gz gcc-868b8cda7b2c89629d7c642db03dae1e913fdd3c.tar.bz2 |
builtins.def (BUILT_IN_PRINTF, [...]): Changed from front-end builtins to normal builtins, using DEF_LIB_BUILTIN.
* builtins.def (BUILT_IN_PRINTF, BUILT_IN_FPRINTF): Changed from
front-end builtins to normal builtins, using DEF_LIB_BUILTIN.
(BUILT_IN_PRINTF_UNLOCKED, BUILT_IN_FPRINTF_UNLOCKED): Changed
from front-end to normal builtins, using DEF_EXT_LIB_BUILTIN.
(DEF_FRONT_END_LIB_BUILTIN): Delete.
(DEF_EXT_FRONT_END_LIB_BUILTIN): Delete.
(BUILT_IN_FWRITE_UNLOCKED): Wrap long line.
* builtins.c (build_string_literal): New function to construct
a char* pointer to a string literal.
(expand_builtin_fputs): Change 2nd argument from "int ignore" to
"rtx target" to be consistent with other expand_builtin_* functions.
Change 3rd argument from "int unlocked" to "bool unlocked".
(expand_builtin_printf): Rewrite of c_expand_builtin_printf from
c-common.c to avoid front-end dependencies. Optimize printf("")
as a no-op when the result isn't required. Handle embedded NULs
in format string.
(expand_builtin_fprintf): A rewrite of c_expand_builtin_fprintf
from c-common.c to avoid front-end dependencies. Likewise, optimize
fprintf(fp,"") as a no-op when the result isn't required, evaluating
fp for side-effects. Handle embedded NULs in format string.
(expand_builtin_sprintf): Fix typo.
(expand_builtin): Don't expand BUILT_IN_FPRINT{,_UNLOCKED} when not
optimizing. Adjust calls of expand_builtin_fputs to match the API
change. Expand BUILT_IN_PRINTF and BUILT_IN_PRINTF_UNLOCKED using
expand_builtin_printf. Likewise, expand BUILT_IN_FPRINTF_UNLOCKED
and BUILT_IN_FPRINTF using expand_builtin_fprintf.
* c-common.c (is_valid_printf_arglist): Delete.
(c_expand_builtin): Delete.
(c_expand_builtin_printf): Moved to builtins.c. Delete.
(c_expand_builtin_fprintf): Moved to builtins.c. Delete.
(c_expand_expr): No longer treat CALL_EXPRs specially.
(CALLED_AS_BUILT_IN): Delete.
From-SVN: r69760
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 296 |
1 files changed, 0 insertions, 296 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 685ec2c..2e985c2 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -1175,14 +1175,6 @@ fix_string_type (tree value) return value; } -static int is_valid_printf_arglist (tree); -static rtx c_expand_builtin (tree, rtx, enum machine_mode, - enum expand_modifier); -static rtx c_expand_builtin_printf (tree, rtx, enum machine_mode, - enum expand_modifier, int, int); -static rtx c_expand_builtin_fprintf (tree, rtx, enum machine_mode, - enum expand_modifier, int, int); - /* Print a warning if a constant expression had overflow in folding. Invoke this function on every expression that the language requires to be a constant expression. @@ -4053,20 +4045,6 @@ c_expand_expr (tree exp, rtx target, enum machine_mode tmode, int modifier) } break; - case CALL_EXPR: - { - if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR - && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - == FUNCTION_DECL) - && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - && (DECL_BUILT_IN_CLASS (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) - == BUILT_IN_FRONTEND)) - return c_expand_builtin (exp, target, tmode, modifier); - else - abort (); - } - break; - case COMPOUND_LITERAL_EXPR: { /* Initialize the anonymous variable declared in the compound @@ -4135,280 +4113,6 @@ c_staticp (tree exp) return 1; return 0; } - -#define CALLED_AS_BUILT_IN(NODE) \ - (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10)) - -static rtx -c_expand_builtin (tree exp, rtx target, enum machine_mode tmode, - enum expand_modifier modifier) -{ - tree type = TREE_TYPE (exp); - tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); - tree arglist = TREE_OPERAND (exp, 1); - enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); - enum tree_code code = TREE_CODE (exp); - const int ignore = (target == const0_rtx - || ((code == NON_LVALUE_EXPR || code == NOP_EXPR - || code == CONVERT_EXPR || code == REFERENCE_EXPR - || code == COND_EXPR) - && TREE_CODE (type) == VOID_TYPE)); - - if (! optimize && ! CALLED_AS_BUILT_IN (fndecl)) - return expand_call (exp, target, ignore); - - switch (fcode) - { - case BUILT_IN_PRINTF: - target = c_expand_builtin_printf (arglist, target, tmode, - modifier, ignore, /*unlocked=*/ 0); - if (target) - return target; - break; - - case BUILT_IN_PRINTF_UNLOCKED: - target = c_expand_builtin_printf (arglist, target, tmode, - modifier, ignore, /*unlocked=*/ 1); - if (target) - return target; - break; - - case BUILT_IN_FPRINTF: - target = c_expand_builtin_fprintf (arglist, target, tmode, - modifier, ignore, /*unlocked=*/ 0); - if (target) - return target; - break; - - case BUILT_IN_FPRINTF_UNLOCKED: - target = c_expand_builtin_fprintf (arglist, target, tmode, - modifier, ignore, /*unlocked=*/ 1); - if (target) - return target; - break; - - default: /* just do library call, if unknown builtin */ - error ("built-in function `%s' not currently supported", - IDENTIFIER_POINTER (DECL_NAME (fndecl))); - } - - /* The switch statement above can drop through to cause the function - to be called normally. */ - return expand_call (exp, target, ignore); -} - -/* Check an arglist to *printf for problems. The arglist should start - at the format specifier, with the remaining arguments immediately - following it. */ -static int -is_valid_printf_arglist (tree arglist) -{ - /* Save this value so we can restore it later. */ - const int SAVE_pedantic = pedantic; - int diagnostic_occurred = 0; - tree attrs; - - /* Set this to a known value so the user setting won't affect code - generation. */ - pedantic = 1; - /* Check to make sure there are no format specifier errors. */ - attrs = tree_cons (get_identifier ("format"), - tree_cons (NULL_TREE, - get_identifier ("printf"), - tree_cons (NULL_TREE, - integer_one_node, - tree_cons (NULL_TREE, - build_int_2 (2, 0), - NULL_TREE))), - NULL_TREE); - check_function_format (&diagnostic_occurred, attrs, arglist); - - /* Restore the value of `pedantic'. */ - pedantic = SAVE_pedantic; - - /* If calling `check_function_format_ptr' produces a warning, we - return false, otherwise we return true. */ - return ! diagnostic_occurred; -} - -/* If the arguments passed to printf are suitable for optimizations, - we attempt to transform the call. */ -static rtx -c_expand_builtin_printf (tree arglist, rtx target, enum machine_mode tmode, - enum expand_modifier modifier, int ignore, - int unlocked) -{ - tree fn_putchar = unlocked ? - implicit_built_in_decls[BUILT_IN_PUTCHAR_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTCHAR]; - tree fn_puts = unlocked ? - implicit_built_in_decls[BUILT_IN_PUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_PUTS]; - tree fn, format_arg, stripped_string; - - /* If the return value is used, or the replacement _DECL isn't - initialized, don't do the transformation. */ - if (!ignore || !fn_putchar || !fn_puts) - return 0; - - /* Verify the required arguments in the original call. */ - if (arglist == 0 - || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)) - return 0; - - /* Check the specifier vs. the parameters. */ - if (!is_valid_printf_arglist (arglist)) - return 0; - - format_arg = TREE_VALUE (arglist); - stripped_string = format_arg; - STRIP_NOPS (stripped_string); - if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR) - stripped_string = TREE_OPERAND (stripped_string, 0); - - /* If the format specifier isn't a STRING_CST, punt. */ - if (TREE_CODE (stripped_string) != STRING_CST) - return 0; - - /* OK! We can attempt optimization. */ - - /* If the format specifier was "%s\n", call __builtin_puts(arg2). */ - if (strcmp (TREE_STRING_POINTER (stripped_string), "%s\n") == 0) - { - arglist = TREE_CHAIN (arglist); - fn = fn_puts; - } - /* If the format specifier was "%c", call __builtin_putchar (arg2). */ - else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0) - { - arglist = TREE_CHAIN (arglist); - fn = fn_putchar; - } - else - { - /* We can't handle anything else with % args or %% ... yet. */ - if (strchr (TREE_STRING_POINTER (stripped_string), '%')) - return 0; - - /* If the resulting constant string has a length of 1, call - putchar. Note, TREE_STRING_LENGTH includes the terminating - NULL in its count. */ - if (TREE_STRING_LENGTH (stripped_string) == 2) - { - /* Given printf("c"), (where c is any one character,) - convert "c"[0] to an int and pass that to the replacement - function. */ - arglist = build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0); - arglist = build_tree_list (NULL_TREE, arglist); - - fn = fn_putchar; - } - /* If the resulting constant was "string\n", call - __builtin_puts("string"). Ensure "string" has at least one - character besides the trailing \n. Note, TREE_STRING_LENGTH - includes the terminating NULL in its count. */ - else if (TREE_STRING_LENGTH (stripped_string) > 2 - && TREE_STRING_POINTER (stripped_string) - [TREE_STRING_LENGTH (stripped_string) - 2] == '\n') - { - /* Create a NULL-terminated string that's one char shorter - than the original, stripping off the trailing '\n'. */ - const int newlen = TREE_STRING_LENGTH (stripped_string) - 1; - char *newstr = alloca (newlen); - memcpy (newstr, TREE_STRING_POINTER (stripped_string), newlen - 1); - newstr[newlen - 1] = 0; - - arglist = fix_string_type (build_string (newlen, newstr)); - arglist = build_tree_list (NULL_TREE, arglist); - fn = fn_puts; - } - else - /* We'd like to arrange to call fputs(string) here, but we - need stdout and don't have a way to get it ... yet. */ - return 0; - } - - return expand_expr (build_function_call (fn, arglist), - (ignore ? const0_rtx : target), - tmode, modifier); -} - -/* If the arguments passed to fprintf are suitable for optimizations, - we attempt to transform the call. */ -static rtx -c_expand_builtin_fprintf (tree arglist, rtx target, enum machine_mode tmode, - enum expand_modifier modifier, int ignore, - int unlocked) -{ - tree fn_fputc = unlocked ? - implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTC]; - tree fn_fputs = unlocked ? - implicit_built_in_decls[BUILT_IN_FPUTS_UNLOCKED] : implicit_built_in_decls[BUILT_IN_FPUTS]; - tree fn, format_arg, stripped_string; - - /* If the return value is used, or the replacement _DECL isn't - initialized, don't do the transformation. */ - if (!ignore || !fn_fputc || !fn_fputs) - return 0; - - /* Verify the required arguments in the original call. */ - if (arglist == 0 - || (TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE) - || (TREE_CHAIN (arglist) == 0) - || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != - POINTER_TYPE)) - return 0; - - /* Check the specifier vs. the parameters. */ - if (!is_valid_printf_arglist (TREE_CHAIN (arglist))) - return 0; - - format_arg = TREE_VALUE (TREE_CHAIN (arglist)); - stripped_string = format_arg; - STRIP_NOPS (stripped_string); - if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR) - stripped_string = TREE_OPERAND (stripped_string, 0); - - /* If the format specifier isn't a STRING_CST, punt. */ - if (TREE_CODE (stripped_string) != STRING_CST) - return 0; - - /* OK! We can attempt optimization. */ - - /* If the format specifier was "%s", call __builtin_fputs(arg3, arg1). */ - if (strcmp (TREE_STRING_POINTER (stripped_string), "%s") == 0) - { - tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist)); - arglist = tree_cons (NULL_TREE, - TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))), - newarglist); - fn = fn_fputs; - } - /* If the format specifier was "%c", call __builtin_fputc (arg3, arg1). */ - else if (strcmp (TREE_STRING_POINTER (stripped_string), "%c") == 0) - { - tree newarglist = build_tree_list (NULL_TREE, TREE_VALUE (arglist)); - arglist = tree_cons (NULL_TREE, - TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))), - newarglist); - fn = fn_fputc; - } - else - { - /* We can't handle anything else with % args or %% ... yet. */ - if (strchr (TREE_STRING_POINTER (stripped_string), '%')) - return 0; - - /* When "string" doesn't contain %, replace all cases of - fprintf(stream,string) with fputs(string,stream). The fputs - builtin will take take of special cases like length==1. */ - arglist = tree_cons (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)), - build_tree_list (NULL_TREE, TREE_VALUE (arglist))); - fn = fn_fputs; - } - - return expand_expr (build_function_call (fn, arglist), - (ignore ? const0_rtx : target), - tmode, modifier); -} /* Given a boolean expression ARG, return a tree representing an increment |