This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: new __builtin_choose_type (patch) (new builtin_equal_typespatch)
- To: Magnus Fromreide <magfr at lysator dot liu dot se>
- Subject: Re: new __builtin_choose_type (patch) (new builtin_equal_typespatch)
- From: Aldy Hernandez <aldyh at redhat dot com>
- Date: 03 Oct 2001 23:19:45 -0400
- Cc: gcc at gcc dot gnu dot org
- References: <Pine.GSO.4.33.0110031005590.27827-100000@proton.lysator.liu.se>
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: