GCC with gcse enabled generates very poor code for this fragment:

------------------------------------------------------------------------------
int r0, r1, r2, r3, r4, r5;

void f (int n)
{
  while (-- n)
    {
      r1 += r0;
      r2 += r1;
      r3 += r2;
      r4 += r3;
      r5 += r4;
      r0 += r5;
    }
}
------------------------------------------------------------------------------

This is code from 3.4.4 with -O2 -fomit-frame-pointer:
.L4:
        movl    16(%esp), %ebp
        movl    12(%esp), %esi
        movl    8(%esp), %ecx
        movl    4(%esp), %edx
        movl    (%esp), %eax
        addl    %edi, %ebp
        addl    %ebp, %esi
        movl    %ebp, 16(%esp)
        addl    %esi, %ecx
        movl    %esi, 12(%esp)
        addl    %ecx, %edx
        movl    %ecx, 8(%esp)
        addl    %edx, %eax
        decl    20(%esp)
        movl    %edx, 4(%esp)
        leal    (%edi,%eax), %ebx
        movl    %eax, (%esp)
        movl    %ebx, %edi
        jne     .L4

And this is with -O2 -fomit-frame-pointer -fno-gcse:
.L4:
        addl    %edi, %ebp
        addl    %ebp, %ebx
        addl    %ebx, %ecx
        addl    %ecx, %edx
        addl    %edx, %eax
        addl    %eax, %edi
        decl    %esi
        jne     .L4

Same applies for 4.0.0, only one should use '-O2 -fomit-frame-pointer
-fno-tree-loop-im -fno-gcse' to get decent code.

This is a regression and was introduced by this change:

2001-07-16  Daniel Berlin  <[EMAIL PROTECTED]>

        * gcse.c: Update comment at top. 
        Update comment on mem handling.
        mem_last_set, mem_first_set, mem_set_in_block: gone.
        Declaration of reg_set_info: gone.
        (oprs_unchanged_p): Don't use mem_*set_* anymore. They are
        pointless with load_killed_in_block_p (they are *more*
        conservative then it, not less, and less accurate).
        (oprs_not_set_p): Ditto.        
        (alloc_gcse_mem): Don't allocate mem_set_in_block
        (free_gcse_mem): Don't free it, either.
        (record_last_mem_set_info): Update comment in front, remove
        mem_*set_* stuff. Note the reason we don't handle stores directly
        here.
        (compute_hash_table): Update comments to reflect reality. Remove
        mem_*set_* references.
        (reset_opr_set_tables): Remove mem_*set_* references.
        (mark_call): Ditto.
        (mark_set): Ditto.  Also remove double sets of bitmaps for REG's.       
        (mark_clobber): Ditto (on both parts, we double set here too).
        (expr_killed_p): Remove mem_set_in_block test.
        (compute_transp): Remove mem_set_in_block test.

-- 
           Summary: [3.3/3.4/4.0 Regression] gcse causes poor register
                    allocation
           Product: gcc
           Version: 4.0.0
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P2
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: belyshev at depni dot sinp dot msu dot ru
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19464

Reply via email to