public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-18 18:39 Robert Dewar
  2002-12-19  3:02 ` Richard Henderson
  2002-12-21 19:49 ` Alexandre Oliva
  0 siblings, 2 replies; 40+ messages in thread
From: Robert Dewar @ 2002-12-18 18:39 UTC (permalink / raw)
  To: rth, toon; +Cc: gcc

> i.e. the dereference is protected by a conditional.  Thus
> we can't hoist the dereference past the conditional (and
> thence out of the loop that started this thread).


it is interesting to note that the IBM compiler group decided that
ensuring that null could be safetly dereferenced, and hence such
references can be hoisted etc, was a major win in C code efficiency.

^ permalink raw reply	[flat|nested] 40+ messages in thread
* Re: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-21 20:36 Robert Dewar
  0 siblings, 0 replies; 40+ messages in thread
From: Robert Dewar @ 2002-12-21 20:36 UTC (permalink / raw)
  To: aoliva, dewar; +Cc: gcc, rth, toon

> At the expense of getting nice crashes at points where NULL is
> dereferenced, which often makes it easy to find bugs?  Oh, and there's

umm ... optimization is about favoring fast execution of code over 
debuggability, so yes, exactly that is the trade off. Note that there
is absolutely NOTHING to stop a compiler from generating code that
diagnoses dereferences of null pointers in fully optimized code if
that's what you want (it is for example required in Ada!)

^ permalink raw reply	[flat|nested] 40+ messages in thread
* Re: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-19  7:08 Richard Kenner
  0 siblings, 0 replies; 40+ messages in thread
From: Richard Kenner @ 2002-12-19  7:08 UTC (permalink / raw)
  To: rth; +Cc: gcc

    So the pointer isn't null, it's uninitialized, and the conditional
    protecting its use is true iff it's initialized.  Same problem.

No, because of the common idiom (especially for lists) of testing a
pointer for being null and then dereferencing it if not.  You can do the
load unconditionally in that case.

^ permalink raw reply	[flat|nested] 40+ messages in thread
* RE: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-13  0:39 Sanjiv Kumar Gupta, Noida
  2002-12-13  2:42 ` Richard Henderson
  0 siblings, 1 reply; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-13  0:39 UTC (permalink / raw)
  To: David Edelsohn, Richard Henderson, Daniel Berlin, Dale Johannesen, gcc

>  It is not hoisting some stores
>which it should.  The cases I have seen have not been due to aliasing.

>David

I have an example where gcse fails despite the success of aliasing.
consider,

void func (double *a, double *b, int i)
{
        int j;
 
        b[2] = a[1];
 
        for (j = 0; j < i; j++)
        {
               if (i)
                   b[3] = a[1];
        }
}

GCC -ml -m4 -O2 -fno-argument-alias  generates
_func:
        mov.l   r14,@-r15
        mov     r15,r14
        mov     r5,r1
        add     #16,r1
        add     #8,r4
        fmov.s  @r4+,fr3		--> loading a[1]
        fmov.s  @r4,fr2
        add     #-4,r4
        add     #4,r1
        fmov.s  fr2,@r1
        mov     #0,r2
        cmp/ge  r6,r2
        bt/s    .L10
        fmov.s  fr3,@-r1
        mov     r5,r1
        add     #24,r1
        mov     r6,r2
        tst     r6,r6
.L11:
        bt      .L4
        fmov.s  @r4+,fr3		--> loading a[1] again ??
        fmov.s  @r4,fr2
        add     #-4,r4
        add     #4,r1
        fmov.s  fr2,@r1
        fmov.s  fr3,@-r1
.L4:
        dt      r2
        bf/s    .L11
        tst     r6,r6

--Sanjiv

^ permalink raw reply	[flat|nested] 40+ messages in thread
* RE: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-12 23:42 Sanjiv Kumar Gupta, Noida
  0 siblings, 0 replies; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-12 23:42 UTC (permalink / raw)
  To: Dan Nicolaescu; +Cc: Daniel Berlin, Dale Johannesen, gcc

>It works just fine on SPARC, so it might be something specific to your
>port... 

>        ldd     [%o0+8], %f8
>        cmp     %o2, 2  !  i

We have reg+offset mode for SPARC here. So that's find with alias.c.
mine is SH4. I fear IA64 may probably have the same problem.

--Sanjiv

^ permalink raw reply	[flat|nested] 40+ messages in thread
* RE: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-12 21:35 Sanjiv Kumar Gupta, Noida
  2002-12-12 21:44 ` Dan Nicolaescu
  0 siblings, 1 reply; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-12 21:35 UTC (permalink / raw)
  To: Geoff Keating, Richard Henderson; +Cc: Daniel Berlin, Dale Johannesen, gcc

 
