public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: new __builtin_choose_type (patch)
@ 2001-10-02 12:03 dewar
  2001-10-02 12:29 ` Dale Johannesen
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: dewar @ 2001-10-02 12:03 UTC (permalink / raw)
  To: aldyh, gcc

This seems a bit of a kludgy feature to me. Do we really need to add
overloading to C for this purpose? If so, surely it should be done
in a manner that is coherent with the rest of the language.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:03 new __builtin_choose_type (patch) dewar
@ 2001-10-02 12:29 ` Dale Johannesen
  2001-10-02 12:58   ` Phil Edwards
  2001-10-02 14:36   ` Aldy Hernandez
  2001-10-02 13:25 ` Geoff Keating
  2001-10-02 14:23 ` Aldy Hernandez
  2 siblings, 2 replies; 25+ messages in thread
From: Dale Johannesen @ 2001-10-02 12:29 UTC (permalink / raw)
  To: dewar; +Cc: Dale Johannesen, aldyh, gcc

On Tuesday, October 2, 2001, at 12:02 PM, dewar@gnat.com wrote:

> This seems a bit of a kludgy feature to me. Do we really need to add
> overloading to C for this purpose? If so, surely it should be done
> in a manner that is coherent with the rest of the language.

Well, the Altivec extensions require overloading, but this doesn't
necessarily have to be visible to everybody else.  Motorola's approach
(also used by Apple, at least for now) was to define a hook for
target-dependent builtins, so the overloading stuff could be hidden
down in rs6000.c.  OTOH, overloading is in C99 already for the math lib
functions, isn't it?  Personally I don't think overloading belongs in C,
but if we're stuck with it anyway, maybe a general mechanism is a good
idea.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:29 ` Dale Johannesen
@ 2001-10-02 12:58   ` Phil Edwards
  2001-10-02 14:38     ` Aldy Hernandez
  2001-10-02 14:36   ` Aldy Hernandez
  1 sibling, 1 reply; 25+ messages in thread
From: Phil Edwards @ 2001-10-02 12:58 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: dewar, aldyh, gcc

On Tue, Oct 02, 2001 at 12:29:35PM -0700, Dale Johannesen wrote:
> OTOH, overloading is in C99 already for the math lib
> functions, isn't it?

I don't believe so.


Phil

-- 
If ye love wealth greater than liberty, the tranquility of servitude greater
than the animating contest for freedom, go home and leave us in peace.  We seek
not your counsel, nor your arms.  Crouch down and lick the hand that feeds you;
and may posterity forget that ye were our countrymen.            - Samuel Adams

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:03 new __builtin_choose_type (patch) dewar
  2001-10-02 12:29 ` Dale Johannesen
@ 2001-10-02 13:25 ` Geoff Keating
  2001-10-02 13:59   ` Stan Shebs
  2001-10-02 14:23 ` Aldy Hernandez
  2 siblings, 1 reply; 25+ messages in thread
From: Geoff Keating @ 2001-10-02 13:25 UTC (permalink / raw)
  To: dewar; +Cc: gcc

dewar@gnat.com writes:

> This seems a bit of a kludgy feature to me. Do we really need to add
> overloading to C for this purpose? If so, surely it should be done
> in a manner that is coherent with the rest of the language.

We don't absolutely have to add overloading to C to make <tgmath.h>
and the altivec stuff work---it appears to work now---but it's
terribly horribly ugly.  <tgmath.h> works like this:

# define __TGMATH_TERNARY_REAL_ONLY(Val1, Val2, Val3, Fct) \
     (__extension__ ({ __tgmath_real_type ((Val1) + (Val2) + (Val3)) __tgmres;\
		       if ((sizeof (Val1) > sizeof (double)		      \
			    || sizeof (Val2) > sizeof (double)		      \
			    || sizeof (Val3) > sizeof (double))		      \
			   && __builtin_classify_type ((Val1) + (Val2)	      \
						       + (Val3)) == 8)	      \
			 __tgmres = __tgml(Fct) (Val1, Val2, Val3);	      \
		       else if (sizeof (Val1) == sizeof (double)	      \
				|| sizeof (Val2) == sizeof (double)	      \
				|| sizeof (Val3) == sizeof (double)	      \
				|| __builtin_classify_type (Val1) != 8	      \
				|| __builtin_classify_type (Val2) != 8	      \
				|| __builtin_classify_type (Val3) != 8)	      \
			 __tgmres = Fct (Val1, Val2, Val3);		      \
		       else						      \
			 __tgmres = Fct##f (Val1, Val2, Val3);		      \
		       __tgmres; }))

