increase alignment of global structs in increase_alignment pass

2016-02-22 Thread Prathamesh Kulkarni
Hi Richard,
As discussed in private mail, this version of patch attempts to
increase alignment
of global struct decl if it contains an an array field(s) and array's
offset is a multiple of the alignment of vector type corresponding to
it's scalar type and recursively checks for nested structs.
eg:
static struct
{
  int a, b, c, d;
  int k[4];
  float f[10];
};
k is a candidate array since it's offset is 16 and alignment of
"vector (4) int" is 8.
Similarly for f.

I haven't been able to create a test-case where there are
multiple candidate arrays and vector alignment of arrays are different.
I suppose in this case we will have to increase alignment
of the struct by the max alignment ?
eg:
static struct
{
  
  T1 k[S1]
  
  T2 f[S2]
  
};

if V1 is vector type corresponding to T1, and V2 corresponding vector
type to T2,
offset (k) % align(V1) == 0 and offset (f) % align(V2) == 0
and align (V1) > align(V2) then we will increase alignment of struct
by align(V1).

Testing showed FAIL for g++.dg/torture/pr31863.C due to program timeout.
Initially it appeared to me, it went in infinite loop. However
on second thoughts I think it's probably not an infinite loop, rather
taking (extraordinarily) large amount of time
to compile the test-case with the patch.
The test-case  builds quickly for only 2 instantiations of ClassSpec
(ClassSpec,
 ClassSpec)
Building with 22 instantiations (upto ClassSpec) takes up
to ~1m to compile.
with:
23  instantiations: ~2m
24 instantiations: ~5m
For 30 instantiations I terminated cc1plus after 13m (by SIGKILL).

I guess it shouldn't go in an infinite loop because:
a) structs cannot have circular references.
b) works for lower number of instantiations
However I have no sound evidence that it cannot be in infinite loop.
I don't understand why a decl node is getting visited more than once
for that test-case.

Using a hash_map to store alignments of decl's so that decl node gets visited
only once prevents the issue.
The patch is cross-tested on aarch64*-*-* and arm*-*-* and passes with
using hash_map
workaround.

Thanks,
Prathamesh
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 2b25b45..6f8c3b6 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -794,38 +794,112 @@ make_pass_slp_vectorize (gcc::context *ctxt)
  This should involve global alignment analysis and in the future also
  array padding.  */
 
