This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Pure and const attributes for builtins




This patch extends GCC's table base mechanism for defining builtins
to allow the "pure" and "const" attributes of builtin functions to
be specified, allowing futher optimization.

For example, with this patch expressions such as "strlen(p)+strlen(p)"
generate code that only calls strlen once.  This marks strlen, strcmp,
strncmp, strchr, strrchr, strstr, strpbrk, strspn, strcspn, memcmp,
rindex, index and bcmp as pure functions, and abs, labs, fabs, fabsf,
fabsl and ffs as const functions.  The __builtin_* variants are also
given the appropriate attributes.

This patch was tested by "make bootstrap" and "make check-gcc" on
i686-pc-linux-gnu with no new regressions.  A related follow-up
patch will be posted in the next few minutes.



2001-11-23  Roger Sayle <roger@eyesopen.com>
	* builtins.def: Extend DEF_BUILTIN to contain two additional
	fields, PURE_P and CONST_P, to represent the pure and const
	attributes of the builtin function.  Mark strlen, strcmp,
	strncmp, strchr, strrchr, strstr, strpbrk, strspn, strcspn,
	memcmp, rindex, index and bcmp as pure functions.  Mark
	abs, labs, fabs, fabsf, fabsl and ffs as const functions.
	* tree.h: Update to reflect extra DEF_BUILTIN arguments.
	* builtins.c: Update to reflect extra DEF_BUILTIN arguments.
	* c-common.c (builtin_function_2): Accept two extra parameters,
	pure_p and const_p, to indicate the pure and const attributes
	of the builtin function.
	(c_common_nodes_and_builtins): Pass these additional values
	in all calls to builtin_function_2.


diff -c3pr gcc/gcc/builtins.c patch2/gcc/builtins.c
*** gcc/gcc/builtins.c	Sun Nov 18 10:33:50 2001
--- patch2/gcc/builtins.c	Fri Nov 23 17:36:11 2001
*************** Software Foundation, 59 Temple Place - S
*** 61,67 ****
  const char *const built_in_class_names[4]
    = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};

! #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA) STRINGX(X),
  const char *const built_in_names[(int) END_BUILTINS] =
  {
  #include "builtins.def"
--- 61,67 ----
  const char *const built_in_class_names[4]
    = {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};

! #define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, P, CO) STRINGX(X),
  const char *const built_in_names[(int) END_BUILTINS] =
  {
  #include "builtins.def"
diff -c3pr gcc/gcc/builtins.def patch2/gcc/builtins.def
*** gcc/gcc/builtins.def	Sun Nov 18 10:37:38 2001
--- patch2/gcc/builtins.def	Fri Nov 23 17:34:34 2001
*************** Software Foundation, 59 Temple Place - S
*** 22,28 ****
  /* Before including this file, you should define a macro:

       DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
!                   FALLBACK_P, NONANSI_P)

     This macro will be called once for each builtin function.  The
     ENUM will be of type `enum built_in_function', and will indicate
--- 22,28 ----
  /* Before including this file, you should define a macro:

       DEF_BUILTIN (ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P,
!                   FALLBACK_P, NONANSI_P, PURE_P, CONST_P)

     This macro will be called once for each builtin function.  The
     ENUM will be of type `enum built_in_function', and will indicate
*************** Software Foundation, 59 Temple Place - S
*** 50,56 ****

     If NONANSI_P is true, then the non-`__builtin_' variant is not an
     ANSI/ISO library function, and so we should pretend it does not
!    exist when compiling in ANSI conformant mode.  */

  /* A GCC builtin (like __builtin_saveregs) is provided by the
     compiler, but does not correspond to a function in the standard
--- 50,65 ----

     If NONANSI_P is true, then the non-`__builtin_' variant is not an
     ANSI/ISO library function, and so we should pretend it does not
!    exist when compiling in ANSI conformant mode.
!
!    If PURE_P is true, then the function(s) are marked with the pure
!    attribute, indicating that the function has no side-effects and
!    the result depends only upon the parameter values and the contents
!    of memory.
!
!    If CONST_P is true, then the function(s) are marked with the
!    const attribute, indicating that the function has no side-effects
!    and the result depends only upon the values of its parameters.  */

  /* A GCC builtin (like __builtin_saveregs) is provided by the
     compiler, but does not correspond to a function in the standard
*************** Software Foundation, 59 Temple Place - S
*** 58,64 ****
  #undef DEF_GCC_BUILTIN
  #define DEF_GCC_BUILTIN(ENUM, NAME, TYPE)			\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST,	\
!                false, false, false)


  /* A fallback builtin is a builtin (like __builtin_puts) that falls
--- 67,73 ----
  #undef DEF_GCC_BUILTIN
  #define DEF_GCC_BUILTIN(ENUM, NAME, TYPE)			\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, BT_LAST,	\
!                false, false, false, false, false)


  /* A fallback builtin is a builtin (like __builtin_puts) that falls
*************** Software Foundation, 59 Temple Place - S
*** 68,121 ****
  #undef DEF_FALLBACK_BUILTIN
  #define DEF_FALLBACK_BUILTIN(ENUM, NAME, TYPE)		\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
! 	       false, true, false)

  /* A library builtin (like __builtin_strchr) is a builtin equivalent
     of an ANSI/ISO standard library function.  In addition to the
!    `__builtin' version, we will create an ordinary version (e.g,
     `strchr') as well.  If we cannot compute the answer using the
     builtin function, we will fall back to the standard library
     version. */
  #undef DEF_LIB_BUILTIN
! #define DEF_LIB_BUILTIN(ENUM, NAME, TYPE)		\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
! 	       true, true, false)

  /* Like DEF_LIB_BUILTIN, except that a call to the builtin should
!    never fall back to the library version.  */
  #undef DEF_LIB_ALWAYS_BUILTIN
  #define DEF_LIB_ALWAYS_BUILTIN(ENUM, NAME, TYPE)	\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
!     	       true, false, true)

  /* Like DEF_LIB_BUILTIN, except that the function is not one that is
     specified by ANSI/ISO C.  So, when we're being fully conformant we
     ignore the version of these builtins that does not begin with
     __builtin.  */
  #undef DEF_EXT_LIB_BUILTIN
