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: Register allocation



  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)"


  > 


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