[comp.lang.misc] Many people's opinions on compu

carroll@s.cs.uiuc.edu (09/20/88)

/* Written  8:50 pm  Sep 18, 1988 by smryan@garth.UUCP in s.cs.uiuc.edu:comp.lang.misc */

In short, if you want p and q, use p&&q. If you want, if p then q else don't
bother with q, just say false, use p?q:false.
/* End of text from s.cs.uiuc.edu:comp.lang.misc */

But if the compiler has any brains at all, p && q should be compiled to
the same thing as p?q:false. I don't see what the latter gains you
except to irritate the programmer.

Alan M. Carroll		                      carroll@s.cs.uiuc.edu
Grad Student / U of Ill - Urbana ...{pur-ee,convex}!uiucdcs!s!carroll
"Too many fools who don't think twice, too many ways to pay the price" - AP&EW

news@amdcad.AMD.COM (Network News) (09/21/88)

In article <208100001@s.cs.uiuc.edu> carroll@s.cs.uiuc.edu writes:
| 
| 
| /* Written  8:50 pm  Sep 18, 1988 by smryan@garth.UUCP in s.cs.uiuc.edu:comp.lang.misc */
| 
| In short, if you want p and q, use p&&q. If you want, if p then q else don't
| bother with q, just say false, use p?q:false.
| /* End of text from s.cs.uiuc.edu:comp.lang.misc */
| 
| But if the compiler has any brains at all, p && q should be compiled to
| the same thing as p?q:false. I don't see what the latter gains you
| except to irritate the programmer.

No, they shouldn't compile the same.  This is because the && operator,
when used as an operand in an assignment, must return either 0 or 1. 
This means that an extra test must occur on the q variable to see if it
is zero or not so it can decide to return 0 or 1.

The ?: construct, however, can simply return the value of q without testing
it.

	-- Tim Olson
	Advanced Micro Devices
	(tim@crackle.amd.com)

smryan@garth.UUCP (Steven Ryan) (09/22/88)

>But if the compiler has any brains at all, p && q should be compiled to
>the same thing as p?q:false. I don't see what the latter gains you
>except to irritate the programmer.

Using an example from my alma mater, suppose we have (m=n and o<0), where
m, n, o are integer variables. Then if and<->if-then-else, on Cy170,

+	   SX6 B1             * assume true.
           IX0 X.m-X.n        * X0 := m-n
           ZR  X0,TRUE        * stall cpu; true if (m=n); maybe fill i-cache.
+          ZR  X.o,FALSE      * -0 gotcha; stall cpu; maybe fill i-cache.
           NG  X.o,TRUE       * stall cpu; true if (o<0); maybe fill i-cache.
+FALSE     SX6 0
           NO
           NO
+TRUE

So that it takes 3 words and 3 jumps; each jump stalls the cpu until the
jump condition is verified. If the target label is out of stack, the i-cache
has to be filled.

Now when the and is semantically distinct from if-then-else,

+          SX7   B0            * +0.
           IX0   X.m-X.n       * X0 := m-n.
           IX.o  X.o+X7        * insure o is not a -0.
           BX1   -X0           * X1 := n-m.
+          IX0   X0+X7         * insure m-n is not a -0.
           IX1   X1+X7         * insure n-m is not a -0
           SX7   B1
           BX0   -X0-X1        * set sign bit if sign(m-n)=sign(n-m), if m=n.
+          BX0   X0*X.o        * set sign bit if m=n and o<0.
           LX0   1
           BX6   X0*X7         * X6=X0 sign bit, 1 if true, 0 if false.

So that it takes 1 parcel less than three words, no alignment constraints
(only 15-bit instructions used), no jumps, no cpu stalls, no no-ops, i-cache
can be prefetched, and the code does not create additional basic blocks
so that all the usual basic block optimisations can be applied.

All the  world is not a Vax. On some machines, jumps are killers. By providing
a separate conditional expression to handle, say, if x>0 then sqrt(x)>2 else
false, it is reasonable to let and/or be the fastest possible operator the
machine can provide.

In other words, say what you mean and don't depend on tricks.