! #define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE)		\
!   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
!    	       true, true, true)

  /* Like DEF_LIB_BUILTIN, except that the function is only a part of
     the standard in C99 or above.  */
  #undef DEF_C99_BUILTIN
  #define DEF_C99_BUILTIN(ENUM, NAME, TYPE)		\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
!    	       true, !flag_isoc99, true)

  /* Like DEF_LIB_BUILTIN, except that the function is expanded in the
     front-end.  */
  #undef DEF_FRONT_END_LIB_BUILTIN
  #define DEF_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE)	        \
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE,	\
! 	       true, true, false)

  /* A built-in that is not currently used.  */
  #undef DEF_UNUSED_BUILTIN
  #define DEF_UNUSED_BUILTIN(X)					\
    DEF_BUILTIN (X, (const char *) NULL, NOT_BUILT_IN, BT_LAST,	\
! 	       BT_LAST, false, false, false)

  /* If SMALL_STACK is defined, then `alloca' is only defined in its
     `__builtin' form.  */
--- 77,131 ----
  #undef DEF_FALLBACK_BUILTIN
  #define DEF_FALLBACK_BUILTIN(ENUM, NAME, TYPE)		\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
! 	       false, true, false, false, false)

  /* A library builtin (like __builtin_strchr) is a builtin equivalent
     of an ANSI/ISO standard library function.  In addition to the
!    `__builtin' version, we will create a an ordinary version (e.g,
     `strchr') as well.  If we cannot compute the answer using the
     builtin function, we will fall back to the standard library
     version. */
  #undef DEF_LIB_BUILTIN
! #define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, PURE_P)	\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
! 	       true, true, false, PURE_P, false)

  /* Like DEF_LIB_BUILTIN, except that a call to the builtin should
!    never fall back to the library version.  The functions are
!    marked const */
  #undef DEF_LIB_ALWAYS_BUILTIN
  #define DEF_LIB_ALWAYS_BUILTIN(ENUM, NAME, TYPE)	\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
