* 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).