+static unsigned get_vec_alignment_for_decl (tree);
+
+/* FIXME: decl_align_map is used to cache vec alignments of decl nodes,
+   so if a decl node is visited again, get_vec_alignment_for_decl
+   returns the alignment.
+   This is done to avoid looping infinitely or taking
+   very large time to compile for pr31863.C (and similar cases).
+   This happens because a decl node gets visited multiple times.
+   I am not sure why a decl node gets visited multiple times.  */
+static hash_map *decl_align_map;
+
+static unsigned
+get_vec_alignment_for_array_decl (tree array_decl)
+{
+  tree type = TREE_TYPE (array_decl);
+  gcc_assert (TREE_CODE (type) == ARRAY_TYPE); 
+
+  tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
+  return (vectype) ? TYPE_ALIGN (vectype) : 0; 
+}
+
+static unsigned
+get_vec_alignment_for_record_decl (tree record_decl)
+{
+  tree type = TREE_TYPE (record_decl);
+  gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+  unsigned max_align = 0, alignment;
+  HOST_WIDE_INT offset; 
+
+  if (TYPE_PACKED (type))
+return 0;
+
+  for (tree field = first_field (type); field != NULL_TREE; field = DECL_CHAIN 
(field)) 
+{
+  /* C++FE puts node "._0" of code TYPE_DECL. skip that.  */
+  if (TREE_CODE (field) != FIELD_DECL)
+   continue;
+
+  offset = int_byte_position (field);
+  alignment = get_vec_alignment_for_decl (field);
+  if (alignment && (offset % (alignment / BITS_PER_UNIT) == 0) && 
(alignment > max_align))
+   max_align = alignment;
+}
+  
+  return max_align; 
+}
+
+static unsigned
+get_vec_alignment_for_decl (tree decl)
+{
+  if (decl == NULL_TREE)
+return 0;
+
+  gcc_assert (DECL_P (decl));
+
+  unsigned *slot = decl_align_map->get (decl);
+  if (slot)
+return *slot;
+
+  static unsigned alignment = 0;
+  tree type = TREE_TYPE (decl);
+
+  switch (TREE_CODE (type))
+{
+  case ARRAY_TYPE:
+   alignment = get_vec_alignment_for_array_decl (decl);
+   break;
+  case RECORD_TYPE:
+   alignment = get_vec_alignment_for_record_decl (decl);
+   break;
+  default:
+   alignment = 0;
+   break;
+}
+
+  unsigned ret = (alignment > DECL_ALIGN (decl)) ? alignment : 0;
+  decl_align_map->put (decl, ret);
+  return ret;
+}
+
 static unsigned int
 increase_alignment (void)
 {
   varpool_node *vnode;
 
   vect_location = UNKNOWN_LOCATION;
-
+  decl_align_map = new hash_map;
+  
   /* Increase the alignment of all global arrays for vectorization.  */
   FOR_EACH_DEFINED_VARIABLE (vnode)
 {
   tree vectype, decl = vnode->decl;
-  tree

section type conflict in gcc xtensa

2016-02-22 Thread Hari Narasimhan H.N
Dear Sir,

We are getting the following error "section type conflict" with xtensa
gcc when a const and non const global variable is placed in the same
section?

I am using a bare metal cross gcc toolchain for Xtensa architecture
built as per instructions in
http://wiki.linux-xtensa.org/index.php/Crosstool-NG. We are using a
custom Xtensa processor in our firmware.

For example consider the code below

__attribute__((section(".dram0.data"))) int x;
__attribute__((section(".dram0.data"))) const int y = 10;

main()
{

}

This throws up an error during compilation

test3.c:2:51: error: y causes a section type conflict with x
 __attribute__((section(".dram0.data"))) const int y = 10;
   ^
test3.c:1:45: note: ‘x’ was declared here
 __attribute__((section(".dram0.data"))) int x;

Removing the const attribute for y will remove this error.

We built our firmware by removing const attributes.Firmware built
using xcc works fine but the same code built using gcc works partly


Thanks and Regards
Hari


Re: section type conflict in gcc xtensa

2016-02-22 Thread Jakub Jelinek
On Mon, Feb 22, 2016 at 02:57:43PM +0530, Hari Narasimhan H.N wrote:
> Dear Sir,
> 
> We are getting the following error "section type conflict" with xtensa
> gcc when a const and non const global variable is placed in the same
> section?
> 
> I am using a bare metal cross gcc toolchain for Xtensa architecture
> built as per instructions in
> http://wiki.linux-xtensa.org/index.php/Crosstool-NG. We are using a
> custom Xtensa processor in our firmware.
> 
> For example consider the code below
> 
> __attribute__((section(".dram0.data"))) int x;
> __attribute__((section(".dram0.data"))) const int y = 10;

This is user error.  You really shouldn't mix const and non-const variables
in the same section, the non-const vars want a writable section, while the
const ones (unless they need dynamic relocations) want read-only section.
Put them into separate sections, and perhaps through a linker script combine
them together if you for whatever strange reason need that.

Jakub


Re: increase alignment of global structs in increase_alignment pass

2016-02-22 Thread Richard Biener
On Mon, 22 Feb 2016, Prathamesh Kulkarni wrote:

> Hi Richard,
> As discussed in private mail, this version of patch attempts to
> increase alignment
> of global struct decl if it contains an an array field(s) and array's
> offset is a multiple of the alignment of vector type corresponding to
> it's scalar type and recursively checks for nested structs.
> eg:
> static struct
> {
>   int a, b, c, d;
>   int k[4];
>   float f[10];
> };
> k is a candidate array since it's offset is 16 and alignment of
> "vector (4) int" is 8.
> Similarly for f.
> 
> I haven't been able to create a test-case where there are
> multiple candidate arrays and vector alignment of arrays are different.
> I suppose in this case we will have to increase alignment
> of the struct by the max alignment ?
> eg:
> static struct
> {
>   
>   T1 k[S1]
>   
>   T2 f[S2]
>   
> };
> 
> if V1 is vector type corresponding to T1, and V2 corresponding vector
> type to T2,
> offset (k) % align(V1) == 0 and offset (f) % align(V2) == 0
> and align (V1) > align(V2) then we will increase alignment of struct
> by align(V1).
> 
> Testing showed FAIL for g++.dg/torture/pr31863.C due to program timeout.
> Initially it appeared to me, it went in infinite loop. However
> on second thoughts I think it's probably not an infinite loop, rather
> taking (extraordinarily) large amount of time
> to compile the test-case with the patch.
> The test-case  builds quickly for only 2 instantiations of ClassSpec
> (ClassSpec,
>  ClassSpec)
> Building with 22 instantiations (upto ClassSpec) takes up
> to ~1m to compile.
> with:
> 23  instantiations: ~2m
> 24 instantiations: ~5m
> For 30 instantiations I terminated cc1plus after 13m (by SIGKILL).
> 
> I guess it shouldn't go in an infinite loop because:
> a) structs cannot have circular references.
> b) works for lower number of instantiations
> However I have no sound evidence that it cannot be in infinite loop.
> I don't understand why a decl node is getting visited more than once
> for that test-case.
> 
> Using a hash_map to store alignments of decl's so that decl node gets visited
> only once prevents the issue.