and frankly, I think it'd be worth one more builtin to make this
code more obvious.

-- 
- Geoffrey Keating <geoffk@geoffk.org>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 13:25 ` Geoff Keating
@ 2001-10-02 13:59   ` Stan Shebs
  0 siblings, 0 replies; 25+ messages in thread
From: Stan Shebs @ 2001-10-02 13:59 UTC (permalink / raw)
  To: Geoff Keating; +Cc: dewar, gcc

Geoff Keating wrote:
> 
>                                 || __builtin_classify_type (Val1) != 8        \

These are especially comical, because the "8" is really supposed to
be "real_type_class" from gcc/typeclass.h, but then if you look at
typeclass.h and imagine people trying to use it for anything, well
it's ROTFL time.

With a __builtin_choose_type, we can flush __builtin_classify_type
and its attendant junk (including an AltiVec change, thus bringing
things full circle :-) ).

Stan

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:03 new __builtin_choose_type (patch) dewar
  2001-10-02 12:29 ` Dale Johannesen
  2001-10-02 13:25 ` Geoff Keating
@ 2001-10-02 14:23 ` Aldy Hernandez
  2 siblings, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 14:23 UTC (permalink / raw)
  To: dewar; +Cc: gcc

On Tue, 2001-10-02 at 15:02, dewar@gnat.com wrote:
> This seems a bit of a kludgy feature to me. Do we really need to add
> overloading to C for this purpose? If so, surely it should be done
> in a manner that is coherent with the rest of the language.

yes it is kludgy.  can you think of a better way-- preferably one that
won't take weeks and weeks to implement?

the way i have it, we can add this builtin and then put the rest of the
nasty stuff in the <altivec.h> include file which can/will be required
anyhow.

aldy

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:29 ` Dale Johannesen
  2001-10-02 12:58   ` Phil Edwards
@ 2001-10-02 14:36   ` Aldy Hernandez
  1 sibling, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 14:36 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: dewar, gcc

On Tue, 2001-10-02 at 15:29, Dale Johannesen wrote:
> 
> On Tuesday, October 2, 2001, at 12:02 PM, dewar@gnat.com wrote:
> 
> > This seems a bit of a kludgy feature to me. Do we really need to add
> > overloading to C for this purpose? If so, surely it should be done
> > in a manner that is coherent with the rest of the language.
> 
> Well, the Altivec extensions require overloading, but this doesn't
> necessarily have to be visible to everybody else.  Motorola's approach
> (also used by Apple, at least for now) was to define a hook for
> target-dependent builtins, so the overloading stuff could be hidden

are these hooks in the middle/front end?  last i heard apple/motorola
were doing all sorts of crazy stuff modifying a myraid of files NOT in
config/rs6000/.  if so, i like that approach even less.

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:58   ` Phil Edwards
@ 2001-10-02 14:38     ` Aldy Hernandez
  0 siblings, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 14:38 UTC (permalink / raw)
  To: Phil Edwards; +Cc: Dale Johannesen, dewar, gcc

On Tue, 2001-10-02 at 15:57, Phil Edwards wrote:
> On Tue, Oct 02, 2001 at 12:29:35PM -0700, Dale Johannesen wrote:
> > OTOH, overloading is in C99 already for the math lib
> > functions, isn't it?

nope.  tgmath.h, compliments of geoff:

    /* This is ugly but unless gcc gets appropriate builtins we have to do
       something like this.  Don't ask how it works.  */
    
    /* 1 if 'type' is a floating type, 0 if 'type' is an integer type.
       Allows for _Bool.  Expands to an integer constant expression.  */
    # define __floating_type(type) (((type) 0.25) && ((type) 0.25 - 1))
    
    /* The tgmath real type for T, where E is 0 if T is an integer type and
       1 for a floating type.  */
    # define __tgmath_real_type_sub(T, E) \
      __typeof__(*(0 ? (__typeof__ (0 ? (double *) 0 : (void *) (E))) 0           \
                     : (__typeof__ (0 ? (T *) 0 : (void *) (!(E)))) 0))
    
with my proposed builtin_choose_type we could simplify this a lot.
    
> 
> I don't believe so.
> 
> 
> Phil
> 
> -- 
> If ye love wealth greater than liberty, the tranquility of servitude greater
> than the animating contest for freedom, go home and leave us in peace.  We seek
> not your counsel, nor your arms.  Crouch down and lick the hand that feeds you;
> and may posterity forget that ye were our countrymen.            - Samuel Adams
-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a Motorcycle
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-03 20:13           ` Aldy Hernandez
@ 2001-10-05 15:55             ` Richard Henderson
  0 siblings, 0 replies; 25+ messages in thread
