Massive f77 fixes for subroutine argument temporary bugs
donn at sdchema.UUCP
donn at sdchema.UUCP
Sun Apr 8 12:35:07 AEST 1984
Here, as promised, are Bob Corbett's changes to f77 to prevent the
allocation of subroutine argument temporaries from trashing DO loop
limits and other things. I have included the fixes to Bob's changes
which I have made, so if you are already running the changes from
Berkeley and Bob hasn't sent you the latest round of fixes, you will
want to use this code instead.
In any case, this supersedes the bug report I sent out titled 'Bug in
f77 loop optimizer generates incorrect code (serious!)'. If you have
already installed my fix, you will need to remove it. As a reminder,
here are the changes needed to remove my fix in exdo() in exec.c. (All
source files that I'll be referring to are in /usr/src/f77/src/f77pass1.
Also, in each set of diffs, '*' marks old code and '-' marks new or
corrected code.)
---------------------------------------------------------------------------
*** /tmp/,RCSt1020046 Sat Apr 7 20:23:42 1984
--- exec.c Fri Mar 23 14:50:26 1984
***************
*** 465,471
if( CONSTLIMIT )
ctlstack->domax = DOLIMIT;
else
! ctlstack->domax = (expptr) mkaltemp(dotype, PNULL);
if( CONSTINCR )
{
--- 447,453 -----
if( CONSTLIMIT )
ctlstack->domax = DOLIMIT;
else
! ctlstack->domax = (expptr) mktemp(dotype, PNULL);
if( CONSTINCR )
{
***************
*** 476,482
}
else
{
! ctlstack->dostep = (expptr) mkaltemp(dotype, PNULL);
ctlstack->dostepsign = VARSTEP;
}
--- 458,464 -----
}
else
{
! ctlstack->dostep = (expptr) mktemp(dotype, PNULL);
ctlstack->dostepsign = VARSTEP;
}
---------------------------------------------------------------------------
Here are the changes needed for the new set of fixes. Be careful --
they are complicated. Where there are long stretches of new code, it
is probably a good idea to clip out the diffs from this article with an
editor, remove the diff marks and install them directly into the file.
The file 'defs.h' needs a couple new external definitions:
---------------------------------------------------------------------------
*** /tmp/,RCSt1020106 Sat Apr 7 20:34:04 1984
--- defs.h Fri Mar 23 14:50:15 1984
***************
*** 117,122
extern flag anylocals;
extern chainp templist;
extern int maxdim;
extern chainp holdtemps;
extern struct Entrypoint *entries;
--- 133,140 -----
extern flag anylocals;
extern chainp templist;
+ extern chainp argtemplist;
+ extern chainp activearglist;
extern int maxdim;
extern chainp holdtemps;
extern struct Entrypoint *entries;
---------------------------------------------------------------------------
The declarations of these variables are in init.c, and the code needed
to reset them is in procinit() in the same file:
---------------------------------------------------------------------------
*** /tmp/,RCSt1020131 Sat Apr 7 20:38:06 1984
--- init.c Fri Mar 23 14:50:37 1984
***************
*** 112,117
flag toomanyinit;
ftnint curdtelt;
chainp templist = NULL;
chainp holdtemps = NULL;
int dorange = 0;
struct Entrypoint *entries = NULL;
--- 131,138 -----
flag toomanyinit;
ftnint curdtelt;
chainp templist = NULL;
+ chainp argtemplist = CHNULL;
+ chainp activearglist = CHNULL;
chainp holdtemps = NULL;
int dorange = 0;
struct Entrypoint *entries = NULL;
***************
*** 279,284
for(cp = templist ; cp ; cp = cp->nextp)
free( (charptr) (cp->datap) );
frchain(&templist);
holdtemps = NULL;
dorange = 0;
nregvar = 0;
--- 300,308 -----
for(cp = templist ; cp ; cp = cp->nextp)
free( (charptr) (cp->datap) );
frchain(&templist);
+ for (cp = argtemplist; cp; cp = cp->nextp)
+ free((char *) (cp->datap));
+ frchain(&argtemplist);
holdtemps = NULL;
dorange = 0;
nregvar = 0;
---------------------------------------------------------------------------
Subroutine argument temporaries need to be recycled at each statement
boundary (not at each call, unfortunately, since the code generator
moves the definitions of temporaries to the beginning of each
statement; the original Berkeley changes did this incorrectly). This
requires a change in the production for 'stat' in gram.head:
---------------------------------------------------------------------------
*** /tmp/,RCSt1020164 Sat Apr 7 20:43:40 1984
--- gram.head Fri Mar 23 22:46:53 1984
***************
*** 110,115
err("label already that of a format");
else
$1->labtype = LABEXEC;
}
}
| thislabel SINCLUDE filename
--- 126,136 -----
err("label already that of a format");
else
$1->labtype = LABEXEC;
+ }
+ if(!optimflag)
+ {
+ argtemplist = hookup(argtemplist, activearglist);
+ activearglist = CHNULL;
}
}
| thislabel SINCLUDE filename
---------------------------------------------------------------------------
A similar change must occur in putopt() in optim.c:
---------------------------------------------------------------------------
*** /tmp/,RCSt1020183 Sat Apr 7 20:46:23 1984
--- optim.c Fri Mar 23 22:48:42 1984
***************
*** 179,184
badthing("SKtype", "putopt", sp->type);
break;
}
}
--- 195,208 -----
badthing("SKtype", "putopt", sp->type);
break;
}
+
+ /*
+ * Recycle argument temporaries here. This must get done on a
+ * statement-by-statement basis because the code generator
+ * makes side effects happen at the start of a statement.
+ */
+ argtemplist = hookup(argtemplist, activearglist);
+ activearglist = CHNULL;
}
---------------------------------------------------------------------------
Now comes the tough part. A new routine mkargtemp() must be added in
proc.c following the code for mkaltmpn():
---------------------------------------------------------------------------
*** /tmp/,RCSt1020214 Sat Apr 7 20:52:40 1984
--- proc.c Fri Mar 23 14:50:58 1984
***************
*** 1003,1008
fprintf(diagfile,"mkaltmpn new offset %d\n",
q->memoffset->constblock.const.ci);
return(q);
}
^L
/* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
--- 1013,1080 -----
fprintf(diagfile,"mkaltmpn new offset %d\n",
q->memoffset->constblock.const.ci);
return(q);
+ }
+
+
+
+ /* The following routine is a patch which is only needed because the */
+ /* code for processing actual arguments for calls does not allocate */
+ /* the temps it needs before optimization takes place. A better */
+ /* solution is possible, but I do not have the time to implement it */
+ /* now. */
+ /* */
+ /* Robert P. Corbett */
+
+ Addrp
+ mkargtemp(type, lengp)
+ int type;
+ expptr lengp;
+ {
+ ftnint leng;
+ chainp oldp, p;
+ Addrp q;
+
+ if (type == TYUNKNOWN || type == TYERROR)
+ badtype("mkargtemp", type);
+
+ if (type == TYCHAR)
+ {
+ if (ISICON(lengp))
+ leng = lengp->constblock.const.ci;
+ else
+ {
+ err("adjustable length");
+ return ((Addrp) errnode());
+ }
+ }
+
+ oldp = CHNULL;
+ p = argtemplist;
+
+ while (p)
+ {
+ q = (Addrp) (p->datap);
+ if (q->vtype == type
+ && (type != TYCHAR || q->vleng->constblock.const.ci == leng))
+ {
+ if (oldp)
+ oldp->nextp = p->nextp;
+ else
+ argtemplist = p->nextp;
+
+ p->nextp = activearglist;
+ activearglist = p;
+
+ return (q);
+ }
+
+ oldp = p;
+ p = p->nextp;
+ }
+
+ q = autovar(1, type, lengp);
+ activearglist = mkchain(q, activearglist);
+ return (q);
}
^L
/* VARIOUS ROUTINES FOR PROCESSING DECLARATIONS */
---------------------------------------------------------------------------
Finally, the routine putcall() in putpcc.c must be changed to use
mkargtemp() instead of mkaltemp(). This is what was causing the breakage
before, since putcall() was dipping into the pool of temporaries after
the point where that pool is supposed to be restricted.
---------------------------------------------------------------------------
*** /tmp/,RCSt1020263 Sat Apr 7 21:03:51 1984
--- putpcc.c Fri Mar 23 22:51:59 1984
***************
*** 1267,1273
int n, first;
Addrp t;
register expptr q;
! Addrp fval;
int type, type2, ctype, qtype, indir;
type2 = types2[type = p->vtype];
--- 1300,1306 -----
int n, first;
Addrp t;
register expptr q;
! Addrp fval, mkargtemp();
int type, type2, ctype, qtype, indir;
type2 = types2[type = p->vtype];
***************
*** 1312,1318
{
if( ISICON(p->vleng) )
{
! fval = mkaltemp(TYCHAR, p->vleng);
n += 2;
}
else {
--- 1345,1351 -----
{
if( ISICON(p->vleng) )
{
! fval = mkargtemp(TYCHAR, p->vleng);
n += 2;
}
else {
***************
*** 1322,1328
}
else if( ISCOMPLEX(type) )
{
! fval = mkaltemp(type, PNULL);
n += 1;
}
else
--- 1355,1361 -----
}
else if( ISCOMPLEX(type) )
{
! fval = mkargtemp(type, PNULL);
n += 1;
}
else
***************
*** 1356,1362
if(indir)
putx(q);
else {
! t = mkaltemp(qtype = q->headblock.vtype,
q->headblock.vleng);
putassign( cpexpr(t), q );
putaddr(t, NO);
--- 1389,1395 -----
if(indir)
putx(q);
else {
! t = mkargtemp(qtype = q->headblock.vtype,
q->headblock.vleng);
putassign( cpexpr(t), q );
putaddr( cpexpr(t), NO );
***************
*** 1359,1365
t = mkaltemp(qtype = q->headblock.vtype,
q->headblock.vleng);
putassign( cpexpr(t), q );
! putaddr(t, NO);
putcomma(1, qtype, YES);
}
}
--- 1392,1398 -----
t = mkargtemp(qtype = q->headblock.vtype,
q->headblock.vleng);
putassign( cpexpr(t), q );
! putaddr( cpexpr(t), NO );
putcomma(1, qtype, YES);
}
}
---------------------------------------------------------------------------
That should keep you busy for a while...
Donn Seeley UCSD Chemistry Dept. ucbvax!sdcsvax!sdchema!donn
32 52' 30"N 117 14' 25"W (619) 452-4016 sdcsvax!sdchema!donn at nosc.ARPA
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list