>> We have the code for it, but alias.c isn't helping.

>It looks like memrefs_conflict_p is supposed to be able to prove that
a[2] and a[4] don't alias, I wonder why it's not working?

It can detect different offsets in 'reg+offset' forms of addresses
but can not distinguish between two pointer regs. 
In this case, the machine (sh4) doesn't support reg+offset addressing
for double-precision values.
I am working on memrefs_conflict_p to handle this.

--Sanjiv

^ permalink raw reply	[flat|nested] 40+ messages in thread
* RE: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-11 22:00 Sanjiv Kumar Gupta, Noida
  2002-12-11 22:18 ` Daniel Berlin
  0 siblings, 1 reply; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-11 22:00 UTC (permalink / raw)
  To: Daniel Berlin, Dale Johannesen; +Cc: gcc



>> But surely it should be smart enough to know they don't alias?
>It depends on what it looks like at the RTL level.
the references of a[4] and a[1] appear as two pointer pseudos
which gcc can not determine that they have been computed with distinct
offsets from same base. Thus assumes aliasing.
I am implementing mod-k residue technique in GCC 
(described in "alias analysis of executable code", Debray98 et. al)
to fix this.
>> This is still a bug, possibly an important one for performance.

>Store motion can't handle this right now.
>It was built to handle a certain special case.
>Improve it so it does more.
>It's not broken, just not as good as it could be.

Store motion is currently disabled. see gcse.c line 910

/* Store motion disabled until it is fixed.  */
  if (0 && !optimize_size && flag_gcse_sm)
    store_motion ();

I don't know what's stopping this? I will try to find
related PRs and have a look into them.

--Sanjiv

^ permalink raw reply	[flat|nested] 40+ messages in thread
* RE: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-11 20:32 Sanjiv Kumar Gupta, Noida
  0 siblings, 0 replies; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-11 20:32 UTC (permalink / raw)
  To: Dale Johannesen; +Cc: gcc

>But surely it should be smart enough to know they don't alias?

I am currently working to make the alias analysis more smart. :) 
After that GCC will be able to figure out that a[4] and a[1] do not alias. 


--Sanjiv

^ permalink raw reply	[flat|nested] 40+ messages in thread
* RE: possible gcse failure: not able to eliminate redundant loads
@ 2002-12-11  3:30 Sanjiv Kumar Gupta, Noida
  2002-12-11 14:53 ` Dale Johannesen
  0 siblings, 1 reply; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-11  3:30 UTC (permalink / raw)
  To: gcc

>void func (double *a, double *b, int i)
>{
>        b[2] = a[1];
>
>        for (i ; i < 3; i = i + 8)
>        {
>                a[4] = a[1];
>
>        }
>}

>for -O2 -fno-argument-alias, I am getting multiple loads for a[1].

Oooops! I realized it just now. Basically GCC is assuming that
a[4] and a[1] may alias, hence reloading a[1] in each loop iteration.
sorry for the inconvenience caused.

regards
--Sanjiv

^ permalink raw reply	[flat|nested] 40+ messages in thread
* possible gcse failure: not able to eliminate redundant loads
@ 2002-12-11  3:27 Sanjiv Kumar Gupta, Noida
  0 siblings, 0 replies; 40+ messages in thread
From: Sanjiv Kumar Gupta, Noida @ 2002-12-11  3:27 UTC (permalink / raw)
  To: gcc

Following code snippet demonstrates the problem.

void func (double *a, double *b, int i)
{
        b[2] = a[1];

        for (i ; i < 3; i = i + 8)
        {
                a[4] = a[1];

        }
}

