public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* How can I tune gcc to move up simple common subexpression?
@ 2013-11-08  9:28 Konstantin Vladimirov
  2013-11-08 10:06 ` Richard Biener
  2013-11-08 20:21 ` Jeff Law
  0 siblings, 2 replies; 4+ messages in thread
From: Konstantin Vladimirov @ 2013-11-08  9:28 UTC (permalink / raw)
  To: gcc, gcc-help

Hi,

Consider simple code:

typedef struct
{
  unsigned prev;
  unsigned next;
} foo_t;

void
foo( unsigned x, unsigned y)
  {
    foo_t *ptr = (foo_t *)((void *)x);

    if (y != 0)
      {
         ptr->prev = y;
         ptr->next = x;
       }
     else
       {
         ptr->prev = 0; /* or explicitly ptr->prev = y; no difference */
         ptr->next = 0;
       }
}

GCC 4.7.2 and 4.8.1 both on O2 and Os creates code like:

testl %esi, %esi
movl %edi, %eax
jne .L5
movl $0, (%edi)
movl $0, 4(%rax)
ret
.L5:
movl %esi, (%edi)
movl %edi, 4(%rax)
ret

Which can be obviously changed to:

testl %esi, %esi
movl %edi, %eax
movl %esi, (%edi)
jne .L5
movl $0, 4(%rax)
ret
.L5:
movl %edi, 4(%rax)
ret

May be there are some options to make it behave so? This is question
for gcc-help group.

Question for gcc group is trickier:

May be in x86 it is not a big deal, but I am working on my private
backend, that have predicated instructions and second form is really
much more prefferable. May be I can somehow tune my backend to achieve
this effect? I can see that 210r.csa pass (try_optimize_cfg before it,
not pass itself) can move code upper in  some cases, but only with
very simple memory addressing and rather unstable, say changing

         ptr->prev = y;
         ptr->next = x;

to

         ptr->prev = x;
         ptr->next = y;

may break everything just because next is second member and addressed
like M[%r+4].

Any ideas?

---
With best regards, Konstantin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: How can I tune gcc to move up simple common subexpression?
  2013-11-08  9:28 How can I tune gcc to move up simple common subexpression? Konstantin Vladimirov
@ 2013-11-08 10:06 ` Richard Biener
  2013-11-08 20:21 ` Jeff Law
  1 sibling, 0 replies; 4+ messages in thread
From: Richard Biener @ 2013-11-08 10:06 UTC (permalink / raw)
  To: Konstantin Vladimirov; +Cc: GCC Development, GCC-help

On Fri, Nov 8, 2013 at 10:28 AM, Konstantin Vladimirov
<konstantin.vladimirov@gmail.com> wrote:
> Hi,
>
> Consider simple code:
>
> typedef struct
> {
>   unsigned prev;
>   unsigned next;
> } foo_t;
>
> void
> foo( unsigned x, unsigned y)
>   {
>     foo_t *ptr = (foo_t *)((void *)x);
>
>     if (y != 0)
>       {
>          ptr->prev = y;
>          ptr->next = x;
>        }
>      else
>        {
>          ptr->prev = 0; /* or explicitly ptr->prev = y; no difference */
>          ptr->next = 0;
>        }
> }
>
> GCC 4.7.2 and 4.8.1 both on O2 and Os creates code like:
>
> testl %esi, %esi
> movl %edi, %eax
> jne .L5
> movl $0, (%edi)
> movl $0, 4(%rax)
> ret
> .L5:
> movl %esi, (%edi)
> movl %edi, 4(%rax)
> ret
>
> Which can be obviously changed to:
>
> testl %esi, %esi
> movl %edi, %eax
> movl %esi, (%edi)
> jne .L5
> movl $0, 4(%rax)
> ret
> .L5:
> movl %edi, 4(%rax)
> ret
>
> May be there are some options to make it behave so? This is question
> for gcc-help group.
>
> Question for gcc group is trickier:
>
> May be in x86 it is not a big deal, but I am working on my private
> backend, that have predicated instructions and second form is really
> much more prefferable. May be I can somehow tune my backend to achieve
> this effect? I can see that 210r.csa pass (try_optimize_cfg before it,
> not pass itself) can move code upper in  some cases, but only with
> very simple memory addressing and rather unstable, say changing
>
>          ptr->prev = y;
>          ptr->next = x;
>
> to
>
>          ptr->prev = x;
>          ptr->next = y;
>
> may break everything just because next is second member and addressed
> like M[%r+4].
>
> Any ideas?