!     	       true, false, true, false, true)

  /* Like DEF_LIB_BUILTIN, except that the function is not one that is
     specified by ANSI/ISO C.  So, when we're being fully conformant we
     ignore the version of these builtins that does not begin with
     __builtin.  */
  #undef DEF_EXT_LIB_BUILTIN
! #define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, PURE_P, CONST_P)	\
!   DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,		\
!    	       true, true, true, PURE_P, CONST_P)

  /* Like DEF_LIB_BUILTIN, except that the function is only a part of
     the standard in C99 or above.  */
  #undef DEF_C99_BUILTIN
  #define DEF_C99_BUILTIN(ENUM, NAME, TYPE)		\
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_NORMAL, TYPE, TYPE,	\
!    	       true, !flag_isoc99, true, false, false)

  /* Like DEF_LIB_BUILTIN, except that the function is expanded in the
     front-end.  */
  #undef DEF_FRONT_END_LIB_BUILTIN
  #define DEF_FRONT_END_LIB_BUILTIN(ENUM, NAME, TYPE)	        \
    DEF_BUILTIN (ENUM, NAME, BUILT_IN_FRONTEND, TYPE, TYPE,	\
! 	       true, true, false, false, false)

  /* A built-in that is not currently used.  */
  #undef DEF_UNUSED_BUILTIN
  #define DEF_UNUSED_BUILTIN(X)					\
    DEF_BUILTIN (X, (const char *) NULL, NOT_BUILT_IN, BT_LAST,	\
! 	       BT_LAST, false, false, false, false, false)

  /* If SMALL_STACK is defined, then `alloca' is only defined in its
     `__builtin' form.  */