From: Richard Henderson @ 2001-10-05 15:55 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Daniel Jacobowitz, gcc

On Wed, Oct 03, 2001 at 11:16:10PM -0400, Aldy Hernandez wrote:
> the builtin_equal_types() approach is simpler in my opinion
> (implementation wise).

How is that?  Magnus' original proposal was 

  _Bool __builtin_equal_types(arg | type, arg | type)

You can't have a type name (like "int" or "float") without
playing with grammar rules.

Further, there is a usability question.  Which is cleaner?

#define foo(x, y)					\
  ({							\
     __typeof(x + y) tmp = x*x + y*y;			\
     if (__builtin_equal_types(tmp, float))		\
       tmp = sqrtf(tmp);				\
     else if (__builtin_equal_types(tmp, double))	\
       tmp = sqrt(tmp);					\
     else if (__builtin_equal_types(tmp, long double))	\
       tmp = sqrtl(tmp);				\
     else						\
       abort();						\
     tmp;						\
  })

#define foo(x, y)						\
  __builtin_choose_type(x+y, float, sqrtf(x*x + y*y),		\
    __builtin_choose_type(x+y, double, sqrt(x*x + y*y),		\
      __builtin_choose_type(x+y, long double, sqrtl(x*x + y+y),	\
	/* The void expression results in a compile-time error	\
	   when assigning the result to something.  */		\
	(void)0)))

Hmm.  This isn't the best example because of "x*x" doing multiple
evaluations of x, but you get the idea -- with equal_types we must
use a statement expression, but we needn't with choose_type.  Plus
there's the issue of using a type that doesn't match.

On to the "does the type match" issue.  Does 'char*' match 'const char *',
or need it be an exact match?  I can see arguments either way.


r~

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-03  9:16         ` Andreas Schwab
@ 2001-10-03 20:16           ` Aldy Hernandez
  0 siblings, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-03 20:16 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Magnus Fromreide, gcc

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

On Wed, 2001-10-03 at 12:16, Andreas Schwab wrote:
> Aldy Hernandez <aldyh@redhat.com> writes:
> 
> |> > Usage examples:
> |> > 
> |> > __builtin_equal_types(x, y) ? no() : x = 10;
> |> > if(__builtin_equal_types(x, y))
> |> >   {
> |> >   }
> |> > else
> |> >   {
> |> >   }
> |> 
> |> then we'd have to generate:
> |> 
> |>    if (const)
> |>      {
> |>      }
> |>      etc
> |> 
> |> whereas with my approach, you wouldn't even have to generate a compare.
> 
> ??? The compiler will just optimize that comparison away.

was just trying to save the compiler some work.  but fear not my next
post has builtin_equal_types implemented :)

> 
> Andreas.
> 
> -- 
> Andreas Schwab                                  "And now for something
> Andreas.Schwab@suse.de				completely different."
> SuSE Labs, SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg
> Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a Motorcycle
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-03 12:41         ` Daniel Jacobowitz
@ 2001-10-03 20:13           ` Aldy Hernandez
  2001-10-05 15:55             ` Richard Henderson
  0 siblings, 1 reply; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-03 20:13 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gcc

On Wed, 2001-10-03 at 15:42, Daniel Jacobowitz wrote:
> On Tue, Oct 02, 2001 at 11:15:14PM -0700, Richard Henderson wrote:
> > On Tue, Oct 02, 2001 at 06:54:04PM -0700, Geoff Keating wrote:
> > > What does va_arg do?
> > 
> > va_arg is a grammar element rather than a builtin:
> > 
> >         | VA_ARG '(' expr_no_commas ',' typename ')'
> >                 { $$ = build_va_arg ($3, groktypename ($5)); }
> > 
> > That's not to say that we can't do the same thing here... ;-)
> 
> ... not to mention, if we make __builtin_choose_type into a grammar
> element, we could make its second argument into a -type-, rather than
> an unintuitive dummy variable.
> 

hmmmm, hadn't thought about that.  good point.

i'm kind of a fan of Magnus' suggestion though-- but mainly because i
already implemented it :) and because my last approach turned out to be
horrendous after i got it coded "correctly".

the builtin_equal_types() approach is simpler in my opinion
(implementation wise).

> -- 
> Daniel Jacobowitz                           Carnegie Mellon University
> MontaVista Software                         Debian GNU/Linux Developer
-- 
Aldy Hernandez					E-mail: aldyh@redhat.com
Professional Gypsy on a Motorcycle
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 23:15       ` Richard Henderson
@ 2001-10-03 12:41         ` Daniel Jacobowitz
  2001-10-03 20:13           ` Aldy Hernandez
  0 siblings, 1 reply; 25+ messages in thread
