This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: a strange infelicity of register allocation


On Wed, 27 Jan 1999 17:07:37 +0000 (GMT), Joern Rennecke wrote:
>> Right before CSE, we have this RTL for the above code.  CSE makes no
>> changes except to annotate insns with patterns.  Flow thinks this is
>
>Well, why doesn't it use reg 86 in insn 620?

I've no idea.  I can do the CSE by hand, which produces better,
but still suboptimal assembler:

        subl -4104(%ebp),%ebx
        pushl %ebx
        movl -4104(%ebp),%ecx
        pushl %ecx
        call xrealloc
        movl %eax,-4104(%ebp)
        movl 12(%ebp),%eax
        movl -4104(%ebp),%edx
        movl %edx,(%eax)
        movl %ebx,%eax

Two issues here.  One is that after the call, %eax is spilled and
restored to %edx, so we can load the pointer at 12(%ebp) into %eax.
It's willing to use %edx here, so why not just load the pointer in
there?  Then we could generate

	movl 12(%ebp),%edx
	movl %eax,(%edx)
	movl %ebx,%eax

This might be lreg's fault.  Here's the RTL after lreg:

(insn 618 616 676 (set (reg/v:SI 26)
        (reg:SI 0 %eax)) 54 {movsi+2} (insn_list 616 (nil))
    (expr_list:REG_DEAD (reg:SI 0 %eax)
        (nil)))

(insn 676 618 621 (set (reg/v:SI 23)
        (mem:SI (plus:SI (reg:SI 16 %argp)
                (const_int 4)) 2)) 54 {movsi+2} (nil)
    (expr_list:REG_EQUIV (mem/f:SI (plus:SI (reg:SI 16 %argp)
                (const_int 4)) 2)
        (nil)))

(insn 621 676 624 (set (mem/s:SI (reg/v:SI 23) 5)
        (reg/v:SI 26)) 54 {movsi+2} (insn_list 618 (nil))
    (expr_list:REG_DEAD (reg/v:SI 26)
        (expr_list:REG_DEAD (reg/v:SI 23)
            (nil))))

(insn 624 621 626 (set (reg/i:SI 0 %eax)
        (reg/v:SI 86)) 54 {movsi+2} (nil)
    (expr_list:REG_DEAD (reg/v:SI 86)
        (nil)))

and lreg says of (reg/v:SI 23)
Register 23 used 2 times across 2 insns in block 58; set 1 time; 
	user var; GENERAL_REGS or none; pointer.

but it didn't give it a hard register...

The other issue is that before the call, we generate what looks to me
like silly assembler:

        subl -4104(%ebp),%ebx
        pushl %ebx
        movl -4104(%ebp),%ecx
        pushl %ecx

Which could be written

        movl -4104(%ebp),%ecx
        subl %ecx,%ebx
        pushl %ebx
        pushl %ecx

saving four bytes of machine code, and I'd think it's faster this way
too (but I'm no expert on Intel scheduling issues).

If I use -Os, it generates almost the assembly I suggested, but
there's a pile of other changes which invalidate the analysis: for
example, -4104(%ebp) is now in %edi apparently throughout the function.

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]