Re: Constexpr in intrinsics?

2016-03-28 Thread Marc Glisse

On Mon, 28 Mar 2016, Allan Sandfeld Jensen wrote:


On Sunday 27 March 2016, Marc Glisse wrote:

On Sun, 27 Mar 2016, Allan Sandfeld Jensen wrote:

Would it be possible to add constexpr to the intrinsics headers?

For instance _mm_set_XX and _mm_setzero intrinsics.


Already suggested here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65197

A patch would be welcome (I started doing it at some point, I don't
remember if it was functional, the patch is attached).


That looks very similar to the patch I experimented with, and that at least
works for using them in C++11 constexpr functions.


Ideally it could also be added all intrinsics that can be evaluated at
compile time, but it is harder to tell which those are.

Does gcc have a C extension we can use to set constexpr?


What for?


To have similar functionality in C. For instance to explicitly allow those
functions to be evaluated at compile time, and values with similar attributes
be optimized completely out.


Those intrinsics that are implemented without builtins can already be 
evaluated at compile time.


#include 

__m128d f(){
  __m128d a=_mm_set_pd(1,2);
  __m128d b=_mm_setr_pd(4,3);
  return _mm_add_pd(a, b);
}

The generated asm is just

movapd  .LC0(%rip), %xmm0
ret

For the more esoteric intrinsics, what is missing is not in the parser, it 
is a folder that understands the behavior of each particular intrinsic.



And of course avoid using precompiler noise, in
shared C/C++ headers like these are.


--
Marc Glisse


Re: Spurious register spill with volatile function argument

2016-03-28 Thread Andrew Haley
On 27/03/16 06:57, Michael Clark wrote:

> GCC, Clang folk, any ideas on why there is a stack spill for a
> volatile register argument passed in esi? Does volatile force the
> argument to have storage allocated on the stack? Is this a corner
> case in the C standard? This argument in the x86_64 calling
> convention only has a register, so technically it can’t change
> outside the control of the C "virtual machine” so volatile has a
> vague meaning here.