Maybe aliases.  Try not walking vnode->alias == true vars.

Richard.


Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

2016-02-22 Thread Michael Matz
Hi,

On Fri, 19 Feb 2016, Richard Smith wrote:

> >> > The trivially copyable is gone again.  Why is it not necessary?
> >>
> >> The C++ ABI doesn't defer to the C psABI for types that aren't
> >> trivially-copyable. See
> >> http://mentorembedded.github.io/cxx-abi/abi.html#normal-call
> >
> > Hmm, yes, but we don't want to define something for only C and C++, but
> > language independend (so far as possible).  And given only the above
> > language I think this type:
> >
> > struct S {
> >   S() {something();}
> > };
> >
> > would be an empty type, and that's not what we want.
> 
> Yes it is. Did you mean to give S a copy constructor, copy assignment
> operator, or destructor instead?

Er, yes, I did mean to :-)


Ciao,
Michael.


Re: RFC: Update Intel386, x86-64 and IA MCU psABIs for passing/returning empty struct

2016-02-22 Thread Michael Matz
Hi,

On Sat, 20 Feb 2016, Richard Smith wrote:

> > An empty type is a type where it and all of its subobjects 
> > (recursively) are of class, structure, union, or array type.
> >
> > doesn't cover "trivially-copyable".
> 
> That's correct. Whether a type is trivially copyable is unrelated to 
> whether it is empty.

I would still feel more comfortable to include the restriction to 
trivially copyable types, not in the part of definition of empty type, of 
course, but as part of the restrictions of when a type can be passed in no 
registers.  Basically to clarify the intent in the psABI if there's any 
doubt.  I.e. like so:

---
An empty type is a type where it and all of its subobjects (recursively)
are of class, structure, union, or array type.  No memory slot nor 
register should be used to pass or return an object of empty type that's 
trivially copyable.
---

(With possibly a self-sufficient definition of trivially copyable, that's 
language agnostic)


Ciao,
Michael.


extendqihi2 and GCC RTL type system

2016-02-22 Thread David Edelsohn
csmith has uncovered a latent bug in the the PowerPC port for a
combiner pattern involving extendqihi2 (the alternative in the pattern
has never triggered for real code in over 10 years). Basic extendqihi2
works correctly (the instructions extend to entire register, but the
upper bits are ignored).

The PowerPC architecture can load and store HImode values, but cannot
compute directly on that mode -- only on SImode or DImode.

One proposed fix for the bug would remove extendqihi2, forcing GCC to
use SUBREGs for HImode extend operations, as it does for all other
computations.

If I remove extendqihi2 (extend:HI pattern) from the PowerPC port,
will that cause any problems for the GCC RTL type system or inhibit
optimizations?   I see that Alpha and SPARC define extendqihi2, but
IA-64 and AArch64 do not, so there is precedent for both approaches.

Any insights would be appreciated.

Thanks, David


Re: extendqihi2 and GCC RTL type system

2016-02-22 Thread Jeff Law

On 02/22/2016 08:55 AM, David Edelsohn wrote:

