Re: Aggressive load in gcc when accessing escaped pointer?

2016-03-18 Thread Cy Cheng
:D

But I don't understand why &c - 8 is invalid? Which rule in C99 it volatile?

That's see the example again with some changes:

// Now, I make c point to &c - 8
PB** bar(PB** t) {
  char* ptr = (char*)t;
  *t = (PB*)(ptr-8);
}

void qux(PB* c) {
  PB* cc;
  bar(&c);

  c->f1_ = 0;// invalid

  cc = c;
  cc->f1_ = 0;  // valid or invalid?
}

My question is, if &c - 8 is an invalid address, then it looks like
cc->f1_ = 0 will be an invalid operation? Or &c - 8 is only invalid in
terms of c, not cc?

(By the way, we also discuss the pattern in llvm mailing list:
https://goo.gl/VHK0dN)

2016-03-19 2:46 GMT+08:00 Richard Biener :
> On March 18, 2016 3:26:37 PM GMT+01:00, Markus Trippelsdorf 
>  wrote:
>>On 2016.03.18 at 22:05 +0800, Cy Cheng wrote:
>>> Hi,
>>>
>>> Please look at this c code:
>>>
>>> typedef struct _PB {
>>>   void* data;  /* required.*/
>>>   int   f1_;
>>>   float f2_;
>>> } PB;
>>>
>>> PB** bar(PB** t);
>>>
>>> void qux(PB* c) {
>>>   bar(&c);  /* c is escaped because of bar */
>>>   c->f1_ = 0;
>>>   c->f2_ = 0.f;
>>> }
>>>
>>> // gcc-5.2.1 with -fno-strict-aliasing -O2 on x86
>>> callbar
>>> movq8(%rsp), %rax  <= load pointer c
>>> movl$0, 8(%rax)
>>> movl$0x, 12(%rax)
>>>
>>> // intel-icc-13.0.1 with -fno-strict-aliasing -O2 on x86
>>> call  bar(_PB**)
>>> movq  (%rsp), %rdx  <= load pointer c
>>> movl  %ecx, 8(%rdx)
>>> movq  (%rsp), %rsi   <= load pointer c
>>> movl  %ecx, 12(%rsi)
>>>
>>> GCC only load pointer c once, but if I implement bar in such way:
>>> PB** bar(PB** t) {
>>>   char* ptr = (char*)t;
>>>   *t = (PB*)(ptr-8);
>>>return t;
>>> }
>>>
>>> Does this volatile C99 standard rule
>>> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf):
>>>
>>>6.5.16 Assignment operators
>>>
>>>"3. ... The side effect of updating the stored value of the left
>>operand
>>> shall occur between the previous and the next sequence point."
>>
>>No. We discussed this on IRC today and Richard Biener pointed out that
>>bar cannot make c point to &c - 8, because computing that pointer would
>>be invalid. So c->f1_ cannot clobber c itself.
>
> Nice to see that only GCC gets this optimization opportunity :)
>
> Richard.
>


Re: Aggressive load in gcc when accessing escaped pointer?

2016-03-18 Thread Markus Trippelsdorf
On 2016.03.18 at 22:05 +0800, Cy Cheng wrote:
> Hi,
> 
> Please look at this c code:
> 
> typedef struct _PB {
>   void* data;  /* required.*/
>   int   f1_;
>   float f2_;
> } PB;
> 
> PB** bar(PB** t);
> 
> void qux(PB* c) {
>   bar(&c);  /* c is escaped because of bar */
>   c->f1_ = 0;
>   c->f2_ = 0.f;
> }
> 
> // gcc-5.2.1 with -fno-strict-aliasing -O2 on x86
> callbar
> movq8(%rsp), %rax  <= load pointer c
> movl$0, 8(%rax)
> movl$0x, 12(%rax)
> 
> // intel-icc-13.0.1 with -fno-strict-aliasing -O2 on x86
> call  bar(_PB**)
> movq  (%rsp), %rdx  <= load pointer c
> movl  %ecx, 8(%rdx)
> movq  (%rsp), %rsi   <= load pointer c
> movl  %ecx, 12(%rsi)
> 
> GCC only load pointer c once, but if I implement bar in such way:
> PB** bar(PB** t) {
>   char* ptr = (char*)t;
>   *t = (PB*)(ptr-8);
>return t;
> }
> 
> Does this volatile C99 standard rule
> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf):
> 
>6.5.16 Assignment operators
> 
>"3. ... The side effect of updating the stored value of the left operand
> shall occur between the previous and the next sequence point."

No. We discussed this on IRC today and Richard Biener pointed out that
bar cannot make c point to &c - 8, because computing that pointer would
be invalid. So c->f1_ cannot clobber c itself. 

-- 
Markus


Re: Aggressive load in gcc when accessing escaped pointer?

