Re: Constexpr in intrinsics?
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
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
* 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
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
> 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
* 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
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)?
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
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)?
> 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)?
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