"const" and "pure" functions pessimize code

Dan Nicolaescu dann@godzilla.ICS.UCI.EDU
Wed Mar 20 10:40:00 GMT 2002


This snippet: 

#ifdef MY_PURE
extern  double mycos (double) __attribute__ ((pure));
extern  double mysin (double) __attribute__ ((pure));
#elif defined MY_CONST
extern  double mycos (double) __attribute__ ((const));
extern  double mysin (double) __attribute__ ((const));
#else
extern double mycos (double x);
extern double mysin (double x);
#endif

struct my_complex
{
  double re;
  double im;
};


int main(void) {

  struct my_complex u[2048];
  int i;
  for (i = 0; i < 2048; ++i)
    {
      u[i].re = 1.0;
      u[i].im = 0.0;
    }
               
  for (i = 0; i < 2048; ++i) {
    struct my_complex *p = u;
    unsigned int j;
    for (j = 0; j < 2048; ++j) {
      double ur = p->re;
      double ui = p->im;
      double u2 = ur * ur + ui * ui;             
      double cosv = mycos (u2);
      double sinv = mysin (u2);
      p->re = p->re * cosv - p->im * sinv;
      p->im = p->im * sinv +  p->re * cosv;
      ++p;
    } 
  }
  return 0;
}

generates worse code when compiled with -O2 -DMY_PURE or
-O2 -DMY_CONST than when compiled just with -O2 on SPARC


gcc -O2                                        gcc -O2 -DMY_CONST
main:					       main:
	!#PROLOGUE# 0			
	sethi	%hi(-32896), %g1	  |		sethi	%hi(-32912), %g1
	or	%g1, %lo(-32896), %g1	  |		or	%g1, %lo(-32912), %g1
	save	%sp, %g1, %sp				save	%sp, %g1, %sp
	!#PROLOGUE# 1					!#PROLOGUE# 1
	sethi	%hi(-32768), %o0			sethi	%hi(-32768), %o0
	add	%fp, -16, %l3				add	%fp, -16, %l3
	add	%l3, %o0, %o2				add	%l3, %o0, %o2
	sethi	%hi(.LLC0), %o0				sethi	%hi(.LLC0), %o0
	ldd	[%o0+%lo(.LLC0)], %f4			ldd	[%o0+%lo(.LLC0)], %f4
	mov	0, %l1					mov	0, %l1
	sethi	%hi(.LLC1), %o0				sethi	%hi(.LLC1), %o0
	ldd	[%o0+%lo(.LLC1)], %f2			ldd	[%o0+%lo(.LLC1)], %f2
.LL5:						.LL5:
	fmovs	%f2, %f6				fmovs	%f2, %f6
	sll	%l1, 4, %o1				sll	%l1, 4, %o1
	add	%o1, 8, %o0				add	%o1, 8, %o0
	add	%l1, 1, %l1				add	%l1, 1, %l1
	cmp	%l1, 2047				cmp	%l1, 2047
	fmovs	%f3, %f7				fmovs	%f3, %f7
	std	%f6, [%o2+%o0]				std	%f6, [%o2+%o0]
	fmovs	%f4, %f6				fmovs	%f4, %f6
	fmovs	%f5, %f7				fmovs	%f5, %f7
	ble	.LL5					ble	.LL5
	std	%f6, [%o2+%o1]				std	%f6, [%o2+%o1]
	mov	0, %l1					mov	0, %l1
	sethi	%hi(-32768), %l2			sethi	%hi(-32768), %l2
	add	%l3, %l2, %i0				add	%l3, %l2, %i0
.LL23:						.LL23:
	mov	0, %l0					mov	0, %l0