IIRC there is some code hoisting in RTL GCSE but not very strong.
code-hoisting in GIMPLE via PRE is still in-progress (see PR23286).

Richard.

> ---
> With best regards, Konstantin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: How can I tune gcc to move up simple common subexpression?
  2013-11-08  9:28 How can I tune gcc to move up simple common subexpression? Konstantin Vladimirov
  2013-11-08 10:06 ` Richard Biener
@ 2013-11-08 20:21 ` Jeff Law
  2013-11-11 11:36   ` Richard Biener
  1 sibling, 1 reply; 4+ messages in thread
From: Jeff Law @ 2013-11-08 20:21 UTC (permalink / raw)
  To: Konstantin Vladimirov, gcc, gcc-help

On 11/08/13 02:28, Konstantin Vladimirov wrote:
> typedef struct
> {
>    unsigned prev;
>    unsigned next;
> } foo_t;
>
> void
> foo( unsigned x, unsigned y)
>    {
>      foo_t *ptr = (foo_t *)((void *)x);
>
>      if (y != 0)
>        {
>           ptr->prev = y;
>           ptr->next = x;
>         }
>       else
>         {
>           ptr->prev = 0; /* or explicitly ptr->prev = y; no difference */
>           ptr->next = 0;
>         }
> }
Umm, you can't hoist ptr->prev before the conditional because that would 
change the meaning of this code.


I think you wanted the conditional to test y == 0 which exposes the code 
hoisting opportunity for the ptr->prev assignment.  Once you fix the 
testcase the code in jump2 will hoist the assignment resulting in:





         .cfi_startproc
         testl   %esi, %esi
         movl    %edi, %eax
         movl    $0, (%edi)
         je      .L5
         movl    $0, 4(%rax)
         ret
         .p2align 4,,10
         .p2align 3
.L5:
         movl    %edi, 4(%rax)
         ret
         .cfi_endproc


Jeff

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: How can I tune gcc to move up simple common subexpression?
  2013-11-08 20:21 ` Jeff Law
@ 2013-11-11 11:36   ` Richard Biener
  0 siblings, 0 replies; 4+ messages in thread
From: Richard Biener @ 2013-11-11 11:36 UTC (permalink / raw)
  To: Jeff Law; +Cc: Konstantin Vladimirov, GCC Development, GCC-help

On Fri, Nov 8, 2013 at 9:21 PM, Jeff Law <law@redhat.com> wrote:
> On 11/08/13 02:28, Konstantin Vladimirov wrote:
>>
>> typedef struct
>> {
>>    unsigned prev;
>>    unsigned next;
>> } foo_t;
>>
>> void
>> foo( unsigned x, unsigned y)
>>    {
>>      foo_t *ptr = (foo_t *)((void *)x);
>>
>>      if (y != 0)
>>        {
>>           ptr->prev = y;
>>           ptr->next = x;
>>         }
>>       else
>>         {
>>           ptr->prev = 0; /* or explicitly ptr->prev = y; no difference */
>>           ptr->next = 0;
>>         }
>> }
>
> Umm, you can't hoist ptr->prev before the conditional because that would
> change the meaning of this code.

We test y != 0 and thus know that y == 0 in the else block.  Thus we can
do

    ptr->prev = y;
    if (y != 0)
     ptr->next = x;
    else
     ptr->next = 0;

note that we already transform

    if (y != 0)
      ...
    else
      ptr->prev = y;

to ptr->prev = 0 AFAIK.

Richard.



>
> I think you wanted the conditional to test y == 0 which exposes the code
> hoisting opportunity for the ptr->prev assignment.  Once you fix the
> testcase the code in jump2 will hoist the assignment resulting in:
>
>
>
>
>
>         .cfi_startproc
>
>         testl   %esi, %esi
>         movl    %edi, %eax
>         movl    $0, (%edi)
>
>         je      .L5
>         movl    $0, 4(%rax)
>         ret
>         .p2align 4,,10
>         .p2align 3
>
> .L5:
>         movl    %edi, 4(%rax)
>         ret
>         .cfi_endproc
>
>
> Jeff

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-11-11 11:36 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-08  9:28 How can I tune gcc to move up simple common subexpression? Konstantin Vladimirov
2013-11-08 10:06 ` Richard Biener
2013-11-08 20:21 ` Jeff Law
2013-11-11 11:36   ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).