*************** DEF_FALLBACK_BUILTIN(BUILT_IN_ALLOCA,
*** 126,132 ****
  #else
  DEF_EXT_LIB_BUILTIN(BUILT_IN_ALLOCA,
  		    "__builtin_alloca",
! 		    BT_FN_PTR_SIZE)
  #endif

  DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_ABS,
--- 136,143 ----
  #else
  DEF_EXT_LIB_BUILTIN(BUILT_IN_ALLOCA,
  		    "__builtin_alloca",
! 		    BT_FN_PTR_SIZE,
!                     false, false)
  #endif

  DEF_LIB_ALWAYS_BUILTIN(BUILT_IN_ABS,
*************** DEF_BUILTIN (BUILT_IN_BZERO,
*** 195,295 ****
  	     BUILT_IN_NORMAL,
  	     BT_FN_VOID_TRAD_PTR_LEN,
  	     BT_FN_VOID_VAR,
! 	     true, true, true)
  DEF_BUILTIN (BUILT_IN_BCMP,
  	     "__builtin_bcmp",
  	     BUILT_IN_NORMAL,
  	     BT_FN_INT_TRAD_CONST_PTR_TRAD_CONST_PTR_LEN,
  	     BT_FN_INT_VAR,
! 	     true, true, true)

  DEF_EXT_LIB_BUILTIN(BUILT_IN_FFS,
  		    "__builtin_ffs",
! 		    BT_FN_INT_INT)
  DEF_EXT_LIB_BUILTIN(BUILT_IN_INDEX,
  		    "__builtin_index",
! 		    BT_FN_STRING_CONST_STRING_INT)
  DEF_EXT_LIB_BUILTIN(BUILT_IN_RINDEX,
  		    "__builtin_rindex",
! 		    BT_FN_STRING_CONST_STRING_INT)

  DEF_LIB_BUILTIN(BUILT_IN_MEMCPY,
  		"__builtin_memcpy",
! 		BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE)
  DEF_LIB_BUILTIN(BUILT_IN_MEMCMP,
  		"__builtin_memcmp",
! 		BT_FN_INT_CONST_PTR_CONST_PTR_SIZE)
  DEF_LIB_BUILTIN(BUILT_IN_MEMSET,
  		"__builtin_memset",
! 		BT_FN_TRAD_PTR_PTR_INT_SIZE)

  DEF_LIB_BUILTIN(BUILT_IN_STRCAT,
  		"__builtin_strcat",
! 		BT_FN_STRING_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRNCAT,
  		"__builtin_strncat",
! 		BT_FN_STRING_STRING_CONST_STRING_SIZE)
  DEF_LIB_BUILTIN(BUILT_IN_STRCPY,
  		"__builtin_strcpy",
! 		BT_FN_STRING_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRNCPY,
  		"__builtin_strncpy",
! 		BT_FN_STRING_STRING_CONST_STRING_SIZE)
  DEF_LIB_BUILTIN(BUILT_IN_STRCMP,
  		"__builtin_strcmp",
! 		BT_FN_INT_CONST_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRNCMP,
  		"__builtin_strncmp",
! 		BT_FN_INT_CONST_STRING_CONST_STRING_SIZE)
  DEF_LIB_BUILTIN(BUILT_IN_STRLEN,
  		"__builtin_strlen",
! 		BT_FN_LEN_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRSTR,
  		"__builtin_strstr",
! 		BT_FN_STRING_CONST_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRPBRK,
  		"__builtin_strpbrk",
! 		BT_FN_STRING_CONST_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRSPN,
  		"__builtin_strspn",
! 		BT_FN_SIZE_CONST_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRCSPN,
  		"__builtin_strcspn",
! 		BT_FN_SIZE_CONST_STRING_CONST_STRING)
  DEF_LIB_BUILTIN(BUILT_IN_STRCHR,
  		"__builtin_strchr",
! 		BT_FN_STRING_CONST_STRING_INT)
  DEF_LIB_BUILTIN(BUILT_IN_STRRCHR,
  		"__builtin_strrchr",
! 		BT_FN_STRING_CONST_STRING_INT)

  DEF_LIB_BUILTIN(BUILT_IN_FSQRT,
! 		"__builtin_fsqrt",
! 		BT_FN_DOUBLE_DOUBLE)
  DEF_LIB_BUILTIN(BUILT_IN_SIN,
  		"__builtin_sin",
! 		BT_FN_DOUBLE_DOUBLE)
  DEF_LIB_BUILTIN(BUILT_IN_COS,
  		"__builtin_cos",
! 		BT_FN_DOUBLE_DOUBLE)
  DEF_LIB_BUILTIN(BUILT_IN_SQRTF,
  		"__builtin_sqrtf",
! 		BT_FN_FLOAT_FLOAT)
  DEF_LIB_BUILTIN(BUILT_IN_SINF,
  		"__builtin_sinf",
! 		BT_FN_FLOAT_FLOAT)
  DEF_LIB_BUILTIN(BUILT_IN_COSF,
  		"__builtin_cosf",
! 		BT_FN_FLOAT_FLOAT)
  DEF_LIB_BUILTIN(BUILT_IN_SQRTL,
  		"__builtin_sqrtl",
! 		BT_FN_LONG_DOUBLE_LONG_DOUBLE)
  DEF_LIB_BUILTIN(BUILT_IN_SINL,
  		"__builtin_sinl",
! 		BT_FN_LONG_DOUBLE_LONG_DOUBLE)
  DEF_LIB_BUILTIN(BUILT_IN_COSL,
  		"__builtin_cosl",
! 		BT_FN_LONG_DOUBLE_LONG_DOUBLE)

  DEF_UNUSED_BUILTIN(BUILT_IN_GETEXP)
  DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN)
--- 206,334 ----
  	     BUILT_IN_NORMAL,
  	     BT_FN_VOID_TRAD_PTR_LEN,
  	     BT_FN_VOID_VAR,
! 	     true, true, true, false, false)
  DEF_BUILTIN (BUILT_IN_BCMP,
  	     "__builtin_bcmp",
  	     BUILT_IN_NORMAL,
  	     BT_FN_INT_TRAD_CONST_PTR_TRAD_CONST_PTR_LEN,
  	     BT_FN_INT_VAR,
! 	     true, true, true, true, false)

  DEF_EXT_LIB_BUILTIN(BUILT_IN_FFS,
  		    "__builtin_ffs",
! 		    BT_FN_INT_INT,
!                     false, true)
  DEF_EXT_LIB_BUILTIN(BUILT_IN_INDEX,
  		    "__builtin_index",
! 		    BT_FN_STRING_CONST_STRING_INT,
!                     true, false)
  DEF_EXT_LIB_BUILTIN(BUILT_IN_RINDEX,
  		    "__builtin_rindex",
! 		    BT_FN_STRING_CONST_STRING_INT,
!                     true,false)

  DEF_LIB_BUILTIN(BUILT_IN_MEMCPY,
  		"__builtin_memcpy",
! 		BT_FN_TRAD_PTR_PTR_CONST_PTR_SIZE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_MEMCMP,
  		"__builtin_memcmp",
! 		BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_MEMSET,
  		"__builtin_memset",
! 		BT_FN_TRAD_PTR_PTR_INT_SIZE,
!                 false)

  DEF_LIB_BUILTIN(BUILT_IN_STRCAT,
  		"__builtin_strcat",
! 		BT_FN_STRING_STRING_CONST_STRING,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_STRNCAT,
  		"__builtin_strncat",
! 		BT_FN_STRING_STRING_CONST_STRING_SIZE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_STRCPY,
  		"__builtin_strcpy",
! 		BT_FN_STRING_STRING_CONST_STRING,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_STRNCPY,
  		"__builtin_strncpy",
! 		BT_FN_STRING_STRING_CONST_STRING_SIZE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_STRCMP,
  		"__builtin_strcmp",
! 		BT_FN_INT_CONST_STRING_CONST_STRING,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRNCMP,
  		"__builtin_strncmp",
! 		BT_FN_INT_CONST_STRING_CONST_STRING_SIZE,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRLEN,
  		"__builtin_strlen",
! 		BT_FN_LEN_CONST_STRING,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRSTR,
  		"__builtin_strstr",
! 		BT_FN_STRING_CONST_STRING_CONST_STRING,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRPBRK,
  		"__builtin_strpbrk",
! 		BT_FN_STRING_CONST_STRING_CONST_STRING,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRSPN,
  		"__builtin_strspn",
! 		BT_FN_SIZE_CONST_STRING_CONST_STRING,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRCSPN,
  		"__builtin_strcspn",
! 		BT_FN_SIZE_CONST_STRING_CONST_STRING,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRCHR,
  		"__builtin_strchr",
! 		BT_FN_STRING_CONST_STRING_INT,
!                 true)
  DEF_LIB_BUILTIN(BUILT_IN_STRRCHR,
  		"__builtin_strrchr",
! 		BT_FN_STRING_CONST_STRING_INT,
!                 true)

  DEF_LIB_BUILTIN(BUILT_IN_FSQRT,
! 		"__builtin_sqrt",
! 		BT_FN_DOUBLE_DOUBLE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_SIN,
  		"__builtin_sin",
! 		BT_FN_DOUBLE_DOUBLE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_COS,
  		"__builtin_cos",
! 		BT_FN_DOUBLE_DOUBLE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_SQRTF,
  		"__builtin_sqrtf",
! 		BT_FN_FLOAT_FLOAT,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_SINF,
  		"__builtin_sinf",
! 		BT_FN_FLOAT_FLOAT,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_COSF,
  		"__builtin_cosf",
! 		BT_FN_FLOAT_FLOAT,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_SQRTL,
  		"__builtin_sqrtl",
! 		BT_FN_LONG_DOUBLE_LONG_DOUBLE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_SINL,
  		"__builtin_sinl",
! 		BT_FN_LONG_DOUBLE_LONG_DOUBLE,
!                 false)
  DEF_LIB_BUILTIN(BUILT_IN_COSL,
  		"__builtin_cosl",
! 		BT_FN_LONG_DOUBLE_LONG_DOUBLE,
!                 false)

  DEF_UNUSED_BUILTIN(BUILT_IN_GETEXP)
  DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN)