.LL14:						.LL14:
	ldd	[%i0], %f4		  |		ldd	[%i0], %f6
	sethi	%hi(4294933504), %o2			sethi	%hi(4294933504), %o2
	ldd	[%i0+8], %f2		  |		ldd	[%i0+8], %f8
	fmuld	%f4, %f4, %f4		  |		fmuld	%f6, %f6, %f4
	or	%o2, 1000, %o2		  |		or	%o2, 992, %o2
	add	%o2, %fp, %o2				add	%o2, %fp, %o2
	add	%l0, 1, %l0				add	%l0, 1, %l0
	fmuld	%f2, %f2, %f2		  |		fmuld	%f8, %f8, %f2
	faddd	%f4, %f2, %f4				faddd	%f4, %f2, %f4
	std	%f4, [%fp-16]				std	%f4, [%fp-16]
	ldd	[%fp-16], %o0				ldd	[%fp-16], %o0
	call	mycos, 0		  <
	std	%f4, [%o2]				std	%f4, [%o2]
					  >		sethi	%hi(4294933504), %o2
					  >		or	%o2, 984, %o2
					  >		add	%o2, %fp, %o2
					  >		std	%f6, [%o2]
					  >		sethi	%hi(4294933504), %o2
					  >		or	%o2, 976, %o2
					  >		add	%o2, %fp, %o2
					  >		call	mycos, 0
					  >		std	%f8, [%o2]
	sethi	%hi(4294933504), %o0			sethi	%hi(4294933504), %o0
	or	%o0, 1000, %o0		  |		or	%o0, 992, %o0
	add	%o0, %fp, %o0				add	%o0, %fp, %o0
	ldd	[%o0], %f4				ldd	[%o0], %f4
	fmovs	%f0, %f6		  |		fmovs	%f0, %f2
	std	%f4, [%fp-16]				std	%f4, [%fp-16]
	sethi	%hi(4294933504), %o2			sethi	%hi(4294933504), %o2
	ldd	[%fp-16], %o0				ldd	[%fp-16], %o0
	or	%o2, 992, %o2		  |		or	%o2, 1000, %o2
	fmovs	%f1, %f7		  |		fmovs	%f1, %f3
	add	%o2, %fp, %o2				add	%o2, %fp, %o2
	call	mysin, 0				call	mysin, 0
	std	%f6, [%o2]		  |		std	%f2, [%o2]
	sethi	%hi(4294933504), %o0			sethi	%hi(4294933504), %o0
	or	%o0, 992, %o0		  |		or	%o0, 976, %o0
	add	%o0, %fp, %o0				add	%o0, %fp, %o0
	ldd	[%i0], %f2		  |		ldd	[%o0], %f8
	cmp	%l0, 2047		  |		sethi	%hi(4294933504), %o2
	ldd	[%i0+8], %f4		  |		sethi	%hi(4294933504), %o0
					  >		or	%o2, 1000, %o2
					  >		or	%o0, 984, %o0
					  >		add	%o2, %fp, %o2
					  >		add	%o0, %fp, %o0
					  >		ldd	[%o2], %f2
					  >		fmuld	%f8, %f0, %f8
	ldd	[%o0], %f6				ldd	[%o0], %f6
	fmuld	%f4, %f0, %f4		  |		cmp	%l0, 2047
	fmuld	%f2, %f6, %f2		  |		fmuld	%f6, %f2, %f6
	fsubd	%f2, %f4, %f2		  |		fsubd	%f6, %f8, %f6
	fmuld	%f2, %f6, %f6		  |		fmuld	%f6, %f2, %f2
	std	%f2, [%i0]		  |		std	%f6, [%i0]
	faddd	%f4, %f6, %f4		  |		faddd	%f8, %f2, %f8
	std	%f4, [%i0+8]		  |		std	%f8, [%i0+8]
	bleu	.LL14					bleu	.LL14
	add	%i0, 16, %i0				add	%i0, 16, %i0
	add	%l1, 1, %l1				add	%l1, 1, %l1
	cmp	%l1, 2047				cmp	%l1, 2047
	ble,a	.LL23					ble,a	.LL23
	add	%l3, %l2, %i0				add	%l3, %l2, %i0
	ret						ret
	restore						restore

Does this happen on other platforms, or is it SPARC-specific? 
Any idea what's the cause? 



More information about the Gcc mailing list