csmith has uncovered a latent bug in the the PowerPC port for a
combiner pattern involving extendqihi2 (the alternative in the pattern
has never triggered for real code in over 10 years). Basic extendqihi2
works correctly (the instructions extend to entire register, but the
upper bits are ignored).

The PowerPC architecture can load and store HImode values, but cannot
compute directly on that mode -- only on SImode or DImode.

Right.  Similar to the PA in that regard.


One proposed fix for the bug would remove extendqihi2, forcing GCC to
use SUBREGs for HImode extend operations, as it does for all other
computations.

And that should work.



If I remove extendqihi2 (extend:HI pattern) from the PowerPC port,
will that cause any problems for the GCC RTL type system or inhibit
optimizations?   I see that Alpha and SPARC define extendqihi2, but
IA-64 and AArch64 do not, so there is precedent for both approaches.

Any insights would be appreciated.
It shouldn't cause any type system kinds of problems.   It might cause 
missed optimizations though.  I'm not sure if combine will handle 
optimizing away the SUBREG by exploiting LOAD_EXTEND_OP.


Jeff


David Malcolm appointed libcpp and diagnostic messages maintainer

2016-02-22 Thread David Edelsohn
I am pleased to announce that the GCC Steering Committee has
appointed David Malcolm as libcpp and diagnostic messages maintainer.

Please join me in congratulating David on his new role.
David, please update your listing in the MAINTAINERS file.

Happy hacking!
David



Re: David Malcolm appointed libcpp and diagnostic messages maintainer

2016-02-22 Thread David Malcolm
On Mon, 2016-02-22 at 11:14 -0500, David Edelsohn wrote:
>   I am pleased to announce that the GCC Steering Committee has
> appointed David Malcolm as libcpp and diagnostic messages maintainer.
> 
>   Please join me in congratulating David on his new role.
> David, please update your listing in the MAINTAINERS file.
> 
> Happy hacking!
> David

Thanks!  I've committed the attached as r233608.



Index: ChangeLog
===
--- ChangeLog	(revision 233607)
+++ ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2016-02-22  David Malcolm  
+
+	* MAINTAINERS (libcpp): Add myself.
+	(diagnostic messages): Likewise.
+
 2016-02-20  Tom de Vries  
 
 	* MAINTAINERS: Fix whitespace.
Index: MAINTAINERS
===
--- MAINTAINERS	(revision 233607)
+++ MAINTAINERS	(working copy)
@@ -164,6 +164,7 @@
 libbacktrace		Ian Lance Taylor	
 libcpp			Per Bothner		
 libcpp			All C and C++ front end maintainers
+libcpp			David Malcolm		
 fp-bit			Ian Lance Taylor	
 libdecnumber		Ben Elliston		
 libgcc			Ian Lance Taylor	
@@ -217,6 +218,7 @@
 i18n			Philipp Thomas		
 i18n			Joseph Myers		
 diagnostic messages	Dodji Seketeli		
+diagnostic messages	David Malcolm		
 build machinery (*.in)	Paolo Bonzini		
 build machinery (*.in)	DJ Delorie		
 build machinery (*.in)	Nathanael Nerode	


Re: extendqihi2 and GCC RTL type system

2016-02-22 Thread Jim Wilson
On Mon, Feb 22, 2016 at 7:55 AM, David Edelsohn  wrote:
> If I remove extendqihi2 (extend:HI pattern) from the PowerPC port,
> will that cause any problems for the GCC RTL type system or inhibit
> optimizations?   I see that Alpha and SPARC define extendqihi2, but
> IA-64 and AArch64 do not, so there is precedent for both approaches.

aarch64 does have an extendqihi2 pattern.  It uses so many iterator
macros that you can't use grep to look for stuff.  The extendqihi2
pattern is called qihi2.

If you have a target with registers larger than HImode, no HImode
register operations, qi/hi loads set the entire register, and you
define PROMOTE_MODE to convert all QImode and HImode operations to the
same larger mode with the same signedness, then I don't think that
there is any advantage to having an extendqihi2 pattern.  You should
get the same code with or without it, as a qimode to himode conversion
is a no-op.  The only difference should be that with an extendqihi2
pattern you will see some HImode operations in the RTL, without
extendqihi2 you will see equivalent operations in the promoted mode.

If you are concerned about this, then just try compiling some large
code base using two compilers, one with extendqihi2 and one without,
and check to see if there are any code generation differences.