2016-03-18 Thread Richard Biener
On March 18, 2016 3:26:37 PM GMT+01:00, Markus Trippelsdorf 
 wrote:
>On 2016.03.18 at 22:05 +0800, Cy Cheng wrote:
>> Hi,
>> 
>> Please look at this c code:
>> 
>> typedef struct _PB {
>>   void* data;  /* required.*/
>>   int   f1_;
>>   float f2_;
>> } PB;
>> 
>> PB** bar(PB** t);
>> 
>> void qux(PB* c) {
>>   bar(&c);  /* c is escaped because of bar */
>>   c->f1_ = 0;
>>   c->f2_ = 0.f;
>> }
>> 
>> // gcc-5.2.1 with -fno-strict-aliasing -O2 on x86
>> callbar
>> movq8(%rsp), %rax  <= load pointer c
>> movl$0, 8(%rax)
>> movl$0x, 12(%rax)
>> 
>> // intel-icc-13.0.1 with -fno-strict-aliasing -O2 on x86
>> call  bar(_PB**)
>> movq  (%rsp), %rdx  <= load pointer c
>> movl  %ecx, 8(%rdx)
>> movq  (%rsp), %rsi   <= load pointer c
>> movl  %ecx, 12(%rsi)
>> 
>> GCC only load pointer c once, but if I implement bar in such way:
>> PB** bar(PB** t) {
>>   char* ptr = (char*)t;
>>   *t = (PB*)(ptr-8);
>>return t;
>> }
>> 
>> Does this volatile C99 standard rule
>> (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf):
>> 
>>6.5.16 Assignment operators
>> 
>>"3. ... The side effect of updating the stored value of the left
>operand
>> shall occur between the previous and the next sequence point."
>
>No. We discussed this on IRC today and Richard Biener pointed out that
>bar cannot make c point to &c - 8, because computing that pointer would
>be invalid. So c->f1_ cannot clobber c itself. 

Nice to see that only GCC gets this optimization opportunity :)

Richard.



Re: [GCC Wiki] Update of "DebugFission" by CaryCoutant

2016-03-18 Thread Thomas Schwinge
Hi Cary!

On Thu, 16 May 2013 16:58:12 -, GCC Wiki  wrote:
> The "DebugFission" page has been changed by CaryCoutant:
> http://gcc.gnu.org/wiki/DebugFission?action=diff&rev1=18&rev2=19
> 
>   = DWARF Extensions for Separate Debug Information Files =
>   
>   Updated January 24, 2013
> + 
> + The "Fission" project was started in response to the problems caused by 
> huge amounts of debug information in large applications. By splitting the 
> debug information into two parts at compile time -- one part that remains in 
> the .o file and another part that is written to a parallel .dwo ("DWARF 
> object") file -- we can reduce the total size of the object files processed 
> by the linker.

Yay, a quite noticeable link-time speedup!  \o/

> + Fission is implemented in GCC 4.7, and requires support from recent 
> versions of objcopy and the gold linker.

Is my understanding correct that the gold linker is not actually a
requirement -- at least nowadays?  In my (very limited, so far) testing,
this also seems to work with ld.bfd.  (I do see objcopy's --extract-dwo
and --split-dwo options being used in gcc/gcc.c:ASM_FINAL_SPEC, so I
suspect that's what "recent versions of objcopy" hints at?)

> + Use the {{{-gsplit-dwarf}}} option to enable the generation of split DWARF 
> at compile time. This option must be used in conjunction with {{{-c}}}; 
> Fission cannot be used when compiling and linking in the same step.

According to the following -- admittedly very minimal -- testing, this is
not actually (no longer?) true?

$ [gcc] [...] -gsplit-dwarf
$ ls *.dwo
ccF9JYjE.dwo  subroutines.dwo
$ gdb -q a.out 
Reading symbols from a.out...done.
(gdb) list main
[...]
(gdb) quit
$ rm *.dwo
$ gdb -q a.out 
Reading symbols from a.out...
warning: Could not find DWO CU subroutines.dwo(0x2d85cdd539df6900) 
referenced by CU at offset 0x0 [in module [...]/a.out]

warning: Could not find DWO CU ccF9JYjE.dwo(0xa6936555a636518) referenced 
by CU at offset 0x35 [in module [...]/a.out]
done.
(gdb) list main
warning: Could not find DWO CU subroutines.dwo(0x2d85cdd539df6900) 
referenced by CU at offset 0x0 [in module [...]/a.out]

Have I been testing the wrong thing?

> + Use the gold linker's {{{--gdb-index}}} option ({{{-Wl,--gdb-index}}} when 
> linking with gcc or g++) at link time to create the .gdb_index section that 
> allows GDB to locate and read the .dwo files as it needs them.

Unless told otherwise, I'll re-word that to the effect that gold, and
usage of its --gdb-index option are optional.


Grüße
 Thomas


signature.asc
Description: PGP signature