mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-12 02:54:31 +08:00
builtins.c (built_in_decls): New array.
* builtins.c (built_in_decls): New array. (expand_builtin_fputs): New function. (expand_builtin): Handle BUILT_IN_FPUTC and BUILT_IN_FPUTS. * builtins.def (BUILT_IN_FPUTC, BUILT_IN_FPUTS): New members. * c-common.c (c_common_nodes_and_builtins): Handle fputc/fputs. * tree.h (built_in_decls): New array. From-SVN: r36363
This commit is contained in:
parent
208b0ab1c8
commit
3ff5f682dc
@ -1,3 +1,15 @@
|
||||
2000-09-12 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* builtins.c (built_in_decls): New array.
|
||||
(expand_builtin_fputs): New function.
|
||||
(expand_builtin): Handle BUILT_IN_FPUTC and BUILT_IN_FPUTS.
|
||||
|
||||
* builtins.def (BUILT_IN_FPUTC, BUILT_IN_FPUTS): New members.
|
||||
|
||||
* c-common.c (c_common_nodes_and_builtins): Handle fputc/fputs.
|
||||
|
||||
* tree.h (built_in_decls): New array.
|
||||
|
||||
Tue Sep 12 08:53:57 2000 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* convex.md: Use "+" instead of "=" for outputs wrapped in a
|
||||
|
@ -67,6 +67,15 @@ const char *const built_in_names[(int) END_BUILTINS] =
|
||||
};
|
||||
#undef DEF_BUILTIN
|
||||
|
||||
/* Setup an array of _DECL trees, make sure each element is
|
||||
initialized to NULL_TREE. */
|
||||
#define DEF_BUILTIN(x) NULL_TREE,
|
||||
tree built_in_decls[(int) END_BUILTINS] =
|
||||
{
|
||||
#include "builtins.def"
|
||||
};
|
||||
#undef DEF_BUILTIN
|
||||
|
||||
tree (*lang_type_promotes_to) PARAMS ((tree));
|
||||
|
||||
static int get_pointer_alignment PARAMS ((tree, unsigned));
|
||||
@ -102,6 +111,7 @@ static rtx expand_builtin_strlen PARAMS ((tree, rtx,
|
||||
static rtx expand_builtin_alloca PARAMS ((tree, rtx));
|
||||
static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
|
||||
static rtx expand_builtin_frame_address PARAMS ((tree));
|
||||
static rtx expand_builtin_fputs PARAMS ((tree, int));
|
||||
static tree stabilize_va_list PARAMS ((tree, int));
|
||||
static rtx expand_builtin_expect PARAMS ((tree, rtx));
|
||||
|
||||
@ -2310,6 +2320,60 @@ expand_builtin_ffs (arglist, target, subtarget)
|
||||
return target;
|
||||
}
|
||||
|
||||
/* If the string passed to fputs is a constant and is one character
|
||||
long, we attempt to transform this call into __builtin_fputc(). */
|
||||
static rtx
|
||||
expand_builtin_fputs (arglist, ignore)
|
||||
tree arglist;
|
||||
int ignore;
|
||||
{
|
||||
tree call_expr, len, stripped_string, newarglist;
|
||||
tree fn = built_in_decls[BUILT_IN_FPUTC];
|
||||
|
||||
/* If the return value is used, or the replacement _DECL isn't
|
||||
initialized, don't do the transformation. */
|
||||
if (!ignore || !fn)
|
||||
return 0;
|
||||
|
||||
/* Verify the 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;
|
||||
|
||||
/* Get the length of the string passed to fputs. */
|
||||
len = c_strlen (TREE_VALUE (arglist));
|
||||
|
||||
/* If the length != 1, punt. */
|
||||
if (len == 0 || compare_tree_int (len, 1))
|
||||
return 0;
|
||||
|
||||
stripped_string = TREE_VALUE (arglist);
|
||||
STRIP_NOPS (stripped_string);
|
||||
if (stripped_string && TREE_CODE (stripped_string) == ADDR_EXPR)
|
||||
stripped_string = TREE_OPERAND (stripped_string, 0);
|
||||
|
||||
/* New argument list transforming fputs(string, stream) to
|
||||
fputc(string[0], stream). */
|
||||
newarglist = build_tree_list (NULL_TREE, TREE_VALUE (TREE_CHAIN (arglist)));
|
||||
newarglist =
|
||||
tree_cons (NULL_TREE,
|
||||
build_int_2 (TREE_STRING_POINTER (stripped_string)[0], 0),
|
||||
newarglist);
|
||||
|
||||
#ifdef TEST_STDIO_OPTS
|
||||
warning ("Converted fputs(one-char-string, FILE*) -> fputc(char, FILE*)");
|
||||
#endif
|
||||
|
||||
call_expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (fn)), fn);
|
||||
call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
|
||||
call_expr, newarglist, NULL_TREE);
|
||||
TREE_SIDE_EFFECTS (call_expr) = 1;
|
||||
return expand_expr (call_expr, NULL_RTX, VOIDmode, 0);
|
||||
}
|
||||
|
||||
/* Expand a call to __builtin_expect. We return our argument and
|
||||
emit a NOTE_INSN_EXPECTED_VALUE note. */
|
||||
|
||||
@ -2383,7 +2447,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
|| fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
|
||||
|| fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
|
||||
|| fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
|
||||
|| fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS))
|
||||
|| fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
|
||||
|| fcode == BUILT_IN_FPUTC || fcode == BUILT_IN_FPUTS))
|
||||
return expand_call (exp, target, ignore);
|
||||
|
||||
switch (fcode)
|
||||
@ -2596,6 +2661,15 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|
||||
emit_barrier ();
|
||||
return const0_rtx;
|
||||
|
||||
case BUILT_IN_FPUTC:
|
||||
break;
|
||||
|
||||
case BUILT_IN_FPUTS:
|
||||
target = expand_builtin_fputs (arglist, ignore);
|
||||
if (target)
|
||||
return target;
|
||||
break;
|
||||
|
||||
/* Various hooks for the DWARF 2 __throw routine. */
|
||||
case BUILT_IN_UNWIND_INIT:
|
||||
expand_builtin_unwind_init ();
|
||||
|
@ -58,6 +58,10 @@ DEF_BUILTIN(BUILT_IN_SETJMP)
|
||||
DEF_BUILTIN(BUILT_IN_LONGJMP)
|
||||
DEF_BUILTIN(BUILT_IN_TRAP)
|
||||
|
||||
/* Stdio builtins. */
|
||||
DEF_BUILTIN(BUILT_IN_FPUTC)
|
||||
DEF_BUILTIN(BUILT_IN_FPUTS)
|
||||
|
||||
/* ISO C99 floating point unordered comparisons. */
|
||||
DEF_BUILTIN(BUILT_IN_ISGREATER)
|
||||
DEF_BUILTIN(BUILT_IN_ISGREATEREQUAL)
|
||||
|
@ -4136,6 +4136,17 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
|
||||
BUILT_IN_COS, BUILT_IN_NORMAL, "cos");
|
||||
builtin_function ("__builtin_cosl", ldouble_ftype_ldouble,
|
||||
BUILT_IN_COS, BUILT_IN_NORMAL, "cosl");
|
||||
/* We declare these without argument so that the initial declaration
|
||||
for these identifiers is a builtin. That allows us to redeclare
|
||||
them later with argument without worrying about the explicit
|
||||
declarations in stdio.h being taken as the initial declaration.
|
||||
Also, save the _DECL for these so we can use them later. */
|
||||
built_in_decls[BUILT_IN_FPUTC] =
|
||||
builtin_function ("__builtin_fputc", int_ftype_any,
|
||||
BUILT_IN_FPUTC, BUILT_IN_NORMAL, "fputc");
|
||||
built_in_decls[BUILT_IN_FPUTS] =
|
||||
builtin_function ("__builtin_fputs", int_ftype_any,
|
||||
BUILT_IN_FPUTS, BUILT_IN_NORMAL, "fputs");
|
||||
|
||||
if (! no_builtins)
|
||||
{
|
||||
@ -4179,6 +4190,15 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("cosl", ldouble_ftype_ldouble, BUILT_IN_COS,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
/* We declare these without argument so that the initial
|
||||
declaration for these identifiers is a builtin. That allows
|
||||
us to redeclare them later with argument without worrying
|
||||
about the explicit declarations in stdio.h being taken as the
|
||||
initial declaration. */
|
||||
builtin_function ("fputc", int_ftype_any, BUILT_IN_FPUTC,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
builtin_function ("fputs", int_ftype_any, BUILT_IN_FPUTS,
|
||||
BUILT_IN_NORMAL, NULL_PTR);
|
||||
|
||||
/* Declare these functions volatile
|
||||
to avoid spurious "control drops through" warnings. */
|
||||
|
@ -96,6 +96,9 @@ enum built_in_function
|
||||
|
||||
/* Names for the above. */
|
||||
extern const char *const built_in_names[(int) END_BUILTINS];
|
||||
|
||||
/* An array of _DECL trees for the above. */
|
||||
extern union tree_node *built_in_decls[(int) END_BUILTINS];
|
||||
|
||||
/* The definition of tree nodes fills the next several pages. */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user