From: Daniel Jacobowitz @ 2001-10-03 12:41 UTC (permalink / raw)
  To: Aldy Hernandez, gcc

On Tue, Oct 02, 2001 at 11:15:14PM -0700, Richard Henderson wrote:
> On Tue, Oct 02, 2001 at 06:54:04PM -0700, Geoff Keating wrote:
> > What does va_arg do?
> 
> va_arg is a grammar element rather than a builtin:
> 
>         | VA_ARG '(' expr_no_commas ',' typename ')'
>                 { $$ = build_va_arg ($3, groktypename ($5)); }
> 
> That's not to say that we can't do the same thing here... ;-)

... not to mention, if we make __builtin_choose_type into a grammar
element, we could make its second argument into a -type-, rather than
an unintuitive dummy variable.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-03  9:06       ` Aldy Hernandez
@ 2001-10-03  9:16         ` Andreas Schwab
  2001-10-03 20:16           ` Aldy Hernandez
  0 siblings, 1 reply; 25+ messages in thread
From: Andreas Schwab @ 2001-10-03  9:16 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: Magnus Fromreide, gcc

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 698 bytes --]

Aldy Hernandez <aldyh@redhat.com> writes:

|> > Usage examples:
|> > 
|> > __builtin_equal_types(x, y) ? no() : x = 10;
|> > if(__builtin_equal_types(x, y))
|> >   {
|> >   }
|> > else
|> >   {
|> >   }
|> 
|> then we'd have to generate:
|> 
|>    if (const)
|>      {
|>      }
|>      etc
|> 
|> whereas with my approach, you wouldn't even have to generate a compare.

??? The compiler will just optimize that comparison away.

Andreas.

-- 
Andreas Schwab                                  "And now for something
Andreas.Schwab@suse.de				completely different."
SuSE Labs, SuSE GmbH, Schanzäckerstr. 10, D-90443 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-03  1:15     ` Magnus Fromreide
@ 2001-10-03  9:06       ` Aldy Hernandez
  2001-10-03  9:16         ` Andreas Schwab
  0 siblings, 1 reply; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-03  9:06 UTC (permalink / raw)
  To: Magnus Fromreide; +Cc: gcc

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.
> 

yeah, but i was hoping the calculations could all be done before code
generation.

> Usage examples:
> 
> __builtin_equal_types(x, y) ? no() : x = 10;
> if(__builtin_equal_types(x, y))
>   {
>   }
> else
>   {
>   }

then we'd have to generate:

   if (const)
     {
     }
     etc

whereas with my approach, you wouldn't even have to generate a compare.

> 
> The part i react most against is that it implements a new code path
> selection mechanism that is unlike all previously seen in C.

exactly.

but your approach sounds much simpler though.  i'm going to add some new
functionality to builtins to get my stuff to work.

patch later today...


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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 18:35     ` Geoff Keating
  2001-10-02 23:15       ` Richard Henderson
@ 2001-10-03  8:55       ` Aldy Hernandez
  1 sibling, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-03  8:55 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc

On Tue, 2001-10-02 at 21:54, Geoff Keating wrote:
> Aldy Hernandez <aldyh@redhat.com> writes:
> 
> > btw, i can't get my builtin to return a given object (irregardless of
> > it's type) because the way builtins work seems to force me to choose a
> > return value type.  i don't want a specific value type.  i want
> > something generic.  see code documentation below.
> 
> What does va_arg do?

__builtin_next_arg returns a pointer to the next argument, obviously
only working on stack arguments.

if we were to follow a similar approach (have the builtin return a void
pointer), we could do:

    float floatt;
    float  f1, f2, f3;
    
    f2 = *((float *)__builtin_choose_type (f1, floatt, f3, etc)
    
    /* f1 and floatt are of the same type, so eval and return f3 */
    
in theory, the builtin would return the address of "f3" as a void*.  we
could then cast that to the appropriate type.  However, this will only
work with lvalues (since they're the only ones with addresses :-)).  and
will definitely not work with "f3" being a function call.

perhaps, the whole builtin mechanism needs to be hacked for it to return
anonymous types.

IMO, this builtin return type needs to be calculated before
expand_builtin().  we could put in a hook when we're calling the builtin
to calculate and set the appropriate return type.  this way the rest of
the FE can do proper type checking.

ok, so it sounds a bit complicated, but it's pretty clear in my head
:).  i'll come up with a patch to demonstrate  later today.  but if
anyone has a better idea on how to implement anonymous return types in
builtins, feel free to chime in.

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 18:06   ` Aldy Hernandez
  2001-10-02 18:35     ` Geoff Keating
  2001-10-03  1:15     ` Magnus Fromreide
