Path: utzoo!attcan!uunet!husc6!cmcl2!nrl-cmf!ames!pasteur!ucbvax!POSTGRES.BERKELEY.EDU!dillon
From: dillon@POSTGRES.BERKELEY.EDU (Matt Dillon)
Newsgroups: comp.sys.amiga.tech
Subject: Re: Dividing by a power of two (Re: Aztec compiler ineffeciencies)
Message-ID: <8811281919.AA17977@postgres.Berkeley.EDU>
Date: 28 Nov 88 19:19:44 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Lines: 48

:> > As many compiler writers have found in the past and I'm sure many will
:> > rediscover in the future, this only works for positive values.  Try
:> > shifting -1 and you'll get -1 as a result, *not* zero as one would expect.
:> I think the problem is that shifting always rounds down, as opposed
:> to towards zero, like we expect.  So even in cases where you have a
:Actually it is much simpler than that.  The Lattice 5.0 compiler generates the
:3 instructions (sometimes 4) inline to perform the division by 2,4, and 8.
:These are the most frequent numbers to occur from analysis of many programs.
:Specifically:
:      x/= 2
:      move x,d0   ;unless it was already there
:      bpl  lab    ;skip if positive
:      addq #1,d0  ;adjust for rounding
:lab:  asr.l #1,d0 ; and do the divide

	This is also a very good example of what is known as "programmer's
experience".  No *good* programmer would do constant division by powers of 2
using '/', but would use a shift instead.  The programmer, after all, knows
exactly what range a particular variable will fall in whether it is 
unsigned or not, and thus can make optimizations and assumptions the
compiler could never match.

	Take a good look at the example above ...  how often do you
divide negative numbers by powers of 2?  Now, take that probability
and ask how often the variable would be unbounded (can take arbitrary values)
verses in a known range that can be optimized by some other method.
Finally, take into account whether, in the case it IS negative, rounding is 
desirable.

	Now you say "But I don't want to worry about it" and "I don't want
to have to worry about optimizing it".  Bullshit.  Either the problem is
sooo important that nobody in their right mind would risk a division anyway,	
or so unimportant that it doesn't matter if it is optimized or not.  I wish
the compiler writers would take more time to optimize the more frequent
cases that occur in tight code rather than these totally useless cases.
For example, Lattice does no register tracking and Aztec doesn't do enough.

	You might say "It is the compiler's job to optimize!", to which I would
respond: "Which do you think the compiler can optimize better, a shift, or
a divide?".  Got it?  No matter how good compilers get, certain constructs
are more apt to optimization than others due to fewer assumptions having to
be made about them, so the 'good' programmer *always* optimizes his code.
little goodies might be a boon to the 'ok' programmer, but even with them
his program is no where near the theoretical efficiency he could obtain, and
what he gains by those (for us) useless cases doesn't help as much as he
would like.

						-Matt