*************** DEF_BUILTIN (BUILT_IN_FPUTS,
*** 359,365 ****
  	     BUILT_IN_NORMAL,
  	     BT_FN_INT_CONST_STRING_PTR,
  	     BT_FN_INT_VAR,
! 	     true, true, false)
  DEF_FALLBACK_BUILTIN(BUILT_IN_FWRITE,
  		     "__builtin_fwrite",
  		     BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR)
--- 398,404 ----
  	     BUILT_IN_NORMAL,
  	     BT_FN_INT_CONST_STRING_PTR,
  	     BT_FN_INT_VAR,
! 	     true, true, false, false, false)
  DEF_FALLBACK_BUILTIN(BUILT_IN_FWRITE,
  		     "__builtin_fwrite",
  		     BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR)
diff -c3pr gcc/gcc/c-common.c patch2/gcc/c-common.c
*** gcc/gcc/c-common.c	Sun Nov 18 10:37:39 2001
--- patch2/gcc/c-common.c	Fri Nov 23 17:44:25 2001
*************** truthvalue_conversion (expr)
*** 2086,2092 ****

  static tree builtin_function_2 PARAMS ((const char *, const char *, tree, tree,
  					int, enum built_in_class, int, int,
! 					int));

  /* Make a variant type in the proper way for C/C++, propagating qualifiers
     down to the element type of an array.  */