Jim


Re: extendqihi2 and GCC RTL type system

2016-02-22 Thread David Edelsohn
Hi, Jim

On Mon, Feb 22, 2016 at 12:53 PM, Jim Wilson  wrote:
> On Mon, Feb 22, 2016 at 7:55 AM, David Edelsohn  wrote:
>> If I remove extendqihi2 (extend:HI pattern) from the PowerPC port,
>> will that cause any problems for the GCC RTL type system or inhibit
>> optimizations?   I see that Alpha and SPARC define extendqihi2, but
>> IA-64 and AArch64 do not, so there is precedent for both approaches.
>
> aarch64 does have an extendqihi2 pattern.  It uses so many iterator
> macros that you can't use grep to look for stuff.  The extendqihi2
> pattern is called qihi2.\

Thanks for the response.  I had missed the all-encompassing iterator for qidi2.

> If you have a target with registers larger than HImode, no HImode
> register operations, qi/hi loads set the entire register, and you
> define PROMOTE_MODE to convert all QImode and HImode operations to the
> same larger mode with the same signedness, then I don't think that
> there is any advantage to having an extendqihi2 pattern.  You should
> get the same code with or without it, as a qimode to himode conversion
> is a no-op.  The only difference should be that with an extendqihi2
> pattern you will see some HImode operations in the RTL, without
> extendqihi2 you will see equivalent operations in the promoted mode.
>
> If you are concerned about this, then just try compiling some large
> code base using two compilers, one with extendqihi2 and one without,
> and check to see if there are any code generation differences.

Segher did a quick sniff test on a large code base and found two minor
differences in code generation.  I wanted to check if there was any
more information than anecdotes.

Thanks, David


Re: Help about how to bootstrap gcc with local version glibc other than system one

2016-02-22 Thread Bin.Cheng
On Mon, Feb 1, 2016 at 7:45 PM, Jeff Law  wrote:
> On 02/01/2016 12:07 PM, Bin.Cheng wrote:
>>
>> On Mon, Feb 1, 2016 at 6:08 PM, Andreas Schwab 
>> wrote:
>>>
>>> "Bin.Cheng"  writes:
>>>
 Seems to me Andrew was right in comment of PR69559, that we simply
 couldn't bootstrap GCC with sysroot.
>>>
>>>
>>> The main use of sysroot is to build a cross compiler, which you cannot
>>> bootstrap anyway.
>>>
 My question here is: If this is the case, how should I bootstrap a gcc
 against local version glibc, rather than the system one?  Is chroot
 the only way to do that?
>>>
>>>
>>> Yes, building in a chroot or a VM is the best way to do it.  For
>>> example, that's how the openSUSE Build Service works.
>>
>> Hi Andreas,
>> Thanks very much for helping.  I will try to do it in chroot.
>
> Definitely what I'd recommend as well.
>
> We do this regularly with something called "mock" on Fedora.  I'm sure SuSE,
> Debian, Ubuntu, etc have an equivalent.
>
> Essentially they create a chroot, populate it with build dependencies
> extracted from the source package, then build within the chroot.  You can
> arrange to get a different glibc during instantiation of the chroot, or
> upgrade it after the chroot is fully instantiated.
Hi,
I still don't quite follow this method.  If I pop up chroot
environment with new glibc, it's still possible that the new glibc
isn't compatible with the default gcc in chroot.  Won't this a
chicken-egg problem because we want to build our gcc against new glibc
in the first place?

Thanks,
bin
>
> I'm sure there's a way to do this with containers too.
>
> jeff


Re: Help about how to bootstrap gcc with local version glibc other than system one

2016-02-22 Thread Jeff Law

On 02/22/2016 11:52 AM, Bin.Cheng wrote:

Hi,
I still don't quite follow this method.  If I pop up chroot
environment with new glibc, it's still possible that the new glibc
isn't compatible with the default gcc in chroot.  Won't this a
chicken-egg problem because we want to build our gcc against new glibc
in the first place?
If there's a fundamental incompatibility, then you have to bootstrap, 
similar to bootstrapping a new architecture.  That's rarely the case though.


Most of the time it's sufficient to use mock or similar tools in this 
manner to build a new glibc or new gcc.  You can then repeat using the 
just built glibc or gcc to catch any secondary effects.



