Trailing-Edge
-
PDP-10 Archives
-
FORTRAN-10_V7wLink_Feb83
-
mova.bli
There are 12 other files named mova.bli in the archive. Click here to see a list.
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
! OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
!COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1974, 1983
!AUTHOR: NORMA ABEL/SJW/DCE/EGM
MODULE MOVA(RESERVE(0,1,2,3), SREG=#17,VREG=#15, FREG=#16, DREGS=4)=
BEGIN
GLOBAL BIND MOVAV= 6^24 + 0^18 + 30; ! Version Date: 20-Jul-81
%(
***** Begin Revision History *****
17 ----- ----- CREATE MODULE
18 ----- ----- FIX HAULASS NOT TO MOVE COMMON SUBS CREATED IH
THIS LOOP
19 ----- ----- FIX HAULASS NOT TO MOVE .R VARIABLE ASSIGNMENTS
20 ----- ----- FIX 19.
21 ----- ----- DONT TRY TO MOVE ASSIGNMENTS THAT ARE TRU
BRANCHES OF LOGICAL IFS
22 ----- ----- IF THE ASSIGNMENT TO BE MOVED IS ONE
THAT ASSIGNS A VARIABLE THAT IS PART OF THE
LOOP CONTROL EXPR MAKE IT INTO A SEPARATE
ASSIGNMENT
23 ----- ----- CHECK THAT ANY ASSIGNMENT TO BE MOVED IS
SURE TO BE EXECUTED. ALSO MAKE SURE THE
VARIABLE IS NOT REFERENCED BEFORE THAT
ASSIGNMENT.
24 ----- ----- MISSING DOT . IN REDEFPT
25 ----- ----- HAULASS IS NOT MOVING STATEMENTS
IF USE THAT PROCEEDS ASSIGNMENT IS THE
ASIGNMENT ITSELF.
26 456 QA784 GIVE FINDTHESPOT 2ND PARAM = TOP IN HAULASS
***** Begin Version 5B *****
27 623 ----- FIX QUALIFY TO CALL ONLIST ONLY IF THE DOCHNGL
EXISTS (IE, WE'RE NOT IN AN IOLIST): THIS IS
NECESSARY TO USE A BLIS10 NEWER THAN 7B(222)
28 647 25315 FIX REDEFPT TO HANDLE SKEWED TREES WITH ARRAY REFS
***** Begin Version 6 *****
29 770 EGM 20-May-80 29339
Correct HAULASS to really move simple assignment statements
when possible.
30 1055 DCE 24-Feb-81 -----
Fix HAULASS so that it correctly finds occurrences of variables
within loops (including innermore loops, CSEs, etc.)
***** End Revision History *****
)%
!MODULE CONTAINS ROUTINES ASSOCIATED
!WITH MOTION OF SIMPLE ASSIGNMENT
!STATEMENTS.
SWITCHES NOLIST;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
SWITCHES LIST;
REQUIRE OPTMAC.BLI;
EXTERNAL TOP,UNIQVAL;
MAP PHAZ2 TOP;
GLOBAL ROUTINE UNLIST(LSTHEAD, ITM, ITMSIZ)=
BEGIN
!IF ITM IS ON THE LINKED LIST HEADED BY LSTHEAD
!DELETE IT (IF POSSIBLE)
!RETURN 1 IF IT IS THE FIRST ITEM ON THE LIST
! DELETION MUST BE AT UPPER LEVEL
!RETURN 0 IN ALL OTHER CASES
!
!THE LIST LOOKS LIKE
!
!--------------------------------------------------------!
! ITEM ! CLINK !
!--------------------------------------------------------!
!
EXTERNAL SAVSPACE;
REGISTER BASE T;
MAP BASE LSTHEAD:ITM;
IF .LSTHEAD EQL 0 THEN RETURN 0;
IF .LSTHEAD [LEFTP] EQL .ITM THEN RETURN 1;
T_.LSTHEAD;
LSTHEAD_.LSTHEAD[RIGHTP];
WHILE .LSTHEAD NEQ 0 DO
BEGIN
IF .LSTHEAD[LEFTP] EQL .ITM THEN
BEGIN
T[RIGHTP]_.LSTHEAD [RIGHTP];
SAVSPACE (.ITMSIZ-1,.LSTHEAD);
RETURN 0;
END;
T_.LSTHEAD;
LSTHEAD_.LSTHEAD[RIGHTP];
END;
END;
!************************************
GLOBAL ROUTINE ONLIST(LSTHEAD,ITM)=
BEGIN
!RETURN TRUE IF ITM IS THE LIST
!HEADED BY LSTHEAD
!THE LIST IS OF THE FORM
!
!LEFT HALF WORD - POINTER TO ITEM
!RIGHT HALF WORD - LINK
!
!LIST IS TERMINATED BY A ZERO LINK
MAP BASE LSTHEAD;
WHILE .LSTHEAD NEQ 0 DO
BEGIN
IF .LSTHEAD[LEFTP] EQL .ITM THEN RETURN 1;
LSTHEAD_.LSTHEAD[RIGHTP];
END;
0
END;
GLOBAL ROUTINE QUALIFY(WARG)=
BEGIN
!TREEPTR POINTS TO AN EXPRESSION
!WARG IS 1 OR 2 INDICATING
!WHICH ARGUMENT TO LOOK AT
!QUALIFY RETURNS TRUE IF
! THE ARGUMENT IN QUESTION IS
! 1. NOT ON DOCHNGL
! 2. GETS A UNIQUE ASSIGNMENT IN THE LOOP
! (I.E. IS ON UNIQVAL)
EXTERNAL TREEPTR,LENTRY;
MAP PEXPRNODE TREEPTR;
IF .WARG THEN
BEGIN
!LOOK AT ARG 1
IF (.TREEPTR[DEFPT1] NEQ 0) AND (.TREEPTR[DEFPT1] NEQ .LENTRY)THEN
RETURN(
%[623]% (IF .TOP [SRCOPT] EQL 0 ! NO OPT BLOCK IF IN
%[623]% THEN 1 ! AN IOLIST (IMPLIED DO)
%[623]% ELSE NOT ONLIST (.TOP [DOCHNGL],.TREEPTR [ARG1PTR]))
AND
ONLIST(.UNIQVAL,.TREEPTR[ARG1PTR])
);
END ELSE
BEGIN
IF (.TREEPTR[DEFPT2] NEQ 0) AND (.TREEPTR[DEFPT2] NEQ .LENTRY) THEN
RETURN (
%[623]% (IF .TOP [SRCOPT] EQL 0 ! NO OPT BLOCK IF IN
%[623]% THEN 1 ! AN IOLIST (IMPLIED DO)
%[623]% ELSE NOT ONLIST (.TOP [DOCHNGL],.TREEPTR [ARG2PTR]))
AND
ONLIST(.UNIQVAL,.TREEPTR[ARG2PTR])
)
END;
0
END;
GLOBAL ROUTINE REDEFPT(EXPR, SHAPE)=
BEGIN
!RE-EXAMINE THE DEFINITION POINTS OF
!THE EXPRESSION. IF THE
!PARENT IS AN ASSIGNMENT STATEMENT
!AND THE LEFT HAND SIDE IS
! 1. NOT ON DEFCHNGL
! 2. ON UNIQVAL
!THEN MAKE THE DEFPT LENTRY
EXTERNAL TREEPTR, LENTRY;
MAP BASE TREEPTR;
REGISTER BASE DAD;
MAP BASE EXPR;
IF (DAD_.EXPR[PARENT]) EQL 0 THEN RETURN;
!IS THE PARENT AN ASSIGNMENT TO A SCALAR
IF .DAD[OPRCLS] EQL STATEMENT THEN
IF .DAD[SRCID] EQL ASGNID THEN
IF .DAD[A1VALFLG] THEN
BEGIN
TREEPTR_.EXPR;
IF .SHAPE EQL SKEW THEN
BEGIN
TREEPTR_.EXPR[ARG1PTR];
IF QUALIFY(2) THEN
![647] FOR THE SKEWED TREE CASE, THERE MAY BE AN ARRAY REFERENCE AT
![647] THE BOTTOM OF THE TREE WHICH HAS RESULTED IN A HASH ENTRY FOR
![647] THE ARRAY REF AND LEAF. IN THIS CASE, WE MUST CHANGE THE
![647] DEFINITION POINT IN THE HASH ENTRY TOO.
%[647]% BEGIN
%[647]% EXTERNAL HASHIT,TBLSRCH;
%[647]% DAD_.TREEPTR[ARG1PTR];
%[647]% IF .DAD[OPRCLS] EQL ARRAYREF THEN
%[647]% BEGIN !MIGHT BE A HASHED ARRAY REFERENCE
%[647]% LOCAL BASE TMP;
%[647]% HASHIT(.TREEPTR,STGHT);
%[647]% TMP_TBLSRCH();
%[647]% IF .FLAG THEN !YES, WAS HASHED ALREADY
%[647]% IF .TMP[USECNT] EQL 1 THEN !AND THIS WAS IT
%[647]% IF .TMP[HA1] EQL .TREEPTR[ARG2PTR] THEN
%[647]% TMP[HDEF1]_.LENTRY
%[647]% ELSE TMP[HDEF2]_.LENTRY
%[647]% END;
%[647]% TREEPTR[DEFPT2]_.LENTRY
%[647]% END;
TREEPTR_.EXPR;
IF QUALIFY(2) THEN
TREEPTR[DEFPT2]_.LENTRY;
END ELSE
BEGIN
!UNARY OR STGHT
IF QUALIFY(1) THEN EXPR[DEFPT1]_.LENTRY;
IF QUALIFY(2) THEN EXPR[DEFPT2]_.LENTRY;
END;
END;
END;
GLOBAL ROUTINE HAULASS=
BEGIN
!MOVE SIMPLE ASSIGNMENT STATEMENTS
!IF POSSIBLE CALLED AFTER MOVCNST SO ALL COMPUTATIONS
!ARE A SINGLE .O VARIABLE
EXTERNAL PHAZ2 CSTMNT:TOP;
EXTERNAL UNIQVAL,LENTRY,FINDTHESPOT,LOKINDVAR,CONTVAR;
EXTERNAL CONTVAR,MAKASGN,GETOPTEMP,LEND,INDVAR;
%[770]% EXTERNAL CORMAN;
%[770]% REGISTER BASE PB;
%[770]% REGISTER PHAZ2 T;
LABEL HAULIT;
CSTMNT_.TOP[BUSY];
WHILE .CSTMNT NEQ 0 DO
BEGIN
HAULIT:
!IS IT AS ASSIGNMENT OF A SCALAR
!AND NOT A TRUE BRANCH OF A LOGICAL IF
%[770]% IF (.CSTMNT[SRCID] EQL ASGNID)
AND (.CSTMNT[SRCLINK] NEQ 0 ) THEN
IF .CSTMNT[A1VALFLG] AND .CSTMNT[A2VALFLG] THEN
BEGIN
!STOP!
!DO NOT MOVE A .O ON THE RIGHT IF TOLENTRY
!IS SET (SET IN GLOBMOV)
PB_.CSTMNT[RHEXP];
IF .PB[IDDOTO] EQL SIXBIT".O" THEN
IF NOT .PB[IDATTRIBUT(TOLENTRY)] THEN
LEAVE HAULIT;
!DO NOT MOVE .R ASSIGNMENTS EITHER
PB_.CSTMNT[LHEXP];
IF .PB[IDDOTO] EQL SIXBIT".R" THEN
LEAVE HAULIT;
![770] IF THIS LOOP HAS ENTRIES (SHOULD HAVE AN EXTENDED RANGE) OR
![770] IF EITHER LEAF APPEARS IN COMMON OR EQUIVALENCE, SKIP THE MOVE
%[770]% IF .TOP[HASENT] THEN LEAVE HAULIT;
%[770]% PB_.CSTMNT[LHEXP];
%[770]% IF .PB[IDATTRIBUT(INCOM)] OR
%[770]% .PB[IDATTRIBUT(INEQV)] THEN LEAVE HAULIT;
%[770]% PB_.CSTMNT[RHEXP];
%[770]% IF .PB[IDATTRIBUT(INCOM)] OR
%[770]% .PB[IDATTRIBUT(INEQV)] THEN LEAVE HAULIT;
!OK MOV'EM OUT
IF ONLIST(.UNIQVAL, .CSTMNT[LHEXP]) AND
NOT ONLIST(.TOP[DOCHNGL],.CSTMNT[RHEXP])THEN
BEGIN
!ONE MORE SIDE TRIP.
!IF THE ASSIGNED VARIABLE IS USED IN THE
!DO LOOP CONROL COMPUTATION.
!MAKE THE CONTROL COMPUTATION A SEPARATE
!ASSIGNEMNT STATEMENT OUTSIDE THE LOOP
IF CONTVAR(.TOP[DOLPCTL],.CSTMNT[LHEXP]) THEN
BEGIN
T_.TOP[DOLPCTL];
TOP[DOLPCTL]_PB_GETOPTEMP(INTEGER);
T_MAKASGN(.PB,.T);
!FIND WHERE TO PUT IT AND PUT IT
! TELL FINDTHESPOT TO STOP AT TOP
PB _ FINDTHESPOT (.LENTRY,.TOP);
T[SRCLINK]_.PB[SRCLINK];
PB[SRCLINK]_.T;
END;
!ONE MORE CHECK:
!FORGET IT ALL TO GETHER IF THE
!ASSIGNMENT STATEMENT IS NOT SURE TO
!BE EXECUTED.
IF .CSTMNT[SRCOPT] NEQ 0 THEN
BEGIN
!USE OPTIMIZER INFO ONLY IF IT
!IS THERE
T_.TOP;
DO
T_.T[POSTDOM]
UNTIL
(.T EQL .CSTMNT)
OR (.T EQL .LEND)
OR (.T EQL 0);
IF .T NEQ .CSTMNT THEN LEAVE HAULIT;
END;
!ALSO CHECK FOR A USE THAT PRECEEDS THIS
!ASSIGNMENT.
!ELIMINATE THE RIGHT HAND SIDE OF THIS
!STATEMENT .
IF CONTVAR(.CSTMNT[RHEXP],.CSTMNT[LHEXP]) THEN
LEAVE HAULIT;
![1055] We now need to determine whether there are uses of the INDVAR
![1055] occurring anywhere within this loop. Unfortunately, it is not
![1055] sufficient to test the BUSY list for at least two reasons:
![1055] recently created common subexpressions are not on the BUSY list,
![1055] and innermore loops have no way to pass out the information
![1055] regarding uses of variables. Therefore, we must take the rather
![1055] painful course of walking the entire loop using the CLINK field
![1055] so as to be certain that we do not miss any uses of INDVAR.
%[1055]% T_.TOP[CLINK];
!SAVE INDVAR, CUZ WE ARE GOING TO
!MULTIPLEX THE TESTREPLACMENT
!ROUTINES.
PB_.INDVAR;
INDVAR_.CSTMNT[LHEXP];
WHILE .T NEQ .CSTMNT DO
BEGIN
%[770]% IF LOKINDVAR(.T) NEQ 0
%[770]% THEN
%[770]% BEGIN
%[770]% INDVAR_.PB; ! RESTORE
%[770]% LEAVE HAULIT
%[770]% END;
%[770]% IF .T[SRCID] EQL IFLID THEN
%[770]% IF LOKINDVAR(.T[LIFSTATE]) NEQ 0
%[770]% THEN
%[770]% BEGIN
%[770]% INDVAR_.PB; ! RESTORE
%[770]% LEAVE HAULIT
%[770]% END;
%[1055]% T_.T[CLINK];
END;
!RESTORE INDVAR
INDVAR_.PB;
!FIND WHERE TO PUT THE ASSIGNEMNT WE ARE REALLY MOVING
!TELL FINDTHESPOT TO STOP AT TOP
T _ FINDTHESPOT (.LENTRY, .TOP);
![770] NOW WE MUST 'MOVE' THE ASSIGNMENT STATEMENT OUT OF THE LOOP
![770] WHILE KEEPING THE GRAPH INTACT. THIS IS DONE BY LINKING IN A
![770] NEW ASSIGNMENT STATEMENT OUTSIDE THE LOOP, COPYING THE RELEVANT
![770] SOURCE FIELDS FROM THE ORIGINAL, AND CHANGING THE ORIGINAL NODE
![770] TO A CONTINUE (WITH 1 EXTRA WORD)
%[770]%
%[770]% PB_.T[SRCLINK]; ! SAVE LINK
%[770]% NAME<LEFT>_SRCSIZ+ASGNSIZ;
%[770]% T_(T[SRCLINK]_CORMAN());! CREATE NEW NODE
%[770]% T[SRCLINK]_.PB; ! LINK IT IN
%[770]% T[CW1]_.CSTMNT[CW1]; ! FLAGS AND SRCID
%[770]% T[SRCISN]_.CSTMNT[SRCISN];! KEEP THE ISN
%[770]% T[RHEXP]_.CSTMNT[RHEXP];! JUST THE EXPRESSION
%[770]% T[LHEXP]_.CSTMNT[LHEXP];! JUST LH SIDE
%[770]%
![770] CHANGE THE ORIGINAL NODE TO A CONTINUE NODE
%[770]% CSTMNT[SRCFLAGS]_0; ! NO FLAGS
%[770]% CSTMNT[SRCOPER]_STOPERC(STATEMENT,CONTID);
%[770]% CSTMNT[SRCISN]_0; ! RETAIN OPT INFO
%[770]% CSTMNT[RHEXP]_0; ! RETAIN LABEL
%[770]% CSTMNT[CW4]_0; ! CLEANUP
END;
END;
CSTMNT_.CSTMNT[BUSY];
END;
END;
END
ELUDOM