--- 2086,2092 ----

  static tree builtin_function_2 PARAMS ((const char *, const char *, tree, tree,
  					int, enum built_in_class, int, int,
! 					int, int, int));

  /* Make a variant type in the proper way for C/C++, propagating qualifiers
     down to the element type of an array.  */
*************** c_common_nodes_and_builtins ()
*** 2636,2643 ****
  #undef DEF_FUNCTION_TYPE_VAR_1
  #undef DEF_POINTER_TYPE

! #define DEF_BUILTIN(ENUM, NAME, CLASS,					\
!                     TYPE, LIBTYPE, BOTH_P, FALLBACK_P, NONANSI_P)	\
    if (NAME)								\
      {									\
        tree decl;							\
--- 2636,2643 ----
  #undef DEF_FUNCTION_TYPE_VAR_1
  #undef DEF_POINTER_TYPE

! #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE,			\
!                     BOTH_P, FALLBACK_P, NONANSI_P, PURE_P, CONST_P)	\
    if (NAME)								\
      {									\
        tree decl;							\
*************** c_common_nodes_and_builtins ()
*** 2660,2665 ****
--- 2660,2667 ----
  				   CLASS,				\
  				   FALLBACK_P,				\
  				   NONANSI_P,				\
+ 				   PURE_P,				\
+ 				   CONST_P,				\
  				   /*noreturn_p=*/0);			\
  									\
        built_in_decls[(int) ENUM] = decl;				\
*************** c_common_nodes_and_builtins ()
*** 2670,2679 ****
    /* Declare _exit and _Exit just to mark them as non-returning.  */
    builtin_function_2 (NULL, "_exit", NULL_TREE,
  		      builtin_types[BT_FN_VOID_INT],
! 		      0, NOT_BUILT_IN, 0, 1, 1);
    builtin_function_2 (NULL, "_Exit", NULL_TREE,
  		      builtin_types[BT_FN_VOID_INT],
! 		      0, NOT_BUILT_IN, 0, !flag_isoc99, 1);

    /* Declare these functions non-returning
       to avoid spurious "control drops through" warnings.  */
--- 2672,2681 ----
    /* Declare _exit and _Exit just to mark them as non-returning.  */
    builtin_function_2 (NULL, "_exit", NULL_TREE,
  		      builtin_types[BT_FN_VOID_INT],
! 		      0, NOT_BUILT_IN, 0, 1, 0, 0, 1);
    builtin_function_2 (NULL, "_Exit", NULL_TREE,
  		      builtin_types[BT_FN_VOID_INT],
! 		      0, NOT_BUILT_IN, 0, !flag_isoc99, 0, 0, 1);

    /* Declare these functions non-returning
       to avoid spurious "control drops through" warnings.  */
*************** c_common_nodes_and_builtins ()
*** 2681,2693 ****
  		      NULL_TREE, ((c_language == clk_cplusplus)
  				  ? builtin_types[BT_FN_VOID]
  				  : builtin_types[BT_FN_VOID_VAR]),
! 		      0, NOT_BUILT_IN, 0, 0, 1);

    builtin_function_2 (NULL, "exit",
  		      NULL_TREE, ((c_language == clk_cplusplus)
  				  ? builtin_types[BT_FN_VOID_INT]
  				  : builtin_types[BT_FN_VOID_VAR]),
! 		      0, NOT_BUILT_IN, 0, 0, 1);

    main_identifier_node = get_identifier ("main");