jeff



Re: Need suggestion about bug 68425

2016-02-22 Thread Joseph Myers
On Sun, 21 Feb 2016, Prasad Ghangal wrote:

> -  pedwarn_init (loc, 0,
> -"excess elements in array initializer");
> +  pedwarn_init (loc, 0, "excess elements in array initializer "
> +  "(%lu elements, expected %lu)",
> +  tree_to_uhwi (constructor_index) + 1,
> +  tree_to_uhwi (constructor_max_index) + 1);

%lu is not correct for HOST_WIDE_INT.  You need to use %wu.

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


Re: How to use _Generic with bit-fields

2016-02-22 Thread Joseph Myers
I wonder if ISO C really ought to have a new Constraint "The controlling 
expression of a generic selection shall not be an expression that 
designates a bit-field member." (so requiring a diagnostic), much like 
such expressions being disallowed in sizeof, to reflect the special nature 
of bit-fields and their types in C.  Or, more weakly, to allow the cbrt 
example, "If the controlling expression of a generic selection is an 
expression that designates a bit-field member, it is unspecified whether 
the type of that expression is considered compatible with any integer 
types named in its generic association list.".

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


Re: How to use _Generic with bit-fields

2016-02-22 Thread Joseph Myers
On Mon, 22 Feb 2016, Wink Saville wrote:

> What about printing of "long" bit fields? I wonder if there should be an
> option which indicates that bit field types should not include their length.

"long" bit-fields aren't even guaranteed by ISO C to be supported at all; 
portable code must avoid them.  The portable way to print values of 
arbitrary integer types is to cast to intmax_t / uintmax_t and then use 
corresponding formats; that works fine with such bit-fields as well as 
normal types.

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


Re: How to use _Generic with bit-fields

2016-02-22 Thread Wink Saville
I understand "long" bit fields are in ISO, but its a gcc extension so
it would seem it should play nice with as much of the language as
possible.

It seems the root of the problem here is the length encoding
in the type, why does gcc do that, does the standard
require it?

On Mon, Feb 22, 2016 at 3:48 PM, Joseph Myers  wrote:
> On Mon, 22 Feb 2016, Wink Saville wrote:
>
>> What about printing of "long" bit fields? I wonder if there should be an
>> option which indicates that bit field types should not include their length.
>
> "long" bit-fields aren't even guaranteed by ISO C to be supported at all;
> portable code must avoid them.  The portable way to print values of
> arbitrary integer types is to cast to intmax_t / uintmax_t and then use
> corresponding formats; that works fine with such bit-fields as well as
> normal types.
>
> --
> Joseph S. Myers
> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-22 Thread Wink Saville
I'm sorry I meant:

I understand "long" bit lengths are NOT in ISO, "



On Mon, Feb 22, 2016 at 4:06 PM, Wink Saville  wrote:
> I understand "long" bit fields are in ISO, but its a gcc extension so
> it would seem it should play nice with as much of the language as
> possible.
>
> It seems the root of the problem here is the length encoding
> in the type, why does gcc do that, does the standard
> require it?
>
> On Mon, Feb 22, 2016 at 3:48 PM, Joseph Myers  wrote:
>> On Mon, 22 Feb 2016, Wink Saville wrote:
>>
>>> What about printing of "long" bit fields? I wonder if there should be an
>>> option which indicates that bit field types should not include their length.
>>
>> "long" bit-fields aren't even guaranteed by ISO C to be supported at all;
>> portable code must avoid them.  The portable way to print values of
>> arbitrary integer types is to cast to intmax_t / uintmax_t and then use
>> corresponding formats; that works fine with such bit-fields as well as
>> normal types.
>>
>> --
>> Joseph S. Myers
>> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-22 Thread Joseph Myers
On Mon, 22 Feb 2016, Wink Saville wrote:

> I understand "long" bit fields are in ISO, but its a gcc extension so
> it would seem it should play nice with as much of the language as
> possible.
> 
> It seems the root of the problem here is the length encoding
> in the type, why does gcc do that, does the standard
> require it?

