Path: utzoo!mnetor!uunet!seismo!sundc!pitstop!sun!dgh!dgh From: dgh%dgh@Sun.COM (David Hough) Newsgroups: comp.lang.c Subject: Re: Bad optimizations (was Re: comma operator) Message-ID: <39616@sun.uucp> Date: 21 Jan 88 21:25:55 GMT References: <3819@sigi.Colorado.EDU> <5080013@hpfcdc.HP.COM> <7120@brl-smoke.ARPA> <269@vsi1.UUCP> Sender: news@sun.uucp Lines: 97 Keywords: optimization swap sun compiler Summary: modern optimizers fix trivial test programs In article <269@vsi1.UUCP>, steve@vsi1.UUCP (Steve Maurer) writes: > to try this out, I decided to compile the > following section of code on our Sun3 (without optimization). > > #define swap(a,b) ((a) = ((b) = ((a) = (a) ^ (b)) ^ (b)) ^ (a)) > #define swap2(A, B, TYPE) { TYPE temp; temp = A; A = B; B = temp; } > > main() > { > int a = 3, b = 5; > > swap(a, b); > foo_marker(); /* marker to deleniate code sections */ > swap2(a, b, int); > } > > The resulting code (without headers or trailers) was as follows: > > movl a6@(-0x4),d0 <-- xor method > movl a6@(-0x8),d1 > eorl d1,d0 > movl d0,a6@(-0x4) > movl a6@(-0x8),d1 > eorl d1,d0 > movl d0,a6@(-0x8) > movl a6@(-0x4),d1 > eorl d1,d0 > movl d0,a6@(-0x4) > > jbsr _foo_marker > > movl a6@(-0x4),a6@(-0xc) <-- move method > movl a6@(-0x8),a6@(-0x4) > movl a6@(-0xc),a6@(-0x8) > > Here is the same exclusive or swap() macro, under Sun's optimizer: > > eorl d1,d0 > movl d0,a6@(-4) > eorl d1,d0 > movl d0,a6@(-8) > movl a6@(-4),d1 > eorl d1,d0 > movl d0,a6@(-4) The above reflects what's called -O1 optimization in SunOS 4.0, currently under development. I tried the example program under maximal optimization (-O4) and it optimized away to just about nothing, so I revised the program: #define swap(a,b) ((a) = ((b) = ((a) = (a) ^ (b)) ^ (b)) ^ (a)) #define swap2(A, B, TYPE) { TYPE temp; temp = A; A = B; B = temp; } main() { int a,b; getab(&a,&b); /* pretend that a and b get new values */ swap(a, b); foo_marker(a,b); /* marker to delineate code sections */ getab(&a,&b); /* pretend that a and b get new values */ swap2(a, b, int); foo_marker(a,b); /* marker to delineate code sections */ } and found: jbsr _getab addqw #8,sp movl a6@(-8),d0 ex or macro eorl d0,a6@(-4) movl a6@(-4),d0 eorl d0,a6@(-8) movl a6@(-8),d0 eorl d0,a6@(-4) movl d0,sp@- movl a6@(-4),sp@- jbsr _foo_marker ... jbsr _getab addqw #8,sp movl a6@(-4),d7 move via temp movl a6@(-8),a6@(-4) movl d7,a6@(-8) movl d7,sp@- movl a6@(-4),sp@- jbsr _foo_marker 8 instructions instead of 5, the difference being the 3 eorl's. In general, you wouldn't use the EOR method unless you were out of space for temporaries, which might be the case if you were microcoding within a small register file, but is hardly typical of C applications. David Hough ARPA: dhough@sun.com UUCP: {ucbvax,decvax,allegra,decwrl,cbosgd,ihnp4,seismo}!sun!dhough