This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Release novops attribute for external use?


Thanks! I forgot to declare the function as pure. The empty asm
seems to be a clever trick to avoid function being optimized out.
I shall tell our engineers to use this instead of implementing a new 
attribute. 

Bingfeng

> -----Original Message-----
> From: Richard Guenther [mailto:richard.guenther@gmail.com] 
> Sent: 13 April 2010 11:25
> To: Bingfeng Mei
> Cc: Andrew Haley; gcc@gcc.gnu.org
> Subject: Re: Release novops attribute for external use?
> 
> On Tue, Apr 13, 2010 at 12:23 PM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
> > On Tue, Apr 13, 2010 at 12:15 PM, Bingfeng Mei 
> <bmei@broadcom.com> wrote:
> >>>
> >>> Surely printf writes to global memory (it clobbers the 
> stdout FILE*)
> >>>
> >> OK, the point is not about whether printf is pure or not. 
> Instead, if
> >> programmer knows the callee function such as printf contains no
> >> memory access that affects operations inside caller 
> function, and he
> >> would like to have a way to optimize the code. Our 
> engineer gave following
> >> example:
> >>
> >> ? ?void myfunc(MyStruct *myStruct)
> >> ? ?{
> >> ? ? ?int a,b;
> >> ? ? ?a = myStruct->a;
> >> ? ? ?printf("a=%d\n",a);
> >> ? ? ?b = 2*mystruct->a; ? ? ?// I would like to have the 
> compiler acting as if I had written b = 2*a;
> >> ? ? ...
> >> ? ?}
> >> Providing such attribute may be potentially dangerous. But 
> it is just
> >> like "restrict" qualifier and some other attributes, 
> putting responsibilty
> >> of correctness on the programmer. "novops" seems to 
> achieve that effect,
> >> though its semantics doesn't match exactly what I described.
> >
> > Indeed. ?IPA pointer analysis will probably figure it out
> > automagically - that *myStruct didn't escape the unit.
> > Being able to annotate incoming pointers this way would
> > maybe be useful.
> >
> >>> As for the original question - novops is internal only because its
> >>> semantics is purely internal and changes with internal aliasing
> >>> changes.
> >>>
> >>> Now, we still lack a compelling example to see what exact 
> semantics
> >>> you are requesting? ?I suppose it might be close to a pure but
> >>> volatile function? ?Which you could simulate by
> >>>
> >>> dummy = pure_fn ();
> >>> asm ("" : "g" (dummy));
> >>>
> >>> or even
> >>>
> >>> volatile int dummy = pure_fn ();
> >>
> >> These two methods still generate extra code to reload variables
> >
> > The latter works for me (ok, the store to dummy is retained):
> >
> > extern int myprintf(int) __attribute__((pure));
> > int myfunc (int *p)
> > {
> > ?int a;
> > ?a = *p;
> > ?volatile int dummy = myprintf(a);
> > ?return a + *p;
> > }
> >
> > myfunc:
> > .LFB0:
> > ? ? ? ?pushq ? %rbx
> > .LCFI0:
> > ? ? ? ?subq ? ?$16, %rsp
> > .LCFI1:
> > ? ? ? ?movl ? ?(%rdi), %ebx
> > ? ? ? ?movl ? ?%ebx, %edi
> > ? ? ? ?call ? ?myprintf
> > ? ? ? ?movl ? ?%eax, 12(%rsp)
> > ? ? ? ?leal ? ?(%rbx,%rbx), %eax
> > ? ? ? ?addq ? ?$16, %rsp
> > .LCFI2:
> > ? ? ? ?popq ? ?%rbx
> > .LCFI3:
> > ? ? ? ?ret
> >
> > so we load from %rdi only once.
> 
> And
> 
> extern int myprintf(int) __attribute__((pure));
> int myfunc (int *p)
> {
>   int a;
>   a = *p;
>   int dummy = myprintf(a);
>   asm ("" : : "g" (dummy));
>   return a + *p;
> }
> 
> produces
> 
> myfunc:
> .LFB0:
>         pushq   %rbx
> .LCFI0:
>         movl    (%rdi), %ebx
>         movl    %ebx, %edi
>         call    myprintf
>         leal    (%rbx,%rbx), %eax
>         popq    %rbx
> .LCFI1:
>         ret
> 
> even better.
> 
> Richard.
> 
> 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]