See the previously identified analysis of the textual history, the various 
C90 and C99 DRs involved, and how (as noted in 1993 in DR#120, and as is 
still the case) there is *no definition whatever* in ISO C of what value 
would be stored in a bit-field by an assignment of a value out of range of 
an integer type with the given number of bits, other than through the 
rules for conversions, which only apply if you consider the bit-field to 
have the restricted-width type.  (And, if you wish, you could do the 
archaeology around the many bugs that were fixed in GCC by giving 
bit-fields types reflecting the values they could actually represent.)

The root of the "problem" is using the extension of bit-fields wider than 
int, a feature that simply doesn't fit well into the C language and has 
unintuitive consequences.

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


Re: How to use _Generic with bit-fields

2016-02-22 Thread Martin Sebor

On 02/21/2016 06:44 PM, Wink Saville wrote:

I've tried you hack, but it doesn't work with "long bit fields". Also,
I've run into another problem. Instead of using unsigned char for
the bit field I changed it to a long unsigned int:33 and now I can't
print it without a warning.


That's unfortunate.  As I suggested before, it would be useful to
add your test cases to bug 65471 to help bring them to the committee's
attention.  The bug submitter especially seems to be interested in
making the feature more useful and while he may not be reading this
list he is likely to notice the bug update.

The purpose of the generic selection in C is to provide a limited
form of function overloading.  Calling functions with bitfield
arguments is obviously useful regardless of the bit-field width
so it should "just work" with _Generic.  It does with other
compilers (Clang and the EDG front end) and there's no good reason
for the C standard not to support it.  (The problem is simply that
wording that specifies the feature was poorly chosen and GCC seems
to follow it a bit too strictly, and to the detriment of usability.)

I'm sorry but I can't think of a way to make this work the way you're
trying to.  Again, I encourage you to add it to the existing bug or
open a new one.

Martin

PS From some of the followups downthread it looks to me as though
the problem might be thought to be the bit-field width in your test
case exceeding that of int.  The following example shows that the
same problem error is reported even with a smaller bit-field.

$ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc 
-B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -xc z.c

struct S { unsigned i: 31; } s;
int i = _Generic (s.i, unsigned: 1);
z.c:2:19: error: ‘_Generic’ selector of type ‘unsigned int:31’ is not 
compatible with any association

 int i = _Generic (s.i, unsigned: 1);
   ^



Re: How to use _Generic with bit-fields

2016-02-22 Thread Joseph Myers
On Mon, 22 Feb 2016, Martin Sebor wrote:

> for the C standard not to support it.  (The problem is simply that
> wording that specifies the feature was poorly chosen and GCC seems
> to follow it a bit too strictly, and to the detriment of usability.)

The wording for bit-fields, although unclear in places, elegantly 
addresses all the issues with what the semantics of assignment to 
bit-fields are (including e.g. allowing an instruction for conversion of 
floating-point to 16-bit integer, complete with raising exceptions for 
out-of-range values, to be used to convert to int:16, rather than 
requiring a conversion to int and subsequent conversion from int to 
int:16), with none of the duplication that would be involved if bit-fields 
had the underlying types and so semantics for conversions needed to be 
specified separately.  It also naturally means that e.g. unsigned long:1 
promotes to int in expressions, by the normal rules for promotions.

> $ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc
> -B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -xc z.c
> struct S { unsigned i: 31; } s;
> int i = _Generic (s.i, unsigned: 1);
> z.c:2:19: error: ‘_Generic’ selector of type ‘unsigned int:31’ is not
> compatible with any association
>  int i = _Generic (s.i, unsigned: 1);
>^

That can be avoided simply by using unary + in the controlling expression 
of _Generic (just as using unary + will avoid an error from sizeof, if you 
want to be able to apply that to expressions that might be bit-fields) - 
or any of the other techniques for achieving promotions of selected types.

You can't use bit-fields with sizeof, or with unary &, or in GNU C with 
typeof.  I think extending this constraint to _Generic - meaning you need 
to use a trick such as unary + when a bit-field might occur there - is 
consistent with the peculiar position of bit-fields in C as not quite 
normal objects or types (and consistent with how _Generic is intended for 
certain limited kinds of overloading such as , not for 
arbitrarily expressive logic on types, cf. the rejection of overloading on 
qualifiers).  If someone uses e.g. unsigned int:8 as the controlling 
expression of _Generic, it's hardly clear whether a selection for unsigned 
char (a type with the same set of values), unsigned int (the declared type 
ignoring width) or int (the type resulting from the integer promotions) 
would be the most useful selection.

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