--- 2683,2695 ----
  		      NULL_TREE, ((c_language == clk_cplusplus)
  				  ? builtin_types[BT_FN_VOID]
  				  : builtin_types[BT_FN_VOID_VAR]),
! 		      0, NOT_BUILT_IN, 0, 0, 0, 0, 1);

    builtin_function_2 (NULL, "exit",
  		      NULL_TREE, ((c_language == clk_cplusplus)
  				  ? builtin_types[BT_FN_VOID_INT]
  				  : builtin_types[BT_FN_VOID_VAR]),
! 		      0, NOT_BUILT_IN, 0, 0, 0, 0, 1);

    main_identifier_node = get_identifier ("main");

*************** builtin_function_disabled_p (name)
*** 2761,2766 ****
--- 2763,2770 ----
     builtin_function.  If LIBRARY_NAME_P is nonzero, NAME is passed as
     the LIBRARY_NAME parameter to builtin_function when declaring BUILTIN_NAME.
     If NONANSI_P is nonzero, the name NAME is treated as a non-ANSI name; if
+    PURE_P is nonzero, the function is marked with the pure attribute; if
+    CONST_P is nonzero, the function is marked with the const attribute; if
     NORETURN_P is nonzero, the function is marked as non-returning.
     Returns the declaration of BUILTIN_NAME, if any, otherwise
     the declaration of NAME.  Does not declare NAME if flag_no_builtin,
*************** builtin_function_disabled_p (name)
*** 2768,2774 ****

  static tree
  builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
! 		    class, library_name_p, nonansi_p, noreturn_p)
       const char *builtin_name;
       const char *name;
       tree builtin_type;
--- 2772,2779 ----

  static tree
  builtin_function_2 (builtin_name, name, builtin_type, type, function_code,
! 		    class, library_name_p, nonansi_p, pure_p, const_p,
!                     noreturn_p)
       const char *builtin_name;
       const char *name;
       tree builtin_type;
*************** builtin_function_2 (builtin_name, name,
*** 2777,2782 ****
--- 2782,2789 ----
       enum built_in_class class;
       int library_name_p;
       int nonansi_p;
+      int pure_p;
+      int const_p;
       int noreturn_p;
  {
    tree bdecl = NULL_TREE;
*************** builtin_function_2 (builtin_name, name,
*** 2790,2795 ****
--- 2797,2806 ----
  	  TREE_THIS_VOLATILE (bdecl) = 1;
  	  TREE_SIDE_EFFECTS (bdecl) = 1;
  	}
+       if (pure_p)
+         DECL_IS_PURE (bdecl) = 1;
+       if (const_p)
+         TREE_READONLY (bdecl) = 1;
      }
    if (name != 0 && !flag_no_builtin && !builtin_function_disabled_p (name)
        && !(nonansi_p && flag_no_nonansi_builtin))
*************** builtin_function_2 (builtin_name, name,
*** 2802,2807 ****
--- 2813,2822 ----
  	  TREE_THIS_VOLATILE (decl) = 1;
  	  TREE_SIDE_EFFECTS (decl) = 1;
  	}
+       if (pure_p)
+         DECL_IS_PURE (decl) = 1;
+       if (const_p)
+         TREE_READONLY (decl) = 1;
      }
    return (bdecl != 0 ? bdecl : decl);
  }
diff -c3pr gcc/gcc/tree.h patch2/gcc/tree.h
*** gcc/gcc/tree.h	Fri Nov 23 10:56:25 2001
--- patch2/gcc/tree.h	Fri Nov 23 17:35:19 2001
*************** extern const char *const built_in_class_
*** 80,86 ****
  /* Codes that identify the various built in functions
     so that expand_call can identify them quickly.  */

! #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA) ENUM,
  enum built_in_function
  {
  #include "builtins.def"
--- 80,86 ----
  /* Codes that identify the various built in functions
     so that expand_call can identify them quickly.  */

! #define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, P, CO) ENUM,
  enum built_in_function
  {
  #include "builtins.def"


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-438-3470



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]