saj@iuvax.UUCP (02/15/84)
#N:iuvax:9500002:000:555 iuvax!apratt Feb 15 00:44:00 1984 In reading through the Lattice C manual, I came across the note that the compiler detects and discards statements like i+j; which have no side effects. This brings to mind the fact that any expression is a legal statement. With that in mind, can anybody tell me the likely difference between if ( i ) j++; else k++; and i ? j++ : k++ ; ...? Surely there will be differences in the compiled code.. Can somebody tell me what they are likely to be? ---- "Can YOU whistle at 300 baud?" -- Allan Pratt ...decvax!ihnp4!inuxc!iuvax!apratt
keesan@bbncca.ARPA (Morris Keesan) (02/16/84)
------------------------------ It is unclear that there will be any differences between the compiled code for if (i) j++; else k++; and i ? j++ : k++ ; Certainly, the compiler's discarding of statements with no side effects doesn't imply anything of the sort. I recently made a similar enhancement to BBN's C compiler (based on the Dennis Ritchie PDP-11 C compiler), making it not generate code for operations with no side effects (such as the statement "i+j;"), and when I ran the two statements above through it, it produced identical code. In my case, this means that I didn't include ?: in my list of "operators with no side effects". I see no reason to expect that the implementers of Lattice C were any less careful. An interesting effect of the way I implemented the enhancement is that I get different code for if (i) j+1 ; else k+1; and i ? j+1 : k+1 ; because in the first case j+1 and k+1 are statements, and thus get discarded, leaving an empty "if" framework which gets dropped by the optimizer. In the second case, j+1 and k+1 are subexpressions of ?:, and the additions get generated. I'm not too concerned about this, since the main reason for my enhancement was to avoid generating unnecessary conversion code for some casts being generated internally. It would be interesting to see what the Lattice C compiler does with this, though. -- Morris M. Keesan {decvax,linus,wjh12,ima}!bbncca!keesan keesan @ BBN-UNIX.ARPA
usenet@abnjh.UUCP (usenet) (02/17/84)
The system V pcc compiler for the 3B20S generates two more instructions for "i ? j++ : k++ ;" than it does for "if (i) j++ else k++;" In the former case, it is apparently attempting to get the value of the result of the expression (namely the prior value of j or k, depending on the value of i) into a register. Even though it never uses the value in the register for anything! It does this regardless of the setting of the "-O" (optimize) flag. The only effect of the -O flag is to replace jumps to returns by returns. Rick Thomas ihnp4!abnji!rbt or ihnp4!abnjh!usenet
guy@rlgvax.UUCP (Guy Harris) (02/18/84)
> The system V pcc compiler for the 3B20S generates two more > instructions for > "i ? j++ : k++ ;" > than it does for > "if (i) j++ else k++;" > In the former case, it is apparently attempting to get the > value of the result of the expression (namely the prior value > of j or k, depending on the value of i) into a register. > Even though it never uses the value in the register for anything! > It does this regardless of the setting of the "-O" (optimize) flag. > The only effect of the -O flag is to replace jumps to returns by > returns. Well, if you said l = i ? j++ : k++ ; it would be using the value in question (the previous value of j or k). Either it's too tricky to teach PCC how to deal with expressions whose value is being thrown out (I suspect, by the way, that explicitly throwing the value out by casting to "void" won't help), or it was decided that it wasn't worth the trouble. Also, "-O" isn't a full-blown optimizer, it's a peephole and "final" (to use Bliss-11 compiler terminology) optimizer and doesn't catch all suboptimal code. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy
mark@laidbak.UUCP (Mark Brukhartz) (02/21/84)
Some machine-dependent code uses "discarded values" for parameters to asm() (assembly language) escapes. For example: a + b; /* Assume result goes to r0 */ asm(" (something using r0) "); /* Do something funny with r0 */ The "a + b" could just as easily be "a < b ? a++ : b++". Such code assumes that the compiler and optimizer will not ignore the "unneeded" statement or value. Quite a bit of recent Berkeley code uses asm() escapes to generate fast VAX code. I don't like this any more than you do, but it's something to keep in mind when considering a change to the compiler. Mark Brukhartz {allegra,ihnp4,ittral,trsvax}!laidbak!mark
emjej@uokvax.UUCP (02/23/84)
#R:iuvax:9500002:uokvax:3000019:000:1536 uokvax!emjej Feb 17 11:35:00 1984 /***** uokvax:net.lang.c / iuvax!apratt / 12:44 am Feb 15, 1984 */ .... With that in mind, can anybody tell me the likely difference between if ( i ) j++; else k++; and i ? j++ : k++ ; ...? Surely there will be differences in the compiled code.. Can somebody tell me what they are likely to be? /* ---------- */ I can only tell you what the difference would be in my code generator. The latter code (?:) would generate worse code in this context, since it looks locally like someone is going to use the results of the conditional expression. The if/else would look like cmp 0,<i> jeq Ln inc 1,<j> jbr L(n+1) Ln: inc 1,<k> L(n+1): ... while the ?: would look like cmp 0,<i> jeq Ln mov <j>,t0 a temporary register inc 1,<j> jbr L(n+1) Ln: mov <k>,t0 inc 1,<k> L(n+1): ... (The comparison might not be there if we knew that we'd just evaluated i so as to set flags.) All it means is that I'm not bright enough to notice that you're not using the old values of j and k for the conditional expression, and that I'm generating code for a machine whose addressing modes don't have side-effects. (It was fun to implement post-increment and decrement so as to avoid unnecessary copies, by the way--you just remember how much to tweak things just before discarding them. Watch out for base registers used to access things that you want to compare, because deferring increments on them may wipe out the condition code! In that case, just bias the offset by the increment amount and do it right away.) James Jones