From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jeffrey A Law To: Thomas.Koenig@ciw.uni-karlsruhe.de (Thomas König) Cc: egcs@cygnus.com Subject: Re: Register allocation Date: Mon, 21 Dec 1998 22:38:00 -0000 Message-id: <22591.914294545@upchuck> References: <199710141250.NAA03152@mvmap66.ciw.uni-karlsruhe.de> X-SW-Source: 1998-12/msg00841.html 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)" >