Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!akgua!mcnc!idis!mi-cec!dvk From: dvk@mi-cec.UUCP (Dan Klein) Newsgroups: net.lang.c Subject: C "neatener" - another example (#9) Message-ID: <212@mi-cec.UUCP> Date: Sun, 19-Feb-84 16:26:06 EST Article-I.D.: mi-cec.212 Posted: Sun Feb 19 16:26:06 1984 Date-Received: Tue, 21-Feb-84 08:48:34 EST Lines: 60 This is a continuation of my diatribe on "C doesn't optimize, it neatens". In this and other articles, I compare a true optimizing compiler (Bliss-32 running under VMS) to a code neatener (C running under BSD 4.1c). Any and all counterexamples are welcome. However, this is NOT a comparison of the languages. Both C and Bliss have their good and bad points. This is simply a comparison of the code they generate. As in all examples, the source code and uncensored assembly code is presented. In all examples, the C source and Bliss source are as nearly identical as language differences permit. I have not taken advantage of any "tricks" to get either language to perform better or worse than the other. The optimizer was enabled for both languages. -Dan Klein, Mellon Institute, Pittsburgh (412)578-3382 ============================================================================= In this example I declare three variables as register variables, clear them, and pass them to a routine. Well, C loses again. 1) Each variable gets the same value (namely 0), but Bliss saves space and time by having three CLRL's, while C does a CLRL and then MOVL's the first register into the other two. This is apparently a maneuver to save space when the right hand side is complex (i.e. calculate it once, and then put the known result into the other destinations). It loses here, since s CLRL is faster than a MOVL. 2) C allocates R9, R10, and R11, while Bliss uses R0, R1, and R2. This in itself is no big deal, but the C routine has to save three registers on routine entry, while Bliss only has to save 1 (namely R2, since R0 and R1 are the return registers). Compare the entry masks to see this. 3) The biggest lose of them all! C does three consecutive PUSHL's to pass the arguments to "alpha". Bliss knows that all the parameters are registers, and does 1 PUSHR. C could have done this too (i.e. the registers are declared in the right order to do this). While the register pushes take the same amount of time, the instruction interpretation is slower in C, and of course, the volume of code is greater. ----------------------------------------+------------------------------------- external routine alpha; | extern alpha(); | routine TEST : novalue = | test() begin | { register a,b,c; | register int a, b, c; | a = b = c = 0; | a = b = c = 0; alpha(.a, .b, .c); | alpha(a, b, c); end; | } | | .data .TITLE FOO | .text | LL0: .align 1 .EXTRN ALPHA | .globl _test | .set L13,0xe00 .PSECT $CODE$,NOWRT,2 | .data | .text TEST: .WORD ^M| _test: .word L13 CLRL R2 | clrl r9 CLRL R1 | movl r9,r10 CLRL R0 | movl r10,r11 PUSHR #^M | pushl r9 CALLS #3, W^ALPHA | pushl r10 RET | pushl r11 | calls $3,_alpha | ret