This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: a strange infelicity of register allocation
- To: Joern Rennecke <amylaar at cygnus dot co dot uk>
- Subject: Re: a strange infelicity of register allocation
- From: Zack Weinberg <zack at rabi dot columbia dot edu>
- Date: Wed, 27 Jan 1999 12:51:24 -0500
- cc: law at cygnus dot com, egcs at egcs dot cygnus dot com
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