donn@sdchema.UUCP (05/27/84)
I have to apologize... I've posted three articles on this subject before and NONE of them contained a fix for the underlying bug, which is still lurking in the depths of the f77 compiler, waiting to strike at the unwary. As yet I STILL don't have a complete fix, but I can supply a hack that will cause all the symptoms of the bug to disappear. I've known about the problem for several weeks, thanks to the efforts of Jerry Berkman at UC Berkeley and Robert Elz at the University of Melbourne, but for various reasons I haven't gotten around to posting anything and since the bug is a major disaster I thought I would simply post my hack. The basic problem is that the code for recycling stack temporaries is broken. The compiler makes special arrangements for recycling stack temporaries after their usefulness comes to an end. It does this by using a special null operation type ('SKFRTEMP') that has the effect of returning specified stack temporaries to the pool of available temporaries (the 'templist'). For example, a DO loop limit temporary is allocated on the stack at the start of a loop, and (if everything goes right) the temporary is returned to the temporary pool after the intermediate code for the loop is emitted. Later the compiler may pull this temporary from the pool and use it (for example) as a place to put the address of the return value of a function that returns objects of type COMPLEX. Unfortunately someone apparently decided that this arrangement broke something in the register allocation code, because immediately prior to register allocation the compiler returns ALL stack temporaries to the pool (in optimize() in f77pass1/bb.c). This of course defeats the effort to keep things like DO loop limit temporaries from being trod on. The mkargtemp() code that Bob Corbett supplied to me and which I posted to the net has the effect of ensuring that the code that processes subroutine calls has its own pool of temporaries to draw on, so that it doesn't reach into the (tainted) general pool. My own earlier fix (to exdo()) causes DO loop limits to be exempted from stack temporary recycling. Neither of these fixes does anything about temporaries that are created as a result of loop optimization, however, and even with BOTH fixes in place the compiler will still generate incorrect code. My hack simply turns off the recycling of stack temporaries. This means that the stacks of f77 programs will be larger than before, but the programs will WORK rather than die mysterious deaths. Here is the hack (in mkaltmpn() in usr.bin/f77/src/f77pass1/proc.c): ------------------------------------------------------------------------ *** /tmp/,RCSt1007713 Sun May 27 13:36:43 1984 --- proc.c Thu May 24 20:54:16 1984 *************** *** 978,983 * remove it from the list and return it */ for(oldp=CHNULL, p=templist ; p ; oldp=p, p=p->nextp) { q = (Addrp) (p->datap); --- 997,1003 ----- * remove it from the list and return it */ + #ifdef notdef for(oldp=CHNULL, p=templist ; p ; oldp=p, p=p->nextp) { q = (Addrp) (p->datap); *************** *** 996,1001 return(q); } } q = autovar(nelt, type, lengp); q->istemp = YES; --- 1016,1022 ----- return(q); } } + #endif notdef q = autovar(nelt, type, lengp); q->istemp = YES; ------------------------------------------------------------------------ I may post one or two more fixes from my backlog before I change jobs next month, but I have been told not to work on f77 until after I leave so there may be some delay... Hacking on weekends, Donn Seeley UCSD Chemistry Dept. ucbvax!sdcsvax!sdchema!donn 32 52' 30"N 117 14' 25"W (619) 452-4016 sdcsvax!sdchema!donn@nosc.ARPA PS Who claims credit for inventing the identifier 'notdef'? PPS Does anyone occasionally compile things with 'cc -Dnotdef' just to see what will happen?