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.