Re: How to use _Generic with bit-fields

2016-02-22 Thread Wink Saville
Joseph,

Thanks for the unary + suggestion.

It definitely makes sense that the bit field length must be known for
handling things like assignments, but it doesn't have to be part of
the type signature.


Martin,

I've updated bug 65471: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65471


I created a simpler test program:

$ cat test.c
#include 

struct S {
  int b0:4;
  unsigned int b1:4;
  unsigned long long int b33:33;
};

#define type2str(__x) _Generic((__x), \
  int : "int", \
  unsigned int : "unsigned int", \
  unsigned long long int : "unsigned long long int", \
  default : "unknown")

int main(void) {
  struct S s = { .b0=3, .b1=4, .b33=0x1 };
  (void)s; // Not used

   // gcc | clang output
  printf("type2str(s.b0):  %s\n", type2str(s.b0)); // unknown | int
  printf("type2str(s.b1):  %s\n", type2str(s.b1)); // unknown | unsigned int
  printf("type2str(s.b33): %s\n", type2str(s.b33));// unknown |
unsigned long long int

  return 0;
}

$ cat Makefile
CC = gcc
O = 3
STD = c11
M = 32

test: test.c Makefile
$(CC) -O$(O) -m$(M) -Wall -std=$(STD) test.c -o test

clean:
rm -f test



And ran it on gcc and clang

$ make clean ; make CC=gcc ; ./test
rm -f test
gcc -O3 -m32 -Wall -std=c11 test.c -o test
type2str(s.b0):  unknown
type2str(s.b1):  unknown
type2str(s.b33): unknown

$ make clean ;make CC=clang ; ./test
rm -f test
clang -O3 -m32 -Wall -std=c11 test.c -o test
type2str(s.b0):  int
type2str(s.b1):  unsigned int
type2str(s.b33): unsigned long long int


-- Wink


On Mon, Feb 22, 2016 at 4:58 PM, Joseph Myers  wrote:
> On Mon, 22 Feb 2016, Martin Sebor wrote:
>
>> for the C standard not to support it.  (The problem is simply that
>> wording that specifies the feature was poorly chosen and GCC seems
>> to follow it a bit too strictly, and to the detriment of usability.)
>
> The wording for bit-fields, although unclear in places, elegantly
> addresses all the issues with what the semantics of assignment to
> bit-fields are (including e.g. allowing an instruction for conversion of
> floating-point to 16-bit integer, complete with raising exceptions for
> out-of-range values, to be used to convert to int:16, rather than
> requiring a conversion to int and subsequent conversion from int to
> int:16), with none of the duplication that would be involved if bit-fields
> had the underlying types and so semantics for conversions needed to be
> specified separately.  It also naturally means that e.g. unsigned long:1
> promotes to int in expressions, by the normal rules for promotions.
>
>> $ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc
>> -B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -xc z.c
>> struct S { unsigned i: 31; } s;
>> int i = _Generic (s.i, unsigned: 1);
>> z.c:2:19: error: ‘_Generic’ selector of type ‘unsigned int:31’ is not
>> compatible with any association
>>  int i = _Generic (s.i, unsigned: 1);
>>^
>
> That can be avoided simply by using unary + in the controlling expression
> of _Generic (just as using unary + will avoid an error from sizeof, if you
> want to be able to apply that to expressions that might be bit-fields) -
> or any of the other techniques for achieving promotions of selected types.
>
> You can't use bit-fields with sizeof, or with unary &, or in GNU C with
> typeof.  I think extending this constraint to _Generic - meaning you need
> to use a trick such as unary + when a bit-field might occur there - is
> consistent with the peculiar position of bit-fields in C as not quite
> normal objects or types (and consistent with how _Generic is intended for
> certain limited kinds of overloading such as , not for
> arbitrarily expressive logic on types, cf. the rejection of overloading on
> qualifiers).  If someone uses e.g. unsigned int:8 as the controlling
> expression of _Generic, it's hardly clear whether a selection for unsigned
> char (a type with the same set of values), unsigned int (the declared type
> ignoring width) or int (the type resulting from the integer promotions)
> would be the most useful selection.
>
> --
> Joseph S. Myers
> jos...@codesourcery.com