Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-13 Thread Richard Biener
On Fri, 13 Jan 2017, Richard Biener wrote:

> On Fri, 13 Jan 2017, Jakub Jelinek wrote:
> 
> > On Fri, Jan 13, 2017 at 09:15:22AM +0100, Richard Biener wrote:
> > > > @@ -1710,6 +1716,24 @@ dump_generic_node (pretty_printer *pp, t
> > > >   print_hex (val, pp_buffer (pp)->digit_buffer);
> > > >   pp_string (pp, pp_buffer (pp)->digit_buffer);
> > > > }
> > > > +  if ((flags & TDF_GIMPLE)
> > > > + && (POINTER_TYPE_P (TREE_TYPE (node))
> > > > + || (TYPE_PRECISION (TREE_TYPE (node))
> > > > + < TYPE_PRECISION (integer_type_node))
> > > > + || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
> > > > +   {
> > > > + if (TYPE_UNSIGNED (TREE_TYPE (node)))
> > > > +   pp_character (pp, 'u');
> > > > + if (TYPE_PRECISION (TREE_TYPE (node))
> > > > + == TYPE_PRECISION (unsigned_type_node))
> > > > +   ;
> > > > + else if (TYPE_PRECISION (TREE_TYPE (node))
> > > > +  == TYPE_PRECISION (long_unsigned_type_node))
> > > > +   pp_character (pp, 'l');
> > > > + else if (TYPE_PRECISION (TREE_TYPE (node))
> > > > +  == TYPE_PRECISION (long_long_unsigned_type_node))
> > > > +   pp_string (pp, "ll");
> > > > +   }
> > 
> > Not sure if I understand this.  The outer if condition says that only the
> > sub-int or strange precision or pointer types do that, but then
> > you compare the precisions against long and long long.  That will be
> > true only for pointers.  Don't you want the u/l/ll/ul/ull suffixes emitted
> > for integers even when they have normal precision and _Literal is not used?
> > Or is that handled somewhere else?
> 
> Oops, you are right - it shouldn't be the same condition that controls
> whether to add _Literal (type).  It should be the inverse.  Maybe
> we need to add suffixes anyway even for say 61bit precision constants
> to avoid warnings from libcpp.
> 
> I'll fix it up after testing a few cases.

Fixed as follows, bootstrapped / tested on x86_64-unknown-linux-gnu
and committed with the GIMPLE_NOP parsing from the other patch.

Richard.

2017-01-13  Richard Biener  

* tree-pretty-print.c (dump_generic_node): Fix inverted condition
for dumping GIMPLE INTEGER_CSTs.

Index: gcc/tree-pretty-print.c
===
--- gcc/tree-pretty-print.c (revision 244393)
+++ gcc/tree-pretty-print.c (working copy)
@@ -1717,10 +1717,10 @@ dump_generic_node (pretty_printer *pp, t
  pp_string (pp, pp_buffer (pp)->digit_buffer);
}
   if ((flags & TDF_GIMPLE)
- && (POINTER_TYPE_P (TREE_TYPE (node))
- || (TYPE_PRECISION (TREE_TYPE (node))
- < TYPE_PRECISION (integer_type_node))
- || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
+ && ! (POINTER_TYPE_P (TREE_TYPE (node))
+   || (TYPE_PRECISION (TREE_TYPE (node))
+   < TYPE_PRECISION (integer_type_node))
+   || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
{
  if (TYPE_UNSIGNED (TREE_TYPE (node)))
pp_character (pp, 'u');


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-13 Thread Richard Biener
On Fri, 13 Jan 2017, Jakub Jelinek wrote:

> On Fri, Jan 13, 2017 at 09:15:22AM +0100, Richard Biener wrote:
> > > @@ -1710,6 +1716,24 @@ dump_generic_node (pretty_printer *pp, t
> > > print_hex (val, pp_buffer (pp)->digit_buffer);
> > > pp_string (pp, pp_buffer (pp)->digit_buffer);
> > >   }
> > > +  if ((flags & TDF_GIMPLE)
> > > +   && (POINTER_TYPE_P (TREE_TYPE (node))
> > > +   || (TYPE_PRECISION (TREE_TYPE (node))
> > > +   < TYPE_PRECISION (integer_type_node))
> > > +   || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
> > > + {
> > > +   if (TYPE_UNSIGNED (TREE_TYPE (node)))
> > > + pp_character (pp, 'u');
> > > +   if (TYPE_PRECISION (TREE_TYPE (node))
> > > +   == TYPE_PRECISION (unsigned_type_node))
> > > + ;
> > > +   else if (TYPE_PRECISION (TREE_TYPE (node))
> > > +== TYPE_PRECISION (long_unsigned_type_node))
> > > + pp_character (pp, 'l');
> > > +   else if (TYPE_PRECISION (TREE_TYPE (node))
> > > +== TYPE_PRECISION (long_long_unsigned_type_node))
> > > + pp_string (pp, "ll");
> > > + }
> 
> Not sure if I understand this.  The outer if condition says that only the
> sub-int or strange precision or pointer types do that, but then
> you compare the precisions against long and long long.  That will be
> true only for pointers.  Don't you want the u/l/ll/ul/ull suffixes emitted
> for integers even when they have normal precision and _Literal is not used?
> Or is that handled somewhere else?

Oops, you are right - it shouldn't be the same condition that controls
whether to add _Literal (type).  It should be the inverse.  Maybe
we need to add suffixes anyway even for say 61bit precision constants
to avoid warnings from libcpp.

I'll fix it up after testing a few cases.

Richard.


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-13 Thread Jakub Jelinek
On Fri, Jan 13, 2017 at 09:15:22AM +0100, Richard Biener wrote:
> > @@ -1710,6 +1716,24 @@ dump_generic_node (pretty_printer *pp, t
> >   print_hex (val, pp_buffer (pp)->digit_buffer);
> >   pp_string (pp, pp_buffer (pp)->digit_buffer);
> > }
> > +  if ((flags & TDF_GIMPLE)
> > + && (POINTER_TYPE_P (TREE_TYPE (node))
> > + || (TYPE_PRECISION (TREE_TYPE (node))
> > + < TYPE_PRECISION (integer_type_node))
> > + || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
> > +   {
> > + if (TYPE_UNSIGNED (TREE_TYPE (node)))
> > +   pp_character (pp, 'u');
> > + if (TYPE_PRECISION (TREE_TYPE (node))
> > + == TYPE_PRECISION (unsigned_type_node))
> > +   ;
> > + else if (TYPE_PRECISION (TREE_TYPE (node))
> > +  == TYPE_PRECISION (long_unsigned_type_node))
> > +   pp_character (pp, 'l');
> > + else if (TYPE_PRECISION (TREE_TYPE (node))
> > +  == TYPE_PRECISION (long_long_unsigned_type_node))
> > +   pp_string (pp, "ll");
> > +   }

Not sure if I understand this.  The outer if condition says that only the
sub-int or strange precision or pointer types do that, but then
you compare the precisions against long and long long.  That will be
true only for pointers.  Don't you want the u/l/ll/ul/ull suffixes emitted
for integers even when they have normal precision and _Literal is not used?
Or is that handled somewhere else?

Jakub


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-13 Thread Richard Biener
On Thu, 12 Jan 2017, Richard Biener wrote:

> On Thu, 12 Jan 2017, Jakub Jelinek wrote:
> 
> > On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote:
> > > It also lacks expressiveness when comparing
> > > 
> > >   short s;
> > >   s_1 = (short) 1;
> > >   s_2 = short (1);
> > > 
> > > IMHO having a _Literal somewhere makes it more obvious what is meant
> > > (I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1
> > > of course as that's even more easy to recognize).
> > 
> > So, with the _Literal (type) constant syntax, what are we going to emit
> > and parse for __int128 constants?
> > _Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something else?
> 
> Yes, unless we teach libcpp about larger than 64bit literals.
> 
> The following patch implements _Literal (but not proper dumping of
> > 64bit literals for __int128 nor parsing the above).
> 
> I think that's a good start which also covers pointer types nicely.
> For integers we might at some point want to adopt sN and uN suffixes
> which appearantly MSVC supports to handle native 128bit literals.
> 
> For
> 
> struct X { int a : 2; };
> void __GIMPLE ()
> foo (struct X * p)
> {
>   p->a = _Literal (int : 2) 1;
>   return;
> }
> 
> and thus 2 bit literals c_parser_type_name needs to be extended
> or for _Literal we can handle : 2 on our own.  But for loads
> from p->a into a temporary we need to handle that in declarations as well.
> 
> struct X { int a : 2; };
> int __GIMPLE ()
> foo (struct X * p)
> {
>   int : 2 a; // int a : 2;
>   a = p->a;
>   return a;
> }

I have bootstrapped and tested the patch below and installed it.  We
can add support for parsing vector and complex constants via the
same mechanism so having _Literal ( type ) x looks useful even if
we get another means of handling integer literals in the future.

Richard.

> 2017-01-12  Richard Biener  
> 
>   c/
>   * gimple-parser.c (c_parser_gimple_postfix_expression): Parse
>   _Literal ( type-name ) number.
> 
>   * tree-pretty-print.c (dump_generic_node): Dump INTEGER_CSTs
>   as _Literal ( type ) number in case usual suffixes do not
>   preserve all information.
> 
>   * gcc.dg/gimplefe-22.c: New testcase.
> 
> Index: gcc/c/gimple-parser.c
> ===
> --- gcc/c/gimple-parser.c (revision 244350)
> +++ gcc/c/gimple-parser.c (working copy)
> @@ -799,6 +799,32 @@ c_parser_gimple_postfix_expression (c_pa
>  type, ptr.value, alias_off);
> break;
>   }
> +   else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
> + {
> +   /* _Literal '(' type-name ')' number  */
> +   c_parser_consume_token (parser);
> +   tree type = NULL_TREE;
> +   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
> + {
> +   struct c_type_name *type_name = c_parser_type_name (parser);
> +   tree tem;
> +   if (type_name)
> + type = groktypename (type_name, , NULL);
> +   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
> +  "expected %<)%>");
> + }
> +   tree val = c_parser_gimple_postfix_expression (parser).value;
> +   if (! type
> +   || ! val
> +   || val == error_mark_node
> +   || TREE_CODE (val) != INTEGER_CST)
> + {
> +   c_parser_error (parser, "invalid _Literal");
> +   return expr;
> + }
> +   expr.value = fold_convert (type, val);
> +   return expr;
> + }
> /* SSA name.  */
> unsigned version, ver_offset;
> if (! lookup_name (id)
> Index: gcc/tree-pretty-print.c
> ===
> --- gcc/tree-pretty-print.c   (revision 244350)
> +++ gcc/tree-pretty-print.c   (working copy)
> @@ -1664,6 +1664,16 @@ dump_generic_node (pretty_printer *pp, t
>break;
>  
>  case INTEGER_CST:
> +  if (flags & TDF_GIMPLE
> +   && (POINTER_TYPE_P (TREE_TYPE (node))
> +   || (TYPE_PRECISION (TREE_TYPE (node))
> +   < TYPE_PRECISION (integer_type_node))
> +   || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
> + {
> +   pp_string (pp, "_Literal (");
> +   dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
> +   pp_string (pp, ") ");
> + }
>if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
> && ! (flags & TDF_GIMPLE))
>   {
> @@ -1693,11 +1703,7 @@ dump_generic_node (pretty_printer *pp, t
>else if (tree_fits_shwi_p (node))
>   pp_wide_integer (pp, tree_to_shwi (node));
>else if (tree_fits_uhwi_p (node))
> - {
> -   pp_unsigned_wide_integer (pp, tree_to_uhwi (node));
> -   if (flags & TDF_GIMPLE)
> - 

Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Joseph Myers
On Thu, 12 Jan 2017, Jakub Jelinek wrote:

> Well, we need some suffix that will not clash with C++ mandated udlits
> very soon, it is already bad that i and Q suffixes are problematic.
> By sN, did you mean s128 or literally sN?
> I've googled around a little bit and only found comments about
> 1ui64 and 1i64 suffixes, so that would mean accepting instead of l/L
> i128 or I128.

i128 and I128 seem reasonable as a user-visible C extension (they could of 
course be mixed in any order with u, U for unsigned, and with i, I, j, J 
for imaginary numbers).  I don't know what's appropriate for C++.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Richard Biener
On January 12, 2017 4:53:54 PM GMT+01:00, Jakub Jelinek  
wrote:
>On Thu, Jan 12, 2017 at 04:45:41PM +0100, Marc Glisse wrote:
>> > On Thu, 12 Jan 2017, Jakub Jelinek wrote:
>> > 
>> > > On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote:
>> > > > It also lacks expressiveness when comparing
>> > > > 
>> > > >   short s;
>> > > >   s_1 = (short) 1;
>> > > >   s_2 = short (1);
>> > > > 
>> > > > IMHO having a _Literal somewhere makes it more obvious what is
>meant
>> > > > (I'm still going to dump 1u or 1l instead of _Literal
>(unsigned) 1
>> > > > of course as that's even more easy to recognize).
>> > > 
>> > > So, with the _Literal (type) constant syntax, what are we going
>to emit
>> > > and parse for __int128 constants?
>> > > _Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something
>else?
>> > 
>> > Yes, unless we teach libcpp about larger than 64bit literals.
>> 
>> Teaching libcpp about 128bit literals sounds like a much nicer idea
>> indeed...
>
>Well, we need some suffix that will not clash with C++ mandated udlits
>very soon, it is already bad that i and Q suffixes are problematic.
>By sN, did you mean s128 or literally sN?
>I've googled around a little bit and only found comments about
>1ui64 and 1i64 suffixes, so that would mean accepting instead of l/L
>i128 or I128.

Indeed i64 and ui64 it was, found referenced on some stack overflow post.  
There was i16 and ui16 as well, can't see i128 mentioned there though.

Richard.

>
>   Jakub



Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Jakub Jelinek
On Thu, Jan 12, 2017 at 04:45:41PM +0100, Marc Glisse wrote:
> > On Thu, 12 Jan 2017, Jakub Jelinek wrote:
> > 
> > > On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote:
> > > > It also lacks expressiveness when comparing
> > > > 
> > > >   short s;
> > > >   s_1 = (short) 1;
> > > >   s_2 = short (1);
> > > > 
> > > > IMHO having a _Literal somewhere makes it more obvious what is meant
> > > > (I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1
> > > > of course as that's even more easy to recognize).
> > > 
> > > So, with the _Literal (type) constant syntax, what are we going to emit
> > > and parse for __int128 constants?
> > > _Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something else?
> > 
> > Yes, unless we teach libcpp about larger than 64bit literals.
> 
> Teaching libcpp about 128bit literals sounds like a much nicer idea
> indeed...

Well, we need some suffix that will not clash with C++ mandated udlits
very soon, it is already bad that i and Q suffixes are problematic.
By sN, did you mean s128 or literally sN?
I've googled around a little bit and only found comments about
1ui64 and 1i64 suffixes, so that would mean accepting instead of l/L
i128 or I128.

Jakub


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Marc Glisse

On Thu, 12 Jan 2017, Richard Biener wrote:


On Thu, 12 Jan 2017, Jakub Jelinek wrote:


On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote:

It also lacks expressiveness when comparing

  short s;
  s_1 = (short) 1;
  s_2 = short (1);

IMHO having a _Literal somewhere makes it more obvious what is meant
(I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1
of course as that's even more easy to recognize).


So, with the _Literal (type) constant syntax, what are we going to emit
and parse for __int128 constants?
_Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something else?


Yes, unless we teach libcpp about larger than 64bit literals.


Teaching libcpp about 128bit literals sounds like a much nicer idea 
indeed...


--
Marc Glisse


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Richard Biener
On Thu, 12 Jan 2017, Jakub Jelinek wrote:

> On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote:
> > It also lacks expressiveness when comparing
> > 
> >   short s;
> >   s_1 = (short) 1;
> >   s_2 = short (1);
> > 
> > IMHO having a _Literal somewhere makes it more obvious what is meant
> > (I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1
> > of course as that's even more easy to recognize).
> 
> So, with the _Literal (type) constant syntax, what are we going to emit
> and parse for __int128 constants?
> _Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something else?

Yes, unless we teach libcpp about larger than 64bit literals.

The following patch implements _Literal (but not proper dumping of
> 64bit literals for __int128 nor parsing the above).

I think that's a good start which also covers pointer types nicely.
For integers we might at some point want to adopt sN and uN suffixes
which appearantly MSVC supports to handle native 128bit literals.

For

struct X { int a : 2; };
void __GIMPLE ()
foo (struct X * p)
{
  p->a = _Literal (int : 2) 1;
  return;
}

and thus 2 bit literals c_parser_type_name needs to be extended
or for _Literal we can handle : 2 on our own.  But for loads
from p->a into a temporary we need to handle that in declarations as well.

struct X { int a : 2; };
int __GIMPLE ()
foo (struct X * p)
{
  int : 2 a; // int a : 2;
  a = p->a;
  return a;
}

Richard.

2017-01-12  Richard Biener  

c/
* gimple-parser.c (c_parser_gimple_postfix_expression): Parse
_Literal ( type-name ) number.

* tree-pretty-print.c (dump_generic_node): Dump INTEGER_CSTs
as _Literal ( type ) number in case usual suffixes do not
preserve all information.

* gcc.dg/gimplefe-22.c: New testcase.

Index: gcc/c/gimple-parser.c
===
--- gcc/c/gimple-parser.c   (revision 244350)
+++ gcc/c/gimple-parser.c   (working copy)
@@ -799,6 +799,32 @@ c_parser_gimple_postfix_expression (c_pa
   type, ptr.value, alias_off);
  break;
}
+ else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
+   {
+ /* _Literal '(' type-name ')' number  */
+ c_parser_consume_token (parser);
+ tree type = NULL_TREE;
+ if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+   {
+ struct c_type_name *type_name = c_parser_type_name (parser);
+ tree tem;
+ if (type_name)
+   type = groktypename (type_name, , NULL);
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+"expected %<)%>");
+   }
+ tree val = c_parser_gimple_postfix_expression (parser).value;
+ if (! type
+ || ! val
+ || val == error_mark_node
+ || TREE_CODE (val) != INTEGER_CST)
+   {
+ c_parser_error (parser, "invalid _Literal");
+ return expr;
+   }
+ expr.value = fold_convert (type, val);
+ return expr;
+   }
  /* SSA name.  */
  unsigned version, ver_offset;
  if (! lookup_name (id)
Index: gcc/tree-pretty-print.c
===
--- gcc/tree-pretty-print.c (revision 244350)
+++ gcc/tree-pretty-print.c (working copy)
@@ -1664,6 +1664,16 @@ dump_generic_node (pretty_printer *pp, t
   break;
 
 case INTEGER_CST:
+  if (flags & TDF_GIMPLE
+ && (POINTER_TYPE_P (TREE_TYPE (node))
+ || (TYPE_PRECISION (TREE_TYPE (node))
+ < TYPE_PRECISION (integer_type_node))
+ || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1))
+   {
+ pp_string (pp, "_Literal (");
+ dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
+ pp_string (pp, ") ");
+   }
   if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
  && ! (flags & TDF_GIMPLE))
{
@@ -1693,11 +1703,7 @@ dump_generic_node (pretty_printer *pp, t
   else if (tree_fits_shwi_p (node))
pp_wide_integer (pp, tree_to_shwi (node));
   else if (tree_fits_uhwi_p (node))
-   {
- pp_unsigned_wide_integer (pp, tree_to_uhwi (node));
- if (flags & TDF_GIMPLE)
-   pp_character (pp, 'U');
-   }
+   pp_unsigned_wide_integer (pp, tree_to_uhwi (node));
   else
{
  wide_int val = node;
@@ -1710,6 +1716,24 @@ dump_generic_node (pretty_printer *pp, t
  print_hex (val, pp_buffer (pp)->digit_buffer);
  pp_string (pp, pp_buffer (pp)->digit_buffer);
}
+  if ((flags & TDF_GIMPLE)
+ && (POINTER_TYPE_P (TREE_TYPE (node))
+ || (TYPE_PRECISION 

Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Jakub Jelinek
On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote:
> It also lacks expressiveness when comparing
> 
>   short s;
>   s_1 = (short) 1;
>   s_2 = short (1);
> 
> IMHO having a _Literal somewhere makes it more obvious what is meant
> (I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1
> of course as that's even more easy to recognize).

So, with the _Literal (type) constant syntax, what are we going to emit
and parse for __int128 constants?
_Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something else?

Jakub


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Richard Biener
On Thu, 12 Jan 2017, Jakub Jelinek wrote:

> On Thu, Jan 12, 2017 at 04:38:27PM +0530, Prathamesh Kulkarni wrote:
> > On 12 January 2017 at 16:15, Richard Biener  wrote:
> > > On Thu, 12 Jan 2017, Jakub Jelinek wrote:
> > >
> > >> On Thu, Jan 12, 2017 at 10:52:23AM +0100, Richard Biener wrote:
> > >> > > I'll give the (short) 1 parsing a try though to see how awkward it
> > >> > > really gets.
> > >> >
> > >> > Ok, doesn't look a good way to go.  Apart from making it difficult
> > >> > to handle in the parser you can't distinguish a conversion from an
> > >> > integer literal and a short literal for
> > >> >
> > >> >  short s;
> > >> >  s_1 = (short) 1;
> > >>
> > >> As there are tons of types the integer literals can have, wouldn't it be
> > >> better to just introduce _Literal  where you could supply
> > >> the type if it is not one where C provides a suffix for it or int?
> > >> Then we could avoid adding lots of suffixes for new and newer types.
> > >> Of course for integer literals with int, unsigned int, {,unsigned} long 
> > >> {,long}
> > >> one would still use no suffix, U, {,U}L{,L} suffixes.
> > >
> > > That's an interesting idea.  _Literal (type) value might be alternative
> > > syntax (a cast to be evaulated as literal).  I'll give it a shot.
> > Um, how about just type(value) ?
> > s_1 = short (10);
> > AFAIU this isn't legal C and could be added as an extension ?
> 
> Even C++ doesn't allow this syntax if the type isn't a single token.
> So you can't use unsigned __int128 (5) or unsigned char (7) or signed char 
> (-5).

It also lacks expressiveness when comparing

  short s;
  s_1 = (short) 1;
  s_2 = short (1);

IMHO having a _Literal somewhere makes it more obvious what is meant
(I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1
of course as that's even more easy to recognize).

Richard.


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Jakub Jelinek
On Thu, Jan 12, 2017 at 04:38:27PM +0530, Prathamesh Kulkarni wrote:
> On 12 January 2017 at 16:15, Richard Biener  wrote:
> > On Thu, 12 Jan 2017, Jakub Jelinek wrote:
> >
> >> On Thu, Jan 12, 2017 at 10:52:23AM +0100, Richard Biener wrote:
> >> > > I'll give the (short) 1 parsing a try though to see how awkward it
> >> > > really gets.
> >> >
> >> > Ok, doesn't look a good way to go.  Apart from making it difficult
> >> > to handle in the parser you can't distinguish a conversion from an
> >> > integer literal and a short literal for
> >> >
> >> >  short s;
> >> >  s_1 = (short) 1;
> >>
> >> As there are tons of types the integer literals can have, wouldn't it be
> >> better to just introduce _Literal  where you could supply
> >> the type if it is not one where C provides a suffix for it or int?
> >> Then we could avoid adding lots of suffixes for new and newer types.
> >> Of course for integer literals with int, unsigned int, {,unsigned} long 
> >> {,long}
> >> one would still use no suffix, U, {,U}L{,L} suffixes.
> >
> > That's an interesting idea.  _Literal (type) value might be alternative
> > syntax (a cast to be evaulated as literal).  I'll give it a shot.
> Um, how about just type(value) ?
> s_1 = short (10);
> AFAIU this isn't legal C and could be added as an extension ?

Even C++ doesn't allow this syntax if the type isn't a single token.
So you can't use unsigned __int128 (5) or unsigned char (7) or signed char (-5).

Jakub


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Prathamesh Kulkarni
On 12 January 2017 at 16:15, Richard Biener  wrote:
> On Thu, 12 Jan 2017, Jakub Jelinek wrote:
>
>> On Thu, Jan 12, 2017 at 10:52:23AM +0100, Richard Biener wrote:
>> > > I'll give the (short) 1 parsing a try though to see how awkward it
>> > > really gets.
>> >
>> > Ok, doesn't look a good way to go.  Apart from making it difficult
>> > to handle in the parser you can't distinguish a conversion from an
>> > integer literal and a short literal for
>> >
>> >  short s;
>> >  s_1 = (short) 1;
>>
>> As there are tons of types the integer literals can have, wouldn't it be
>> better to just introduce _Literal  where you could supply
>> the type if it is not one where C provides a suffix for it or int?
>> Then we could avoid adding lots of suffixes for new and newer types.
>> Of course for integer literals with int, unsigned int, {,unsigned} long 
>> {,long}
>> one would still use no suffix, U, {,U}L{,L} suffixes.
>
> That's an interesting idea.  _Literal (type) value might be alternative
> syntax (a cast to be evaulated as literal).  I'll give it a shot.
Um, how about just type(value) ?
s_1 = short (10);
AFAIU this isn't legal C and could be added as an extension ?

Thanks,
Prathamesh
>
>> > It looks like we currently have no way to write __int128 literals in C?
>> >
>> > __int128 x = 0x;
>>
>> Yeah, one typically has to use
>> __int128 x = (((unsigned __int128) 0xULL) << 64) | 
>> 0xULL;
>> or something similar.
>
> I see.
>
> Thanks,
> Richard.


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Richard Biener
On Thu, 12 Jan 2017, Jakub Jelinek wrote:

> On Thu, Jan 12, 2017 at 10:52:23AM +0100, Richard Biener wrote:
> > > I'll give the (short) 1 parsing a try though to see how awkward it
> > > really gets.
> > 
> > Ok, doesn't look a good way to go.  Apart from making it difficult
> > to handle in the parser you can't distinguish a conversion from an
> > integer literal and a short literal for
> > 
> >  short s;
> >  s_1 = (short) 1;
> 
> As there are tons of types the integer literals can have, wouldn't it be
> better to just introduce _Literal  where you could supply
> the type if it is not one where C provides a suffix for it or int?
> Then we could avoid adding lots of suffixes for new and newer types.
> Of course for integer literals with int, unsigned int, {,unsigned} long 
> {,long}
> one would still use no suffix, U, {,U}L{,L} suffixes.

That's an interesting idea.  _Literal (type) value might be alternative
syntax (a cast to be evaulated as literal).  I'll give it a shot.

> > It looks like we currently have no way to write __int128 literals in C?
> > 
> > __int128 x = 0x;
> 
> Yeah, one typically has to use
> __int128 x = (((unsigned __int128) 0xULL) << 64) | 
> 0xULL;
> or something similar.

I see.

Thanks,
Richard.


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Jakub Jelinek
On Thu, Jan 12, 2017 at 10:52:23AM +0100, Richard Biener wrote:
> > I'll give the (short) 1 parsing a try though to see how awkward it
> > really gets.
> 
> Ok, doesn't look a good way to go.  Apart from making it difficult
> to handle in the parser you can't distinguish a conversion from an
> integer literal and a short literal for
> 
>  short s;
>  s_1 = (short) 1;

As there are tons of types the integer literals can have, wouldn't it be
better to just introduce _Literal  where you could supply
the type if it is not one where C provides a suffix for it or int?
Then we could avoid adding lots of suffixes for new and newer types.
Of course for integer literals with int, unsigned int, {,unsigned} long {,long}
one would still use no suffix, U, {,U}L{,L} suffixes.

> It looks like we currently have no way to write __int128 literals in C?
> 
> __int128 x = 0x;

Yeah, one typically has to use
__int128 x = (((unsigned __int128) 0xULL) << 64) | 
0xULL;
or something similar.

Jakub


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Richard Biener
On Thu, 12 Jan 2017, Richard Biener wrote:

> On Wed, 11 Jan 2017, Joseph Myers wrote:
> 
> > On Wed, 11 Jan 2017, Richard Biener wrote:
> > 
> > > As you can see I adjusted dumping of pointer constants (we can't
> > > parse the B suffix and large unsigned numbers get a warning so
> > > add 'U').  There's the general issue that we dump
> > > 
> > >   short x;
> > >   x = 1;
> > > 
> > > and then lex the '1' as type int and there's no suffixes for integer
> > > types smaller than int which means we can't write those constants
> > > type correct :/  Suggestions welcome (currently we ICE with type
> > > mismatches in those cases, we can avoid that by auto-fixing during
> > > parsing but I'd like to be explicit somehow).
> > 
> > You could always dump as ((short) 1); that's valid C.
> 
> Indeed.  It makes parsing a little more awkward as (short) 1 is not
> a postfix expression.
> 
> I suppose adding additional suffixes for char/short conditional on
> -fgimple would be another way (either via setting user_literals option
> or teaching libcpp about those itself).  's' and 'ss' (CPP_N_SMALL_SMALL
> and CPP_N_SMALL_SMALL_SMALL?) would be my choice...
> 
> I'll give the (short) 1 parsing a try though to see how awkward it
> really gets.

Ok, doesn't look a good way to go.  Apart from making it difficult
to handle in the parser you can't distinguish a conversion from an
integer literal and a short literal for

 short s;
 s_1 = (short) 1;

I've pasted below what I came up with for 's' and 'ss'.  It's just
a prototype as it doens't handle larger literals and bit-precision
literals we have in the IL.  So I suppose user_literals and
interpreting uN/sN with N being the actual precision looks better
here?  Likewise we need something for pointer literals (where we
might need to encode the address-space as well...).  A simple pN
would work for a start I suppose.

It looks like we currently have no way to write __int128 literals in C?

__int128 x = 0x;

yields

t.c:1:14: warning: integer constant is too large for its type
 __int128 x = 0x;
  ^~

and truncation to 64bits which looks like a limitation of cpp_num.

I'd like to solve the issue of short and char literals for GIMPLE
testcases for GCC 6, any preference on the solution?  There's also
bool literals (1-bit precision integers in GIMPLE...), for those
using _True and _False might be a workaround.  Though 1u1 and 0u1
would work for those as well.

Thanks,
Richard.

2017-01-12  Richard Biener  

c-family/
* c-lex.c (narrowest_unsigned_type): Handle CPP_N_TINY and
CPP_N_MINISCULE.
(narrowest_signed_type): Likewise.

libcpp/
* include/cpplib.h (CPP_N_TINY): New.
(CPP_N_MINISCULE): Likewise.
* expr.c (interpret_int_suffix): Map 's' to CPP_N_TINY and
'ss' to CPP_N_MINISCULE if ext_numeric_literals.

* tree-pretty-print.c (dump_generic_node): Dump integer constant
type suffixes with -gimple.

Index: gcc/c-family/c-lex.c
===
--- gcc/c-family/c-lex.c(revision 244350)
+++ gcc/c-family/c-lex.c(working copy)
@@ -641,7 +641,11 @@ narrowest_unsigned_type (const widest_in
 {
   int itk;
 
-  if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+  if ((flags & CPP_N_WIDTH) == CPP_N_MINISCULE)
+itk = itk_unsigned_char;
+  else if ((flags & CPP_N_WIDTH) == CPP_N_TINY)
+itk = itk_unsigned_short;
+  else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
 itk = itk_unsigned_int;
   else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
 itk = itk_unsigned_long;
@@ -669,7 +673,11 @@ narrowest_signed_type (const widest_int
 {
   int itk;
 
-  if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
+  if ((flags & CPP_N_WIDTH) == CPP_N_MINISCULE)
+itk = itk_signed_char;
+  else if ((flags & CPP_N_WIDTH) == CPP_N_TINY)
+itk = itk_short;
+  else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
 itk = itk_int;
   else if ((flags & CPP_N_WIDTH) == CPP_N_MEDIUM)
 itk = itk_long;
Index: gcc/tree-pretty-print.c
===
--- gcc/tree-pretty-print.c (revision 244350)
+++ gcc/tree-pretty-print.c (working copy)
@@ -1710,6 +1710,28 @@ dump_generic_node (pretty_printer *pp, t
  print_hex (val, pp_buffer (pp)->digit_buffer);
  pp_string (pp, pp_buffer (pp)->digit_buffer);
}
+  if (flags & TDF_GIMPLE)
+   {
+ if (TYPE_UNSIGNED (TREE_TYPE (node)))
+   pp_character (pp, 'u');
+ if (POINTER_TYPE_P (TREE_TYPE (node)))
+   ;
+ else if (TYPE_PRECISION (TREE_TYPE (node))
+  == TYPE_PRECISION (unsigned_char_type_node))
+   pp_string (pp, "ss");
+ else if (TYPE_PRECISION (TREE_TYPE (node))
+  == TYPE_PRECISION (short_unsigned_type_node))
+   

Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-12 Thread Richard Biener
On Wed, 11 Jan 2017, Joseph Myers wrote:

> On Wed, 11 Jan 2017, Richard Biener wrote:
> 
> > As you can see I adjusted dumping of pointer constants (we can't
> > parse the B suffix and large unsigned numbers get a warning so
> > add 'U').  There's the general issue that we dump
> > 
> >   short x;
> >   x = 1;
> > 
> > and then lex the '1' as type int and there's no suffixes for integer
> > types smaller than int which means we can't write those constants
> > type correct :/  Suggestions welcome (currently we ICE with type
> > mismatches in those cases, we can avoid that by auto-fixing during
> > parsing but I'd like to be explicit somehow).
> 
> You could always dump as ((short) 1); that's valid C.

Indeed.  It makes parsing a little more awkward as (short) 1 is not
a postfix expression.

I suppose adding additional suffixes for char/short conditional on
-fgimple would be another way (either via setting user_literals option
or teaching libcpp about those itself).  's' and 'ss' (CPP_N_SMALL_SMALL
and CPP_N_SMALL_SMALL_SMALL?) would be my choice...

I'll give the (short) 1 parsing a try though to see how awkward it
really gets.

Thanks,
Richard.


Re: [PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-11 Thread Joseph Myers
On Wed, 11 Jan 2017, Richard Biener wrote:

> As you can see I adjusted dumping of pointer constants (we can't
> parse the B suffix and large unsigned numbers get a warning so
> add 'U').  There's the general issue that we dump
> 
>   short x;
>   x = 1;
> 
> and then lex the '1' as type int and there's no suffixes for integer
> types smaller than int which means we can't write those constants
> type correct :/  Suggestions welcome (currently we ICE with type
> mismatches in those cases, we can avoid that by auto-fixing during
> parsing but I'd like to be explicit somehow).

You could always dump as ((short) 1); that's valid C.

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH][GIMPLE FE] Add parsing of MEM_REFs

2017-01-11 Thread Richard Biener

The following fills the gap of missed handling of MEM_REF parsing.
As we want to represent all info that is on a MEM_REF the existing
dumping isn't sufficent so I resorted to

  __MEM '<' type-name [ ',' number ] '>'
'(' [ '(' type-name ')' ] unary-expression
 [ '+' number ] ')'  */

where optional parts are in []s.  So for

  __MEM < int, 16 > ( (char *)  + 1 )

we access x as 16-bit aligned int at offset 1 with TBAA type 'char'.

Naturally VIEW_CONVERT_EXPR would look like __VCE < int > (x) then,
TARGET_MEM_REF would simply get some additional operands in the
above function-like __MEM (rather than + step * index + index2).

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

The testcase parses, dumps and then parses again to the same output.

Any comments / objections to the syntax (of __MEM) and/or suggestions
for VIEW_CONVERT_EXPR or TARGET_MEM_REF?

As you can see I adjusted dumping of pointer constants (we can't
parse the B suffix and large unsigned numbers get a warning so
add 'U').  There's the general issue that we dump

  short x;
  x = 1;

and then lex the '1' as type int and there's no suffixes for integer
types smaller than int which means we can't write those constants
type correct :/  Suggestions welcome (currently we ICE with type
mismatches in those cases, we can avoid that by auto-fixing during
parsing but I'd like to be explicit somehow).

Thanks,
Richard.

2017-01-11  Richard Biener  

* tree-pretty-print.c (dump_generic_node): Provide -gimple
variant for MEM_REF.  Sanitize INTEGER_CST for -gimple.

c/
* gimple-parser.c (c_parser_gimple_postfix_expression): Parse
__MEM.

* gcc.dg/gimplefe-21.c: New testcase.

Index: gcc/tree-pretty-print.c
===
*** gcc/tree-pretty-print.c (revision 244312)
--- gcc/tree-pretty-print.c (working copy)
*** dump_generic_node (pretty_printer *pp, t
*** 1459,1465 
  
  case MEM_REF:
{
!   if (integer_zerop (TREE_OPERAND (node, 1))
/* Dump the types of INTEGER_CSTs explicitly, for we can't
   infer them and MEM_ATTR caching will share MEM_REFs
   with differently-typed op0s.  */
--- 1459,1496 
  
  case MEM_REF:
{
!   if (flags & TDF_GIMPLE)
! {
!   pp_string (pp, "__MEM <");
!   dump_generic_node (pp, TREE_TYPE (node),
!  spc, flags | TDF_SLIM, false);
!   if (TYPE_ALIGN (TREE_TYPE (node))
!   != TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node
! {
!   pp_string (pp, ", ");
!   pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node)));
! }
!   pp_greater (pp);
!   pp_string (pp, " (");
!   if (TREE_TYPE (TREE_OPERAND (node, 0))
!   != TREE_TYPE (TREE_OPERAND (node, 1)))
! {
!   pp_left_paren (pp);
!   dump_generic_node (pp, TREE_TYPE (TREE_OPERAND (node, 1)),
!  spc, flags | TDF_SLIM, false);
!   pp_right_paren (pp);
! }
!   dump_generic_node (pp, TREE_OPERAND (node, 0),
!  spc, flags | TDF_SLIM, false);
!   if (! integer_zerop (TREE_OPERAND (node, 1)))
! {
!   pp_string (pp, " + ");
!   dump_generic_node (pp, TREE_OPERAND (node, 1),
!  spc, flags | TDF_SLIM, false);
! }
!   pp_right_paren (pp);
! }
!   else if (integer_zerop (TREE_OPERAND (node, 1))
/* Dump the types of INTEGER_CSTs explicitly, for we can't
   infer them and MEM_ATTR caching will share MEM_REFs
   with differently-typed op0s.  */
*** dump_generic_node (pretty_printer *pp, t
*** 1633,1639 
break;
  
  case INTEGER_CST:
!   if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
{
  /* In the case of a pointer, one may want to divide by the
 size of the pointed-to type.  Unfortunately, this not
--- 1664,1671 
break;
  
  case INTEGER_CST:
!   if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
! && ! (flags & TDF_GIMPLE))
{
  /* In the case of a pointer, one may want to divide by the
 size of the pointed-to type.  Unfortunately, this not
*** dump_generic_node (pretty_printer *pp, t
*** 1661,1667 
else if (tree_fits_shwi_p (node))
pp_wide_integer (pp, tree_to_shwi (node));
else if (tree_fits_uhwi_p (node))
!   pp_unsigned_wide_integer (pp, tree_to_uhwi (node));
else
{
  wide_int val = node;
--- 1693,1703 
else if (tree_fits_shwi_p (node))
pp_wide_integer (pp, tree_to_shwi (node));
else if (tree_fits_uhwi_p (node))
!   {
!