This is the mail archive of the gcc@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]

Re: new __builtin_choose_type (patch) (new builtin_equal_typespatch)


On Wed, 2001-10-03 at 04:15, Magnus Fromreide wrote:
> It is my feeling that it would be more general and cleaner to do something
> along the lines of
> 
> _Bool __builtin_equal_types(arg|type, arg|type)
> 
> that doesn't evaluate the arguments if they are expressions and answers
> the question of wether they are of the same type.
> 
> Usage examples:
> 
> __builtin_equal_types(x, y) ? no() : x = 10;
> if(__builtin_equal_types(x, y))
>   {
>   }
> else
>   {
>   }

thought about it.  like it.  nice and clean.

is everyone ok with this approach?  it's pretty.  it's got
documentation.  it's got a test case. :)

patch below.

-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a Motorcycle
Red Hat, Inc.

2001-10-03  Aldy Hernandez  <aldyh@redhat.com>

        * doc/extend.texi (__builtin_equal_types): New.

        * gcc.c-torture/execute/builtin-equal-types.c: New test.

	* builtins.c (expand_builtin_equal_types): New.
	(expand_builtin): Add case for BUILT_IN_EQUAL_TYPES.

        * builtins.def (BUILT_IN_EQUAL_TYPES): New.
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/doc/extend.texi,v
retrieving revision 1.27
diff -c -r1.27 extend.texi
*** extend.texi	2001/10/02 23:15:55	1.27
--- extend.texi	2001/10/04 03:15:42
***************
*** 4342,4347 ****
--- 4342,4375 ----
  prefixed.  We intend for a library implementor to be able to simply
  @code{#define} each standard macro to its built-in equivalent.
  
+ @deftypefn {Built-in Function} __builtin_equal_types (@var{exp0},
+ @var{exp1})
+ 
+ You can use the builtin function @code{__builtin_equal_types} to
+ determine whether two expressions have the same type.  This builtin
+ compares the types of EXP1 and EXP2 (without evaluating them) and
+ returns 1 if the types are the same.  Otherwise, 0 is returned.
+ 
+ @code{__builtin_equal_types} ignores the values of EXP0 and EXP1,
+ considering only their data type.
+ 
+ You would typically use this function for code whose execution varies
+ depending on the arguments' types.  For example:
+ 
+ @smallexample
+           #define atan(X)                                               	\
+                       ({float f;                                                \
+                         __complex double cd;		                        \
+                         __builtin_equal_types (X, cd)				\
+                           ? atan_complex_double (X)				\
+                           : __builtin_equal_types (X, f)			\
+                           ? atan_float (X)					\
+                           /* Assume or convert to double.  */			\
+                           : atan_double ((double) X); })
+ @end smallexample
+ 
+ @end deftypefn
+ 
  @deftypefn {Built-in Function} int __builtin_constant_p (@var{exp})
  You can use the built-in function @code{__builtin_constant_p} to
  determine if a value is known to be constant at compile-time and hence
Index: testsuite/gcc.c-torture/execute/builtin-equal-types.c
===================================================================
RCS file: builtin-equal-types.c
diff -N builtin-equal-types.c
*** /dev/null	Tue May  5 13:32:27 1998
--- builtin-equal-types.c	Wed Oct  3 20:15:42 2001
***************
*** 0 ****
--- 1,27 ----
+ int b, i;
+ float f, g;
+ double d;
+ 
+ no()
+ {
+   exit(1);
+ }
+ 
+ main()
+ {
+   int j;
+ 
+   if (!__builtin_equal_types (i, b))
+     exit (1);
+ 
+   if (!__builtin_equal_types (f, g))
+     exit (1);
+ 
+   if (__builtin_equal_types (f, d))
+     exit (1);
+ 
+   if (__builtin_equal_types (b, f))
+     exit (1);
+ 
+   exit (0);
+ }
Index: builtins.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/builtins.def,v
retrieving revision 1.22
diff -c -r1.22 builtins.def
*** builtins.def	2001/08/22 14:34:42	1.22
--- builtins.def	2001/10/04 03:15:44
***************
*** 336,341 ****
--- 336,344 ----
  DEF_GCC_BUILTIN(BUILT_IN_TRAP,
  		"__builtin_trap",
  		BT_FN_VOID)
+ DEF_GCC_BUILTIN(BUILT_IN_EQUAL_TYPES,
+ 		"__builtin_equal_types", 
+ 		BT_FN_INT_VAR)
  
  /* Stdio builtins.  */
  DEF_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR,
Index: builtins.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/builtins.c,v
retrieving revision 1.121
diff -c -r1.121 builtins.c
*** builtins.c	2001/09/22 08:42:00	1.121
--- builtins.c	2001/10/04 03:15:56
***************
*** 95,100 ****
--- 95,101 ----
  static rtx expand_builtin_classify_type	PARAMS ((tree));
  static rtx expand_builtin_mathfn	PARAMS ((tree, rtx, rtx));
  static rtx expand_builtin_constant_p	PARAMS ((tree));
+ static rtx expand_builtin_equal_types	PARAMS ((tree, rtx));
  static rtx expand_builtin_args_info	PARAMS ((tree));
  static rtx expand_builtin_next_arg	PARAMS ((tree));
  static rtx expand_builtin_va_start	PARAMS ((int, tree));
***************
*** 1316,1321 ****
--- 1317,1369 ----
    return tmp;
  }
  