"volatile" doesn't really mean very much, formally speaking.  Sure, the
standard says "accesses to volatile objects are evaluated
strictly according to the rules of the abstract machine," but nowhere
is it specified exactly what constitutes an access.  (To be precise,
"what constitutes an access to an object that has volatile-qualified
type is implementation-defined.")

So, we have to fall back to tradition.  Traditionally, all volatile
objects are allocated stack slots and all accesses to them are memory
accesses.  This is consistent behaviour, and has been for a long time.
It is also extremely useful when debugging optimized code.

> volatile for scalar function arguments seems to mean: “make this
> volatile and subject to change outside of the compiler” rather than
> being a qualifier for its storage (which is a register).

No, arguments are not necessarily stored in registers: they're passed
in registers, but after function entry function they're just auto
variables and are stored wherever the compiler likes.

Andrew.


Re: Spurious register spill with volatile function argument

2016-03-28 Thread Florian Weimer
* Andrew Haley:

> "volatile" doesn't really mean very much, formally speaking.  Sure, the
> standard says "accesses to volatile objects are evaluated
> strictly according to the rules of the abstract machine," but nowhere
> is it specified exactly what constitutes an access.

Reading or modifying an object is defined as “access”.

The problem is that “reading” is either not defined, or the existing
flatly contradicts existing practice.

For example, if p is a pointer to a struct, will the expression &p->m
read *p?

Previously, this wasn't very interesting.  But under the model memory,
it's suddenly quite relevant.  If reading p->m implies a read of the
entire object *p, you cannot use a member to synchronize access to
other members of the struct.  For example, if m is a mutex, and
carefully acquire the mutex before you read or write other members,
you still have data race between a write to some other member and the
acquisition of the mutex because the mutex acquisition reads the
entire struct (including the member written to ).

One possible cure is to take the address of the mutex and keep track
of it separately.  Or you could construct a pointer using offsetof.
But no one is doing that, obviously.

This is not entirely hypothetical.  Even today, GCC's aliasing
analysis requires that those implicit whole-object reads take place,
to make certain forms of type-punning invalid which would otherwise be
well-defined (and for which GCC would generate invalid code).


regression in C++ parsing performance between 4.9.3 and 5.3.1

2016-03-28 Thread Pádraig Brady

The attached shell script will generate a larger version
of the following:

constexpr bool static_str_equal(const char* x, const char* y) {
  return (*x == 0 || *y == 0) ?
(*x == *y) :
((*x == *y) && static_str_equal(x + 1, y + 1));
}
int main(void)
{
 static_assert( !static_str_equal("unspecified1", "unspecified"), "");
}

There is a significant slow down and increase in ram usage
compiling that, between gcc 4.9.3 and 5.3.1 (20151207):

$ sh cstrcmp.sh > cstrcmp.cpp
$ ~/gcc-4.9.3/g++ -ftime-report --std=gnu++11 cstrcmp.cpp

Execution times (seconds)
 phase setup :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.01 ( 1%) wall  
  1445 kB ( 1%) ggc
 phase parsing   :   0.91 (100%) usr   0.16 (100%) sys   1.08 (99%) 
wall  149089 kB (99%) ggc
 |name lookup:   0.03 ( 3%) usr   0.00 ( 0%) sys   0.02 ( 2%) wall  
89 kB ( 0%) ggc
 |overload resolution:   0.01 ( 1%) usr   0.00 ( 0%) sys   0.02 ( 2%) wall  
   628 kB ( 0%) ggc
 preprocessing   :   0.02 ( 2%) usr   0.05 (31%) sys   0.04 ( 4%) wall  
  2048 kB ( 1%) ggc
 parser (global) :   0.02 ( 2%) usr   0.03 (19%) sys   0.08 ( 7%) wall  
 16178 kB (11%) ggc
 parser function body:   0.87 (96%) usr   0.08 (50%) sys   0.96 (88%) wall  
130855 kB (87%) ggc
 TOTAL :   0.91 0.16 1.09 
150594 kB

$ g++ -ftime-report --std=gnu++11 cstrcmp.cpp  # default fedora version

Execution times (seconds)
 phase setup :   0.00 ( 0%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall  
  1408 kB ( 0%) ggc
 phase parsing   :   1.90 (99%) usr   0.26 (100%) sys   2.16 (100%) 
wall  469089 kB (100%) ggc
 phase opt and generate  :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall  
53 kB ( 0%) ggc
 |name lookup:   0.04 ( 2%) usr   0.00 ( 0%) sys   0.05 ( 2%) wall  
93 kB ( 0%) ggc
 |overload resolution:   0.01 ( 1%) usr   0.00 ( 0%) sys   0.00 ( 0%) wall  
   628 kB ( 0%) ggc
 garbage collection  :   0.20 (10%) usr   0.02 ( 8%) sys   0.21 (10%) wall  
 0 kB ( 0%) ggc
 preprocessing   :   0.01 ( 1%) usr   0.05 (19%) sys   0.08 ( 4%) wall  
  2048 kB ( 0%) ggc
 parser (global) :   0.02 ( 1%) usr   0.04 (15%) sys   0.05 ( 2%) wall  
 16181 kB ( 3%) ggc
 parser function body:   1.67 (87%) usr   0.15 (58%) sys   1.82 (84%) wall  
450852 kB (96%) ggc
 integrated RA   :   0.01 ( 1%) usr   0.00 ( 0%) sys   0.01 ( 0%) wall  
24 kB ( 0%) ggc
 TOTAL :   1.91 0.26 2.17 
470569 kB

Note I compiled the gcc 5 branch at 20160302 with the same results.

thanks,
Pádraig


cstrcmp.sh
Description: Bourne shell script


Re: Spurious register spill with volatile function argument

2016-03-28 Thread Paul_Koning

> On Mar 28, 2016, at 8:11 AM, Florian Weimer  wrote:
> 
> ...
> The problem is that “reading” is either not defined, or the existing
> flatly contradicts existing practice.
> 
> For example, if p is a pointer to a struct, will the expression &p->m
> read *p?

Presumably the offset of m is substantially larger than 0?  If so, my answer 
would be "it had better not".  Does any compiler treat that statement as an 
access to *p ?

paul


Re: Spurious register spill with volatile function argument

2016-03-28 Thread Florian Weimer
* Paul Koning:

>> On Mar 28, 2016, at 8:11 AM, Florian Weimer  wrote:
>> 
>> ...
>> The problem is that “reading” is either not defined, or the existing
>> flatly contradicts existing practice.
>> 
>> For example, if p is a pointer to a struct, will the expression &p->m
>> read *p?
>
> Presumably the offset of m is substantially larger than 0?  If so, my
> answer would be "it had better not".  Does any compiler treat that
> statement as an access to *p ?

As I tried to explain, GCC does, for aliasing purposes.  For the
expression p->m, there is an implicit read of *p, asserting that the
static and dynamic types match.


Compute all gimple statements in which a var is used

2016-03-28 Thread Cristina Georgiana Opriceana
Hello,

In order to compute all the statements where a variable is used, is it
enough to rely on the SSA analysis? I tried to do something like this:

FOR_EACH_LOCAL_DECL (cfun, i, var) {
for (unsigned int i = 0; i < num_ssa_names; i++) {
if (ssa_name(i) && SSA_NAME_VAR (ssa_name(i)) == var) {
tree ssa_node = ssa_name(i);
FOR_EACH_IMM_USE_FAST (use_op, imm_iter, ssa_node) {
gimple * use_stmt = USE_STMT(use_op);
...
}

Thanks,
Cristina


Should a disabled warning be allowed to be promoted to an error(Bugzilla PR 70275)?

2016-03-28 Thread kevin-tucker
In Bugzilla PR # 70275, Manuel López-Ibáñez reports that even though he 
provides the "-Werror=return-type" option, the compiler doesn't flag the 
warning/error about a control reaching the end of a non-void function, due to 
the presence of the "-w" option.  He points out that clang++ wtill flags the 
promoted warning even though warnings are inhibited.

I'm thinking that not reporting the promoted error is the correct and desired 
behavior, based on two factors:
1) Warnings are inhibited, so there is no warning to promote.

2) The comment in diagnostic.c which reads:
/* Give preference to being able to inhibit warnings, before they
 get reclassified to something else.  */

I was looking at this issue as one I could use to get my feet wet in GCC 
maintenance , and would be glad to take on if it is decided that it is 
desired, which I would argue that it is not, but I thought I'd open up 
discussion on the topic.

I have worked on the MIcrochip PIC18 C compiler, and worked for DDC-I, 
supporting their compiler suites,(Ada, C/C++) as well as some work on the ASIS 
standard, and thought it might be fun to work on GCC.


Looking forward to reading discussion on the topic!

Kevin Tucker



Re: Compute all gimple statements in which a var is used

2016-03-28 Thread Richard Biener
On March 28, 2016 7:23:26 PM GMT+02:00, Cristina Georgiana Opriceana 
 wrote:
>Hello,
>
>In order to compute all the statements where a variable is used, is it
>enough to rely on the SSA analysis? I tried to do something like this:
>
>FOR_EACH_LOCAL_DECL (cfun, i, var) {
>for (unsigned int i = 0; i < num_ssa_names; i++) {
>if (ssa_name(i) && SSA_NAME_VAR (ssa_name(i)) == var) {
>tree ssa_node = ssa_name(i);
>FOR_EACH_IMM_USE_FAST (use_op, imm_iter, ssa_node) {
>gimple * use_stmt = USE_STMT(use_op);
>...
>}

No, you'll miss variables not in SSA form.

Richard.

>Thanks,
>Cristina




Re: Should a disabled warning be allowed to be promoted to an error(Bugzilla PR 70275)?

2016-03-28 Thread Florian Weimer
> In Bugzilla PR # 70275, Manuel López-Ibáñez reports that even though
> he provides the "-Werror=return-type" option, the compiler doesn't
> flag the warning/error about a control reaching the end of a non-void
> function, due to the presence of the "-w" option.  He points out that
> clang++ wtill flags the promoted warning even though warnings are
> inhibited.

I think -w is ordered with respect to the other warning obtions, and
-w inhibits previously requested warnings, and future -W flags may
enable other warnings.  With this in mind, I agree that the current
GCC behavior is consistent and probably not a bug.


Re: Should a disabled warning be allowed to be promoted to an error(Bugzilla PR 70275)?

2016-03-28 Thread Martin Sebor

On 03/28/2016 01:56 PM, Florian Weimer wrote:

In Bugzilla PR # 70275, Manuel López-Ibáñez reports that even though
he provides the "-Werror=return-type" option, the compiler doesn't
flag the warning/error about a control reaching the end of a non-void
function, due to the presence of the "-w" option.  He points out that
clang++ wtill flags the promoted warning even though warnings are
inhibited.


I think -w is ordered with respect to the other warning obtions, and
-w inhibits previously requested warnings, and future -W flags may
enable other warnings.  With this in mind, I agree that the current
GCC behavior is consistent and probably not a bug.


The general rule of thumb documented in the manual is that more
specific options take precedence over more general ones, regardless
of where they appear on the command line:

  The combined effect of positive and negative forms [of warning
  options] is that more specific options have priority over less
  specific ones, independently of their position in the command-
  line.

The manual doesn't give an exhaustive list of the more general
options but it mentions -Wall and -Wextra as examples.  I would
tend to view -w as another such example and, like the reporter,
expect "-Werror=return-type -w" to disable all warnings but treat
-Wreturn-type as an error.

Martin