This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Register allocation
- To: Thomas dot Koenig at ciw dot uni-karlsruhe dot de (Thomas König)
- Subject: Re: Register allocation
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Mon, 21 Dec 1998 19:42:25 -0700
- cc: egcs at cygnus dot com
- Reply-To: law at cygnus dot com
In message <199710141250.NAA03152@mvmap66.ciw.uni-karlsruhe.de>you write:
> egcs 971008 with haifa enabled generates two unnecessary register
> moves for the function for Linux i386-glibc1:
>
> typedef struct pt
> {
> int x;
> int y;
> struct pt *n;
> } pt;
>
> #define WALL(a) ((a)->n == 0)
> #define SQR(a) ((double) (a)* (double) (a))
>
> double e_point_point(pt *a, pt *b)
> {
> double res;
> res = SQR(a->x - b->x) + SQR(a->y - b->y);
> if (WALL(a) || WALL(b)) {
> res *= 4;
> }
> return res;
> }
Yea. This is is a generic problem with how we've handled 2 address machines.
In the past we relied on reload to rearrange operands so that one of the
inputs would match one of the ouputs.
To do so requires spilling and potentially useless register copies as seen
in this case.
We've got a pass (regmove) that is supposed to improve the code we generate
for 2 address machines, but it does not help this case for a couple of reasons.
* The source/dest operands of the subtractions are not related by copy
insns at the time regmove runs.
* The code to copy a source operand to a destination operand does not
handle cases where the source operand is a MEM (as happens with this
code.
I've got a hack to regmove (which I'm going to ask Jim & Joern to look at)
which addresses both problems.
I get the following code for your testcase when using that patch. Note there
is not a single copy insn in the resulting code *AND* the subtractions operate
on regs, not memory operands :-)
.globl e_point_point
.type e_point_point,@function
e_point_point:
pushl %ebp # 83 movsi-2
movl %esp,%ebp # 85 movsi+2/1
pushl %ebx # 86 movsi-2
movl 12(%ebp),%ebx # 6 movsi+2/2
movl 8(%ebp),%ecx # 4 movsi+2/2
movl (%ebx),%edx # 15 movsi+2/2
movl (%ecx),%eax # 80 movsi+2/2
subl %edx,%eax # 17 subsi3+1/1
movl 4(%ebx),%edx # 30 movsi+2/2
pushl %eax # 18 *addsidi3_1-3
fildl (%esp)
addl $4,%esp
movl 4(%ecx),%eax # 77 movsi+2/2
fmul %st(0),%st # 26 ffshi_1+1/1
subl %edx,%eax # 32 subsi3+1/1
pushl %eax # 33 *addsidi3_1-3
fildl (%esp)
addl $4,%esp
fmul %st(0),%st # 41 ffshi_1+1/1
faddp %st,%st(1) # 42 ffshi_1+1/1
cmpl $0,8(%ecx) # 46 tstsi_1
je .L4 # 47 bleu+1
cmpl $0,8(%ebx) # 50 tstsi_1
jne .L3 # 51 bleu+1
.L4:
fmull .LC0 # 59 ffshi_1+1/1
.L3:
popl %ebx # 88 pop
movl %ebp,%esp # 89 epilogue_set_stack_ptr
popl %ebp # 90 pop
ret # 91 return_internal
.Lfe1:
.size e_point_point,.Lfe1-e_point_point
.ident "GCC: (GNU) egcs-2.92.31 19981220 (gcc2 ss-980609 experimental)"
>