Hi Roberto,
On 5/25/2011 12:23 PM, Roberto Waltman wrote:
>> I remember thinking about "peephole optimizers" and wondering how
>> they could be effective ("Shirley the compiler knows what code it
>> *just* emitted? Why would it ever do something as inane as
>> 'STORE X; LOAD X'?"). But, if you saw how stanzas were "pasted"
>> together, you could see lots of opportunities for this kind
>> of micro-optimization!
>
> My favorite example of obvious but missed optimization was a Fortran
> compiler for HP-1000 minis, that would always generate a return
> instruction at the end of a function even when the last statement was
> RETURN.
>
> (OK, for purists, the "return" instruction was an indirect jump
> through the first word of the function, lets call it JUMPBACK for now)
Like the PDP-8?
> so,
>
> FUNCTION xxx
> ....
> END
>
> would generate a bunch of instructions ending in
> ....
> JUMPBACK
>
> while this,
>
> FUNCTION xxx
> ....
> RETURN
> END
>
> would generate a bunch of instructions ending in
> ....
> JUMPBACK
> JUMPBACK
>
> To hamilton, Yes - For "simple minded" compilers you can reverse
> generate code that is very close to the original.
> This FORTRAN compiler was very predictable, but I doubt you can find a
> Hewlett-Packard RTE-II system running it.
> You may try Ron Cain's original Small-C compiler for the 8080.
While Cain's compiler wasn't *commercial*, it illustrates the
type of "mechanical replacement" of C statements with assembly
language stanzas that I was talking about.
Here's a toy bit of code run through the Small-C compiler
with the C source interspersed. Note that even on this tiny
bit of code, you can see how the compiler "thinks" (note the
metric butt-load of "helper routines" -- CC* --invoked!):
---------8<----------8<--------------8<----------------
;<><><> Small-C V1.2 DOS--CP/M Cross Compiler <><><>
;<><><><><> CP/M Large String Space Version <><><><><>
;<><><><><><><><><><> By Ron Cain <><><><><><><><><><>
;
ORG 100H
LHLD 6
SPHL
CALL CCGO
CALL QZMAIN
CALL QZEXIT
;#define SUCCESS (0)
;#define FAILURE (27)
;#define LENGTHY "a lot of"
;#define MAX_ATTEMPTS (10)
;main() /* return type & void not supported */
QZMAIN:
;{
; char x; /* uninitialized */
DCX SP
; int attempts; /* initialiZers unsupported */
PUSH B
; int start, end;
PUSH B
PUSH B
; char interval[20]; /* >= max( (sprintf(end - start)/attempts,
"%f"), sizeof
;LENGTHY) ) */
XCHG
LXI H,-20
DAD SP
SPHL
XCHG
; start = gettime();
LXI H,22
DAD SP
PUSH H
CALL QZGETTIME
POP D
CALL CCPINT
; attempts = 0;
LXI H,24
DAD SP
PUSH H
LXI H,0
POP D
CALL CCPINT
; while (x = getchar()) {
CC2:
LXI H,26
DAD SP
PUSH H
CALL QZGETCHAR
POP D
MOV A,L
STAX D
MOV A,H
ORA L
JZ CC3
; if (x == 'Q') {
LXI H,26
DAD SP
CALL CCGCHAR
PUSH H
LXI H,81
POP D
CALL CCEQ
MOV A,H
ORA L
JZ CC4
; printf("Got X = %x\n", x);
LXI H,CC1+0
PUSH H
LXI H,28
DAD SP
CALL CCGCHAR
PUSH H
CALL QZPRINTF
POP B
POP B
; ringbell();
CALL QZRINGBELL
; }
; if (++attempts >= MAX_ATTEMPTS) {
CC4:
LXI H,24
DAD SP
PUSH H
CALL CCGINT
INX H
POP D
CALL CCPINT
PUSH H
LXI H,10
POP D
CALL CCGE
MOV A,H
ORA L
JZ CC5
; printf("Giving up after %d iterations!\n", attempts);
LXI H,CC1+13
PUSH H
LXI H,26
DAD SP
CALL CCGINT
PUSH H
CALL QZPRINTF
POP B
POP B
; return FAILURE;
LXI H,27
XCHG
LXI H,27
DAD SP
SPHL
XCHG
RET
; }
; end = gettime();
CC5:
LXI H,20
DAD SP
PUSH H
CALL QZGETTIME
POP D
CALL CCPINT
; if (end < start) {
LXI H,20
DAD SP
CALL CCGINT
PUSH H
LXI H,24
DAD SP
CALL CCGINT
POP D
CALL CCLT
MOV A,H
ORA L
JZ CC6
; /* overflow */
; interval = LENGTHY;
LXI H,0
DAD SP
LXI H,CC1+46
; } else {
JMP CC7
CC6:
; sprintf(interval, "%f", (end - start) / attempts);
LXI H,0
DAD SP
PUSH H
LXI H,CC1+55
PUSH H
LXI H,24
DAD SP
CALL CCGINT
PUSH H
LXI H,28
DAD SP
CALL CCGINT
POP D
CALL CCSUB
PUSH H
LXI H,30
DAD SP
CALL CCGINT
POP D
CALL CCDIV
PUSH H
CALL QZSPRINTF
POP B
POP B
POP B
; }
CC7:
; printf("There were %d unsuccessful attempts prior to this.\n", attempts);
LXI H,CC1+58
PUSH H
LXI H,26
DAD SP
CALL CCGINT
PUSH H
CALL QZPRINTF
POP B
POP B
; printf("with an average interval of %s seconds.\n", interval);
LXI H,CC1+111
PUSH H
LXI H,2
DAD SP
PUSH H
CALL QZPRINTF
POP B
POP B
;
; return SUCCESS;
LXI H,0
XCHG
LXI H,27
DAD SP
SPHL
XCHG
RET
;}
...