Newsgroups: | comp.compilers |
From: | adk@sun13.SCRI.FSU.EDU (Tony Kennedy) |
Keywords: | C, optimize, assembler |
Organization: | SCRI, Florida State University |
References: | 93-10-114 93-10-127 |
Date: | Fri, 29 Oct 1993 03:48:36 GMT |
> Dave Gillespie <synaptx!daveg@uunet.UU.NET> writes:
> My favorite example comes from an i860 loop we wrote here,
> which involved a bunch of multipy-adds followed by something
> of the form max(min(x, limit), -limit), i.e., constrain
> abs(x) <= limit. Branches are awful on the i860...
I am not sure why a compiler would want to use branches. Noting that
max(x,limit) = max(x-limit,0) + limit
it suffices to evaluate max(z,0) up to a couple of arithmetic
operations. Now,
max(z,0) = z & (z > 0)
where "&" means "bitwise and", and "z > 0" is a word of all ones if z
is greater than zero and a word of all zeros if it is not. This may be
computed by propagating the sign bit of z through an entire word and
logically negating it. In C terms this leads to the following function
(for 32 long ints and floats with the sign bit at the left end)
float max(float x, float y) {
union fl {float f; long l;} z;
z.f = x - y;
z.l &= ~z.l >> 31;
return z.f + y;}
I am not claiming that this is faster than your trick, but the C
compiler *could* generate code without any branches.
(Caveat: I checked my method on a VAX, where the sign bit is in the
middle of word. I have not directly checked the version given here).
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.