https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63390

            Bug ID: 63390
           Summary: [SH] Hoist/schedule constant pool loads
           Product: gcc
           Version: 5.0
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: olegendo at gcc dot gnu.org
            Target: sh*-*-*

The following example resembles a use case where a tagged pointer (1 bit tag in
LSB) is tested for nullptr and a function is invoked with the extracted normal
pointer:

void foo (unsigned int, int);
void test (unsigned int* x)
{
  if (__builtin_expect ((*x >> 1) != 0, 1))
    foo (*x >> 1, 123456);
}

-O2 -m4 -ml:
        mov.l   @r4,r4
        shlr    r4
        tst     r4,r4
        bt      .L3
        mov.l   .L6,r1    <<<<
        mov.l   .L7,r5    <<<<
        jmp     @r1
        nop
        .align 1
.L3:
        rts    
        nop
.L7:

Since the pointer is likely to be not nullptr, the function 'foo' is also
likely to be executed.  Thus it would make sense to hoist the loads for the
function call to get better scheduling:

        mov.l   @r4,r4
        mov.l   .L6,r1    <<<<
        shlr    r4
        mov.l   .L7,r5    <<<<
        tst     r4,r4
        bt      .L3
        jmp     @r1
        nop
.L3:
        rts    
        nop
.L7:

The scheduler doesn't see that because the constant loads remain in the same
basic block that contains the function call.  Moreover, the constant pool loads
are expanded by sh_reorg pass after scheduling (which makes sense).

One idea could be to record the expanded constant pool load insns and try to
hoist them after sh_reorg and maybe run the scheduler on the modified insn
sections.

Reply via email to