@ 2001-10-03  2:20     ` Joseph S. Myers
  2 siblings, 0 replies; 25+ messages in thread
From: Joseph S. Myers @ 2001-10-03  2:20 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc

On 2 Oct 2001, Aldy Hernandez wrote:

> btw, i can't get my builtin to return a given object (irregardless of
> it's type) because the way builtins work seems to force me to choose a
> return value type.  i don't want a specific value type.  i want
> something generic.  see code documentation below.

That's why overloaded builtins need actual new mechanism in the compiler
(to do overload resolution for builtins sufficiently early), not simply
another builtin like this using existing mechanisms.

> +   /* 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));

This looks to me like one of the problems with the current approach -
since explicit casts should be preserved in computing the types, but
implicit conversions from the default argument promotions (which shouldn't
get applied with proper overloaded builtins, but would at present)  
shouldn't be preserved.

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 18:06   ` Aldy Hernandez
  2001-10-02 18:35     ` Geoff Keating
@ 2001-10-03  1:15     ` Magnus Fromreide
  2001-10-03  9:06       ` Aldy Hernandez
  2001-10-03  2:20     ` Joseph S. Myers
  2 siblings, 1 reply; 25+ messages in thread
From: Magnus Fromreide @ 2001-10-03  1:15 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc

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
  {
  }

The part i react most against is that it implements a new code path
selection mechanism that is unlike all previously seen in C.

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 18:35     ` Geoff Keating
@ 2001-10-02 23:15       ` Richard Henderson
  2001-10-03 12:41         ` Daniel Jacobowitz
  2001-10-03  8:55       ` Aldy Hernandez
  1 sibling, 1 reply; 25+ messages in thread
From: Richard Henderson @ 2001-10-02 23:15 UTC (permalink / raw)
  To: Geoff Keating; +Cc: Aldy Hernandez, gcc

On Tue, Oct 02, 2001 at 06:54:04PM -0700, Geoff Keating wrote:
> What does va_arg do?

va_arg is a grammar element rather than a builtin:

        | VA_ARG '(' expr_no_commas ',' typename ')'
                { $$ = build_va_arg ($3, groktypename ($5)); }

That's not to say that we can't do the same thing here... ;-)


r~

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 18:06   ` Aldy Hernandez
@ 2001-10-02 18:35     ` Geoff Keating
  2001-10-02 23:15       ` Richard Henderson
  2001-10-03  8:55       ` Aldy Hernandez
  2001-10-03  1:15     ` Magnus Fromreide
  2001-10-03  2:20     ` Joseph S. Myers
  2 siblings, 2 replies; 25+ messages in thread
From: Geoff Keating @ 2001-10-02 18:35 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc

Aldy Hernandez <aldyh@redhat.com> writes:

> btw, i can't get my builtin to return a given object (irregardless of
> it's type) because the way builtins work seems to force me to choose a
> return value type.  i don't want a specific value type.  i want
> something generic.  see code documentation below.

What does va_arg do?

-- 
- Geoffrey Keating <geoffk@geoffk.org>

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:04 ` Joseph S. Myers
  2001-10-02 14:34   ` Aldy Hernandez