+ /* Expand expression EXP, which is a call to __builtin_equal_types.
+ 
+    __builtin_equal_types (<exp0>, <exp1>)
+ 
+    If the types of <exp0> and <exp1> are the same, return 1, else return 0.
+ */
+ 
+ static rtx
+ expand_builtin_equal_types (exp, target)
+      tree exp;
+      rtx target;
+ {
+   tree arg = TREE_OPERAND (exp, 1);
+   tree chain;
+   enum machine_mode exp0_mode, exp1_mode;
+ 
+   if (!arg)
+     return const0_rtx;
+ 
+   chain = TREE_CHAIN (arg);
+   arg = TREE_VALUE (arg);
+ 
+   /* Strip off all NOPs.  */
+   while (TREE_CODE (arg) == NOP_EXPR
+ 	 || TREE_CODE (arg) == CONVERT_EXPR
+ 	 || TREE_CODE (arg) == NON_LVALUE_EXPR
+ 	 || TREE_CODE (arg) == INDIRECT_REF)
+     arg = TREE_OPERAND (arg, 0);
+ 
+   /* Get <exp0> type.  */
+   exp0_mode = TYPE_MODE (TREE_TYPE (arg));
+ 
+   /* Get <exp1> type.  */
+   arg = TREE_VALUE (chain);
+   if (!arg)
+     error ("missing argument in `__builtin_equal_types'");
+   /* Strip off all NOPs.  */
+   while (TREE_CODE (arg) == NOP_EXPR
+ 	 || TREE_CODE (arg) == CONVERT_EXPR
+ 	 || TREE_CODE (arg) == NON_LVALUE_EXPR
+ 	 || TREE_CODE (arg) == INDIRECT_REF)
+     arg = TREE_OPERAND (arg, 0);
+   exp1_mode = TYPE_MODE (TREE_TYPE (arg));
+ 
+   return exp0_mode == exp1_mode ? const1_rtx : const0_rtx;
+ }
+ 
  /* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
     Return 0 if a normal call should be emitted rather than expanding the
     function in-line.  EXP is the expression that is a call to the builtin
***************
*** 3512,3517 ****
--- 3560,3568 ----
  
      case BUILT_IN_CONSTANT_P:
        return expand_builtin_constant_p (exp);
+ 
+     case BUILT_IN_EQUAL_TYPES:
+       return expand_builtin_equal_types (exp, target);
  
      case BUILT_IN_FRAME_ADDRESS:
      case BUILT_IN_RETURN_ADDRESS:


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