for -O2 -fno-argument-alias, I am getting multiple loads for a[1].

_func:
        mov.l   r14,@-r15
        mov     r15,r14
        add     #16,r5
        mov     r4,r2
        add     #8,r2
        fmov.s  @r2+,fr3		--> loading a[1] here
        fmov.s  @r2,fr2
        add     #-4,r2
        add     #4,r5
        fmov.s  fr2,@r5
        mov     #2,r1
        cmp/gt  r1,r6
        bt/s    .L9
        fmov.s  fr3,@-r5
        add     #32,r4
.L6:
        fmov.s  @r2+,fr3		--> loading a[1] here again //
problem.
        fmov.s  @r2,fr2
        add     #-4,r2
        add     #4,r4
        fmov.s  fr2,@r4
        add     #8,r6
        cmp/gt  r1,r6
        bf/s    .L6
        fmov.s  fr3,@-r4
.L9:
        mov     r14,r15
        rts
        mov.l   @r15+,r14

with -fno-argument-alias GCC knows that b[2] and a[1] do not alias, so
store into b[2] is not invalidating the loaded value of a[1]. Hence
it should have used the previously loaded value of a[1] inside the for loop
instead of reloading it.

The above assembly listing is for sh-elf, but this problem might be there
for other targets too. Enabling store_motion code in gcse.c and 
using -O3 -fgcse-lm -fgcse-sm don't help either.

However, it behaves perfectly fine for following

void func (double *a, double *b, int i)
{
        b[2] = a[1];

        if (i < 3)
        {
                a[4] = a[1];

        }
}

Here, we do not get extra loads for a[1]. 

Can somebody please help me knowing what is happening here?
--Sanjiv

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

end of thread, other threads:[~2002-12-21 19:39 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-18 18:39 possible gcse failure: not able to eliminate redundant loads Robert Dewar
2002-12-19  3:02 ` Richard Henderson
2002-12-21 19:49 ` Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2002-12-21 20:36 Robert Dewar
2002-12-19  7:08 Richard Kenner
2002-12-13  0:39 Sanjiv Kumar Gupta, Noida
2002-12-13  2:42 ` Richard Henderson
2002-12-13 13:10   ` Toon Moene
2002-12-16 10:15     ` Richard Henderson
2002-12-16 11:32       ` Andrew Haley
2002-12-16 13:13       ` Toon Moene
2002-12-16 13:32         ` Richard Henderson
2002-12-16 14:44           ` Toon Moene
2002-12-16 14:48             ` Toon Moene
2002-12-16 15:29               ` Richard Henderson
2002-12-17 15:20                 ` Toon Moene
2002-12-16 15:38               ` Jan Hubicka
2002-12-16 16:40           ` Alex Rosenberg
2002-12-12 23:42 Sanjiv Kumar Gupta, Noida
2002-12-12 21:35 Sanjiv Kumar Gupta, Noida
2002-12-12 21:44 ` Dan Nicolaescu
2002-12-11 22:00 Sanjiv Kumar Gupta, Noida
2002-12-11 22:18 ` Daniel Berlin
2002-12-11 20:32 Sanjiv Kumar Gupta, Noida
2002-12-11  3:30 Sanjiv Kumar Gupta, Noida
2002-12-11 14:53 ` Dale Johannesen
2002-12-11 20:02   ` Daniel Berlin
2002-12-11 20:03     ` Daniel Berlin
2002-12-12 12:25     ` Richard Henderson
2002-12-12 12:28       ` Daniel Berlin
2002-12-12 13:03         ` Richard Henderson
2002-12-12 13:04           ` David Edelsohn
2002-12-12 14:32             ` Richard Henderson
2002-12-12 14:42               ` David Edelsohn
2002-12-12 14:58                 ` Richard Henderson
2002-12-12 15:28                   ` Daniel Berlin
2002-12-13  3:41                     ` Richard Henderson
2002-12-12 20:30                   ` David Edelsohn
2002-12-12 15:29               ` Geoff Keating
2002-12-11  3:27 Sanjiv Kumar Gupta, Noida

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