@ 2001-10-02 18:06   ` Aldy Hernandez
  2001-10-02 18:35     ` Geoff Keating
                       ` (2 more replies)
  1 sibling, 3 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 18:06 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

> Since your patch doesn't add documentation or testcases, I don't know what
> it really intends.  In a case like this, the documentation and the

i started writing docs for the builtin and noticed that yes, you're
right:  docs and test cases do make it clearer.

so here is the patch, the doc, and the testcase.

i hope it's clear why this approach is better than the <tgmath.h>
atrocity. ;-)

btw, i can't get my builtin to return a given object (irregardless of
it's type) because the way builtins work seems to force me to choose a
return value type.  i don't want a specific value type.  i want
something generic.  see code documentation below.

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

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/03 00:59:16
***************
*** 4342,4347 ****
--- 4342,4372 ----
  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_choose_type (@var{object1},
+ @var{object2}, @var{exp1}, @var{exp2})
+ You can use the builtin function @code{__builtin_choose_type} to execute
+ code, depending on its type.  This builtin compares the types of OBJECT1
+ and OBJECT2 (without evaluating them) and executes EXP1 if their types
+ are the same.  Otherwise, EXP2 is executed.
+ 
+ @code{__builtin_choose_type} ignores the values of OBJECT1 and OBJECT2,
+ considering only their data type.  This returns either exp1 or exp2.
+ 
+ You would typically use this function on code whose execution varies
+ depending on the arguments' types.  For example:
+ 
+ @smallexample
+           #define atan(X)                                               	\
+                       ({float f;                                                \
+                         __complex double cd;                                    \
+                         __builtin_choose_type (X, cd, atan_complex_double (X),  \
+                           __builtin_choose_type (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: 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/03 00:59:17
***************
*** 336,341 ****
--- 336,344 ----
  DEF_GCC_BUILTIN(BUILT_IN_TRAP,
  		"__builtin_trap",
  		BT_FN_VOID)
+ DEF_GCC_BUILTIN(BUILT_IN_CHOOSE_TYPE,
+ 		"__builtin_choose_type", 
+ 		BT_FN_PTR_VAR)
  
  /* Stdio builtins.  */
  DEF_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR,

Index: testsuite/gcc.c-torture/execute/builtin-choose-type.c
====================================================================
new file
--- testsuite/gcc.c-torture/execute/builtin-choose-type.c
***************
*** 0 ****
--- 1,24 ----
+ int b, i;
+ float f;
+ double d;
+ 
+ no()
+ {
+   exit(1);
+ }
+ 
+ main()
+ {
+   int j;
+ 
+   __builtin_choose_type (f, d, no(), 1);
+   __builtin_choose_type (d, (double)3.0F, 1, no());
+   __builtin_choose_type (b, i, 1, no());
+ 
+   __builtin_choose_type (i, d, no(), j = 45);
+ 
+   if (j != 45)
+     exit(1);
+ 
+   exit(0);
+ }
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/03 00:59:31
***************
*** 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_choose_type	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,1384 ----
    return tmp;
  }
  
+ /* Expand expression EXP, which is a call to __builtin_choose_type.
+ 
+    __builtin_type_choose (<exp0>, <type>, <exp1>, <exp2>)
+ 
+    If <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.
+ */
+ 
+ static rtx
+ expand_builtin_choose_type (exp, target)
+      tree exp;
+      rtx target;
+ {
+   tree arg = TREE_OPERAND (exp, 1);
+   tree chain;
+   enum machine_mode exp0_mode, desired_mode;
+ 
+   if (arg == 0)
+     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 <type> type.  */
+   arg = TREE_VALUE (chain);
+   if (!arg)
+     return const0_rtx;
+   /* 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);
+   desired_mode = TYPE_MODE (TREE_TYPE (arg));
+ 
+   /* Get exp1.  */
+   chain = TREE_CHAIN (chain);
+   if (!chain)
+     error ("missing argument in `__builtin_choose_type'");
+ 
+   if (exp0_mode == desired_mode)
+     /* Evaluate exp1.  */
+     return expand_expr (TREE_VALUE (chain), target, VOIDmode, EXPAND_NORMAL);
+   
+   /* Get exp2.  */
+   chain = TREE_CHAIN (chain);
+   if (!chain)
+     error ("missing argument in `__builtin_choose_type'");
+ 
+   /* Evaluate exp2.  */
+   return expand_expr (TREE_VALUE (chain), target, VOIDmode, EXPAND_NORMAL);
+ }
+ 
  /* 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 ****
--- 3575,3583 ----
  
      case BUILT_IN_CONSTANT_P:
        return expand_builtin_constant_p (exp);
+ 
+     case BUILT_IN_CHOOSE_TYPE:
+       return expand_builtin_choose_type (exp, target);
  
      case BUILT_IN_FRAME_ADDRESS:
      case BUILT_IN_RETURN_ADDRESS:

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 14:22 mike stump
@ 2001-10-02 14:39 ` Aldy Hernandez
  0 siblings, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 14:39 UTC (permalink / raw)
  To: mike stump; +Cc: gcc

On Tue, 2001-10-02 at 17:21, mike stump wrote:
> > From: Aldy Hernandez <aldyh@redhat.com>
> > To: gcc@gcc.gnu.org
> > Date: 02 Oct 2001 14:39:09 -0400
> 
> > for the altivec enhancements, we need a way to overload functions in C.
> 
> > for example:
> 
> > 	vec_add(foo, bar)
> 
> You know, with 3 more features, you'll have C++.

yes i know.  i really hate motorola's altivec draft.  the front end
changes are abismal.

i'm just trying to look for a "not as kludgy" way of doing things. 
pretty much anything we do is going to look a little messy.  i just
wanted to keep the mess to a mininmum and perhaps come up with something
that can be used for other things.

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 12:04 ` Joseph S. Myers
@ 2001-10-02 14:34   ` Aldy Hernandez
  2001-10-02 18:06   ` Aldy Hernandez
  1 sibling, 0 replies; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 14:34 UTC (permalink / raw)
  To: Joseph S. Myers; +Cc: gcc

On Tue, 2001-10-02 at 15:04, Joseph S. Myers wrote:
> On 2 Oct 2001, Aldy Hernandez wrote:
> 
> > it was suggested to have a builtin analogous to the ?: operator that
> > will work as follows:
> > 
> > 	__builtin_choose_type (exp0, type, exp1, exp2);
> > 
> > if <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.
> > 
> > i have a patch for this feature and i'd like some comments.
> 
> Since your patch doesn't add documentation or testcases, I don't know what
> it really intends.  In a case like this, the documentation and the

well i didn't add documentation or testcases because i didn't want to
code the entire thing, docs and all, and have everyone say-- "oh, that's
not the right approach".  that's what i posted info on what i wanted to
do.

example:

    int b;
    double a;
    float float_type;
    
    foo(){  
            __builtin_choose_type(a, float_type, b=8, b=10);
    }
    
in this case, b=10 is evaluated because the type of "a" (double) is not
the type of "float_type" (float).  the value of the entire
builtin_choose_type instruction is 10.

so, in pseudo code:

  typeof(a) == typeof(float_type) ? b=8 : b=10

b=8 is not evaluated at all.

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

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
@ 2001-10-02 14:22 mike stump
  2001-10-02 14:39 ` Aldy Hernandez
  0 siblings, 1 reply; 25+ messages in thread
From: mike stump @ 2001-10-02 14:22 UTC (permalink / raw)
  To: aldyh, gcc

> From: Aldy Hernandez <aldyh@redhat.com>
> To: gcc@gcc.gnu.org
> Date: 02 Oct 2001 14:39:09 -0400

> for the altivec enhancements, we need a way to overload functions in C.

> for example:

> 	vec_add(foo, bar)

You know, with 3 more features, you'll have C++.

:-)

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: new __builtin_choose_type (patch)
  2001-10-02 11:36 Aldy Hernandez
@ 2001-10-02 12:04 ` Joseph S. Myers
  2001-10-02 14:34   ` Aldy Hernandez
  2001-10-02 18:06   ` Aldy Hernandez
  0 siblings, 2 replies; 25+ messages in thread
From: Joseph S. Myers @ 2001-10-02 12:04 UTC (permalink / raw)
  To: Aldy Hernandez; +Cc: gcc

On 2 Oct 2001, Aldy Hernandez wrote:

> it was suggested to have a builtin analogous to the ?: operator that
> will work as follows:
> 
> 	__builtin_choose_type (exp0, type, exp1, exp2);
> 
> if <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.
> 
> i have a patch for this feature and i'd like some comments.

Since your patch doesn't add documentation or testcases, I don't know what
it really intends.  In a case like this, the documentation and the
testcases are more useful for people to comment on than the code patch,
and can usefully be written first.

What is the return type of the builtin?  What is the return value?  Do the
default argument promotions get applied to the arguments of it?  (Anything
that applies the default argument promotions is unsuitable for <tgmath.h>,
where float must be handled differently from double; whereas types such as
char which are subject to the integer promotions don't matter here.)

-- 
Joseph S. Myers
jsm28@cam.ac.uk

^ permalink raw reply	[flat|nested] 25+ messages in thread

* new __builtin_choose_type (patch)
@ 2001-10-02 11:36 Aldy Hernandez
  2001-10-02 12:04 ` Joseph S. Myers
  0 siblings, 1 reply; 25+ messages in thread
From: Aldy Hernandez @ 2001-10-02 11:36 UTC (permalink / raw)
  To: gcc

hi guys.

for the altivec enhancements, we need a way to overload functions in C.

for example:

	vec_add(foo, bar)

where foo and bar can be of a variety of vector types.  so if foo and
bar are of V4SF something happens, and if they are of type V2SI
something else happens.

it was suggested to have a builtin analogous to the ?: operator that
will work as follows:

	__builtin_choose_type (exp0, type, exp1, exp2);

if <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.

i have a patch for this feature and i'd like some comments.

in the example below, b=10 gets evaluated because float != double, and
the entire builtin's value is 10.

    int b;
    double a;
    float float_type;
    
    foo(){
            __builtin_choose_type(a, float_type, b=8, b=10);
    }
    
one problem i have with the patch below, is that if the first argument
is of type "char" it gets promoted to an "int" so there's no way to use
this builtin with a <char>.  it really doesn't matter since what i
really want is vector types, but i'd really like to get it working
across all types-- perhaps we can rewrite that <tgmath.h> crap with this
builtin ;-).

comment away.

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


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

        * builtins.c (expand_builtin_choose_type): New.
        (expand_builtin): Add case for BUILT_IN_CHOOSE_TYPE.

        * builtins.def (BUILT_IN_CHOOSE_TYPE): New.

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/02 18:34:22
***************
*** 336,341 ****
--- 336,344 ----
  DEF_GCC_BUILTIN(BUILT_IN_TRAP,
  		"__builtin_trap",
  		BT_FN_VOID)
+ DEF_GCC_BUILTIN(BUILT_IN_CHOOSE_TYPE,
+ 		"__builtin_choose_type", 
+ 		BT_FN_PTR_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/02 18:34:33
***************
*** 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_choose_type	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,1384 ----
    return tmp;
  }
  
+ /* Expand expression EXP, which is a call to __builtin_choose_type.
+ 
+    __builtin_type_choose (<exp0>, <type>, <exp1>, <exp2>)
+ 
+    If <exp0> is of type <type>, evaluate <exp1> else evaluate <exp2>.
+ */
+ 
+ static rtx
+ expand_builtin_choose_type (exp, target)
+      tree exp;
+      rtx target;
+ {
+   tree arg = TREE_OPERAND (exp, 1);
+   tree chain;
+   enum machine_mode exp0_mode, desired_mode;
+ 
+   if (arg == 0)
+     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 <type> type.  */
+   arg = TREE_VALUE (chain);
+   if (!arg)
+     return const0_rtx;
+   /* 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);
+   desired_mode = TYPE_MODE (TREE_TYPE (arg));
+ 
+   /* Get exp1.  */
+   chain = TREE_CHAIN (chain);
+   if (!chain)
+     error ("missing argument in `__builtin_choose_type'");
+ 
+   if (exp0_mode == desired_mode)
+     /* Evaluate exp1.  */
+     return expand_expr (TREE_VALUE (chain), target, VOIDmode, EXPAND_NORMAL);
+   
+   /* Get exp2.  */
+   chain = TREE_CHAIN (chain);
+   if (!chain)
+     error ("missing argument in `__builtin_choose_type'");
+ 
+   /* Evaluate exp2.  */
+   return expand_expr (TREE_VALUE (chain), target, VOIDmode, EXPAND_NORMAL);
+ }
+ 
  /* 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 ****
--- 3575,3583 ----
  
      case BUILT_IN_CONSTANT_P:
        return expand_builtin_constant_p (exp);
+ 
+     case BUILT_IN_CHOOSE_TYPE:
+       return expand_builtin_choose_type (exp, target);
  
      case BUILT_IN_FRAME_ADDRESS:
      case BUILT_IN_RETURN_ADDRESS:

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2001-10-05 15:55 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-10-02 12:03 new __builtin_choose_type (patch) dewar
2001-10-02 12:29 ` Dale Johannesen
2001-10-02 12:58   ` Phil Edwards
2001-10-02 14:38     ` Aldy Hernandez
2001-10-02 14:36   ` Aldy Hernandez
2001-10-02 13:25 ` Geoff Keating
2001-10-02 13:59   ` Stan Shebs
2001-10-02 14:23 ` Aldy Hernandez
  -- strict thread matches above, loose matches on Subject: below --
2001-10-02 14:22 mike stump
2001-10-02 14:39 ` Aldy Hernandez
2001-10-02 11:36 Aldy Hernandez
2001-10-02 12:04 ` Joseph S. Myers
2001-10-02 14:34   ` Aldy Hernandez
2001-10-02 18:06   ` Aldy Hernandez
2001-10-02 18:35     ` Geoff Keating
2001-10-02 23:15       ` Richard Henderson
2001-10-03 12:41         ` Daniel Jacobowitz
2001-10-03 20:13           ` Aldy Hernandez
2001-10-05 15:55             ` Richard Henderson
2001-10-03  8:55       ` Aldy Hernandez
2001-10-03  1:15     ` Magnus Fromreide
2001-10-03  9:06       ` Aldy Hernandez
2001-10-03  9:16         ` Andreas Schwab
2001-10-03 20:16           ` Aldy Hernandez
2001-10-03  2:20     ` Joseph S. Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).