26a5f65ac94c236f592cfd463f8dbe989d59e3d0
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)optloop.c 5.2 (Berkeley) %G%";
* Loop optimizations, f77 compiler pass 1, 4.2 BSD.
* University of Utah CS Dept. modification history:
* Revision 1.4 84/10/25 01:27:29 donn
* Fixed a subtle bug in removesafe(). When the moved code is an assignment
* into a temporary, we use the lhs to substitute for the expression inside
* the loop. Previously the data structure for the temporary was not copied,
* so later on when the lhs was freed, the substitute was too, turning it
* Revision 1.3 84/08/05 17:04:03 donn
* Changed worthcost() so that it skips variable length strings -- we can't
* make temporaries for these...
* Revision 1.2 84/07/19 11:50:39 donn
* Installed changes to force non-intrinsic subroutines and functions to define
* their arguments (make them ineligible for optimization), function setsuses.
int memno
; /* holds memalloc for TTEMP */
LOCAL Varp table
[TABLESIZE
];
LOCAL Varp
mkbucket(vstg
,memno
)
memno
= (int) p
->tempblock
.memalloc
;
vstg
= p
->addrblock
.vstg
;
memno
= p
->addrblock
.memno
;
badtag ("lookup",p
->tag
);
for (; q
; r
= q
, q
= q
->next
)
if ((q
->vstg
== vstg
) && (q
->memno
== memno
))
return r
->next
= mkbucket(vstg
,memno
);
return table
[key
] = mkbucket(vstg
,memno
);
for (i
= 0; i
< TABLESIZE
; i
++)
LOCAL
int comocount
; /* count of number of code motions done */
if (debugflag
[6]) return;
for (sl1
= firstslot
; sl1
; sl1
= nextslot
)
if (lastlabslot
&& sl1
->label
== lastlabslot
->label
)
first
= optinsert (SKLABEL
,0,lab
,0,lastlabslot
->next
);
for (sl2
= sl1
; sl2
; sl2
= sl2
->next
)
if (sl2
->type
== SKDOHEAD
) match
++;
else if (sl2
->type
== SKENDDO
) match
--;
fatal ("unmatched do in code buffer");
if (sl2
->type
!= SKENDDO
)
fatal ("internal error in optloops");
/* last now points to the SKENDDO slot; the SKNULL slot
* is reached through last->nullslot
last
= (Slotp
) last
->nullslot
;
fprintf (diagfile
,"%d code motion%s performed\n",comocount
,
(comocount
==1 ? "" : "s") );
for (sp
= first
; sp
!= last
->next
; sp
= sp
->next
)
for (sp
= first
; sp
!= last
->next
; sp
= sp
->next
)
for (i
= 0; i
< TABLESIZE
; i
++)
for (p
= table
[i
]; p
; p
= p
->next
)
if (p
->vstg
== STGCOMMON
)
switch (p
->exprblock
.opcode
)
setsuses(p
->exprblock
.leftp
);
setsuses(p
->exprblock
.rightp
);
setsuses(p
->exprblock
.vleng
);
switch (p
->exprblock
.leftp
->tag
)
lhs
= (Addrp
) p
->exprblock
.leftp
;
lhs
= (Addrp
) p
->exprblock
.leftp
;
setsuses(lhs
->memoffset
);
setsuses(p
->exprblock
.rightp
);
setsuses(p
->exprblock
.vleng
);
fatal("O6: l-value expected");
switch (p
->exprblock
.leftp
->tag
)
lhs
= (Addrp
) p
->exprblock
.leftp
;
lhs
= (Addrp
) p
->exprblock
.leftp
;
fatal("O7: l-value expected");
setsuses(p
->exprblock
.leftp
);
setsuses(p
->exprblock
.rightp
);
setsuses(p
->exprblock
.vleng
);
if (p
->exprblock
.leftp
->tag
!= TADDR
)
fatal("O8: subprogram expected");
setsuses(p
->exprblock
.rightp
);
setsuses(p
->exprblock
.vleng
);
if (p
->exprblock
.leftp
->addrblock
.vstg
== STGINTR
) break;
if (p
->exprblock
.rightp
== NULL
) break;
args
= p
->exprblock
.rightp
->listblock
.listp
;
for (; args
; args
= args
->nextp
)
if (args
->datap
->tag
== TADDR
)
lhs
= (Addrp
) args
->datap
;
else if (args
->datap
->tag
== TTEMP
)
lhs
= (Addrp
) args
->datap
;
varinfo
= lookup((Addrp
) p
);
setsuses(p
->addrblock
.memoffset
);
setsuses(p
->addrblock
.vleng
);
varinfo
= lookup((Addrp
) p
);
for (args
= p
->listblock
.listp
; args
; args
= args
->nextp
)
fatal("O9: bad tag value");
for (ch
= p
->listblock
.listp
; ch
; ch
= ch
->nextp
)
s1
= anex(p
->exprblock
.leftp
);
s2
= anex(p
->exprblock
.rightp
);
s3
= anex(p
->exprblock
.vleng
);
switch (p
->exprblock
.opcode
)
expr
= p
->exprblock
.leftp
;
setfirst
= varinfo
->setfirst
&& (varinfo
->sets
== 1);
if (expr
->tag
== TTEMP
&& setfirst
&&
s2
== SCSAFE
&& s3
== SCSAFE
)
if (s2
== SCSAFE
) removesafe (&p
->exprblock
.rightp
);
if (s3
== SCSAFE
) removesafe (&p
->exprblock
.vleng
);
if ((s2
== SCSAFE
) && (s3
== SCSAFE
))
if ((s2
!= SCSAFE
) || (s3
!= SCSAFE
))
if (ISINT(p
->exprblock
.vtype
))
if (ISINT(p
->exprblock
.leftp
->headblock
.vtype
))
if (ISINT(p
->exprblock
.vtype
))
if (safefactor(p
->exprblock
.leftp
) ||
safefactor(p
->exprblock
.rightp
))
if (ISINT(p
->exprblock
.vtype
))
if (!(ISREAL(p
->exprblock
.vtype
) || ISCOMPLEX(p
->exprblock
.vtype
)))
removesafe(&p
->exprblock
.leftp
);
removesafe(&p
->exprblock
.leftp
);
removesafe(&p
->exprblock
.rightp
);
if ((p
->exprblock
.vleng
!= ENULL
) && ( ! ISCONST(p
->exprblock
.vleng
)))
if (s2
== SCFREE
) removesafe (&p
->exprblock
.leftp
);
if (s2
== SCSAFE
) removesafe (&p
->exprblock
.rightp
);
if (s1
== SCSAFE
) removesafe(&p
->exprblock
.leftp
);
if (s2
== SCSAFE
) removesafe(&p
->exprblock
.rightp
);
if (s3
== SCSAFE
) removesafe(&p
->exprblock
.vleng
);
s1
= anex(p
->addrblock
.memoffset
);
s2
= anex(p
->addrblock
.vleng
);
if (s2
== SCFREE
) removesafe(&p
->addrblock
.memoffset
);
if (s2
== SCSAFE
) removesafe(&p
->addrblock
.vleng
);
if (s1
== SCSAFE
) removesafe(&p
->addrblock
.memoffset
);
if (s2
== SCSAFE
) removesafe(&p
->addrblock
.vleng
);
if (ISINT(p
->constblock
.vtype
))
if (abs(p
->constblock
.constant
.ci
) <= 1)
if (ISREAL(p
->constblock
.vtype
))
if (abs(p
->constblock
.constant
.cd
[0]) <= 1.0)
if ((vleng
= p
->addrblock
.vleng
) && ! ISCONST(vleng
))
return NO
; /* Can't make variable length temporaries */
if ((memoffset
= p
->addrblock
.memoffset
) && ! ISCONST(memoffset
))
for (q
= p
->listblock
.listp
; q
; q
= q
->nextp
)
if (worthcost ((expptr
) q
->datap
))
return (cost
>2 ? YES
: NO
);
LOCAL
removesafe(refexpr
)
if (ep
->tag
== TEXPR
&& ep
->exprblock
.opcode
== OPASSIGN
)
if (ep
->exprblock
.leftp
->tag
!= TTEMP
)
fatal ("non-TEMP in assignment to be moved in optloop");
newslot
= optinsert (SKEQ
, ep
, 0, 0, first
);
*refexpr
= (expptr
) cpexpr (ep
->exprblock
.leftp
);
ap
= (Tempp
) gettemp(ep
);
newslot
= optinsert (SKEQ
, mkexpr(OPASSIGN
,cpexpr(ap
),ep
), 0, 0, first
);
optinsert (SKFRTEMP
,ap
->memalloc
,0,0,last
->next
);
return mktemp(p
->headblock
.vtype
, p
->headblock
.vleng
);
badtag ("movefrtemp",expr
->tag
);
for (s
= first
; s
; s
= s
->next
)
if (s
->type
== SKFRTEMP
&& s
->expr
== (expptr
) expr
->memalloc
)
insertslot (s
,last
->next
);