Trailing-Edge
-
PDP-10 Archives
-
bb-4157h-bm_fortran20_v10_16mt9
-
fortran-compiler/cmpblo.bli
There are 12 other files named cmpblo.bli in the archive. Click here to see a list.
!COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1973, 1985
!ALL RIGHTS RESERVED.
!
!THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
!ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
!INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
!COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
!OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
!TRANSFERRED.
!
!THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
!AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
!CORPORATION.
!
!DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
!SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
!AUTHOR: S. MURPHY/HPW/TFV/TJK
MODULE CMPBLO(SREG=#17,VREG=#15,FREG=#16,DREGS=4,RESERVE(0,1,2,3))=
BEGIN
GLOBAL BIND CMPBLV = #10^24 + 0^18 + #2227; ! Version Date: 21-Oct-83
%(
***** Begin Revision History *****
46 ----- ----- MAKE REGCANDIDATES TABLE INTO A LINKED
LIST
47 ----- ----- MUST END A BASIC BLOCK WHEN HAVE A CALL
INSIDE A LOGICAL IF
***** Begin Version 6 *****
48 761 TFV 1-Mar-80 -----
Remove test for KA10FLG
***** Begin Version 7 *****
***** End V7 Development *****
2006 TJK 6-Oct-83
Add call to ENDSMZTRIP in CMPBLOCK to determine if the current
statement (pointed to by CSTMNT) should end a basic block by
virtue of ending at least one DO-loop with the MAYBEZTRIP flag
set.
***** Begin Version 10 *****
2227 TJK 21-Oct-83
Rewrite main routine of CMPBLOCK to have it call ENDSBBLOCK to
determine where a basic block ends. Also added external
declaration for ENDSBBLOCK, removed external declaration for
ENDSMZTRIP (now called only by ENDSBBLOCK), and fixed some
comments.
***** End V10 Development *****
***** End Revision History *****
)%
SWITCHES NOLIST;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
SWITCHES LIST;
FORWARD
CMPBLOCK(0),
SRCHREGCANDATE(1),
ADDREGCANDATE(2),
SAVREGCONTAINING(1);
EXTERNAL
CGERR, ! Generates internal compiler errors
%2227% CMSTMN, ! Performs complexity walk for current statement
CORMAN,
%2227% BASE CSTMNT, ! Pointer to current statement being processed
%2227% ENDSBBLOCK, ! Checks if the current statement (pointed to
! by CSTMNT) ends a basic block
%2227% ISN, ! Internal sequence number of statement being processed
%2227% ! (this is used for error messages)
SAVSPACE;
OWN BLKISN; !SEQ NO OF CURRENT STMNT WITHIN THE BASIC BLOCK
%(***DEFINE THE TABLE THATS USED TO REMEMBER WHICH VARS/CONSTS
HAVE THEIR VALS LEFT IN ACS BY THE EXECUTION OF STMNTS IN A
GIVEN BASIC BLOCK
*******)%
OWN REGLINK; !POINTER TO REGCANDIDATES TABLES
!ENTRIES
!EACH ENTRY IS THREE WORDS
!WITH A FORWARD AND BACKWARD LINK
!IN THE FIRST WORD
!LH OF REGLINK IS LAST
!LINK
!RH OF REGLINK IS FIRST LINK
GLOBAL ROUTINE CMPBLOCK = ![2227] Main routine rewritten in this edit
!++
! FUNCTIONAL DESCRIPTION:
!
! This is the top level routine for the first pass of the basic
! block register allocator. It causes a complexity walk to be
! performed for every statement in a basic block.
!
! This routine is called with CSTMNT pointing to the first
! statement of a basic block. It returns with CSTMNT pointing
! to the first statement of the next basic block. If the end of
! the program has been reached it returns with CSTMNT equal to
! zero. The REGCANDIDATES table is cleared when it has
! completed the pass over a basic block.
!
! If the last statement of the basic block was a DO statement,
! and if the only reason for terminating the basic block was
! because of the DO statement, and if the DO-variable doesn't
! have the DBLFLG flag set, then it leaves the DO-variable in
! the REGCANDIDATES table for consideration in the next basic
! block.
!
! The REGCANDIDATES table should be properly initialized for the
! first call to this routine. For subsequent calls, the
! REGCANDIDATES table should be in the state in which this
! routine left it after processing the preceding basic block.
!
! FORMAL PARAMETERS:
!
! NONE
!
! IMPLICIT INPUTS:
!
! CSTMNT points to the first statement of the basic block to be
! processed.
!
! IMPLICIT OUTPUTS:
!
! BLKISN is the basic block internal sequence number of the
! current statement.
!
! CSTMNT points to the next statement to be processed. Upon
! return from this routine, CSTMNT points to the first
! statement of the next basic block to be processed
! (unless we just processed the last basic block of the
! current program unit, in which case CSTMNT is zero).
!
! ISN is the internal sequence number of the statement being
! processed (used for error messages).
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS:
!
! NONE
!
!--
BEGIN
LABEL BLOCK; ! Used to leave basic block processing loop
REGISTER ENDVAL; ! Used to save value returned by ENDSBBLOCK
ROUTINE CLRREGCANDIDATES=
%(**********
LOCAL ROUTINE TO CLEAR THE REGCADIDATES TABLE
**********)%
BEGIN
LOCAL RGCTBLENTRY RGLST; !PREVIOUS LINK
LOCAL RGCTBLENTRY RGLNK; !CURRENT LINK
RGLNK_.REGLINK<RIGHT>; !LOCATE FIRST LINK
UNTIL .RGLNK EQL 0 DO
BEGIN
%(***WALK THRU ALL ENTRIES IN THE TABLE***)%
LOCAL BASE SYMENTRY; !LOCAL TO WORK IN
IF (SYMENTRY_.RGLNK[RGVAR]) NEQ 0 !LOAD SYMBOL/CONST ADR
THEN
BEGIN
%(***CLEAR THE FLAG IN THE SYMBOL
TABLE ENTRY THAT INDICATED THAT THE VARIABLE
WAS IN THE REGCANDIDATE TABLE***)%
SYMENTRY[RGCANDFLG]_0
END;
RGLST_.RGLNK; !REMEMBER NODE ADR
RGLNK_.RGLNK[RGFOR]; !LOCATE NEXT ENTRY
SAVSPACE(RGCENTSIZE,.RGLST) !DELETE THE NODE
END;
REGLINK_0 !CLEAR THE POINTER
END; ! of CLRREGCANDIDATES
BLKISN = 1; ! First statement in basic block has block ISN of 1
! Now perform the complexity walk for each statement in this
! basic block.
BLOCK: WHILE TRUE
DO
BEGIN ! For each statement in basic block
ISN = .CSTMNT[SRCISN]; ! ISN for the current statement
CMSTMN(); ! Do complexity walk for current stmnt
! Check if the current statement is the last statement
! of the basic block by calling ENDSBBLOCK, and save
! the return value in ENDVAL. If it's 0, we continue
! the basic block. Otherwise we end the basic block
! by leaving BLOCK; ENDVAL will be 1 for a normal end
! of the basic block, and 2 if the basic block was
! ended for the sole reason that CSTMNT points to a DO
! statement.
IF (ENDVAL = ENDSBBLOCK()) NEQ 0 ! End of basic block?
THEN LEAVE BLOCK; ! Yes, leave the loop
! The current statement (pointed to by CSTMNT) isn't
! the last statement of the basic block.
CSTMNT = .CSTMNT[SRCLINK]; ! Move to next statement
BLKISN = .BLKISN+1; ! Bump basic block ISN
END; ! For each statement in basic block
! We're at the end of the basic block. The last statement of
! the basic block has had the complexity walk performed on it,
! and is pointed to by CSTMNT. Also, ENDVAL is either 1 or 2;
! 1 for a normal end of the basic block, and 2 if the basic
! block was ended for the sole reason that CSTMNT points to a
! DO statement.
CLRREGCANDIDATES(); ! Clear the REGCANDIDATES table
! If we ended the basic block for the sole reason that the
! current statement is a DO statement (i.e., ENDVAL is 2), we
! set up a REGCANDIDATES table entry for the DO-variable (but
! only if it's a single-word data type).
IF .ENDVAL EQL 2 ! Did BB end because of a DO?
THEN
BEGIN ! Special DO case
REGISTER PEXPRNODE DOVAR; ! DOVAR points to the symbol
DOVAR = .CSTMNT[DOSYM]; ! node for the DO-variable
! If the DO-variable is single-word, set up a
! REGCANDIDATES entry.
IF NOT .DOVAR[DBLFLG] ! Is DO-variable single-word?
THEN ADDREGCANDATE(.DOVAR,.CSTMNT); ! Set up entry
END; ! Special DO case
CSTMNT = .CSTMNT[SRCLINK]; ! Have CSTMNT point to the next stmnt
! (i.e., the first stmnt of the next
! basic block)
END; ! of CMPBLOCK
GLOBAL ROUTINE SRCHREGCANDATE(SYMENTRY)=
%(********
THIS ROUTINE DETERMINES WHETHER THERE IS AN ENTRY IN THE REGCANDIDATES TABLE FOR
THE SYMBOL/CONSTANT INDICATED BY THE PARAMETER "SYMENTRY". IF THERE IS SUCH AN
ENTRY, IT INDICATES THAT THAT VARIABLE/CONSTANT CAN POTENTIALLY HAVE BEEN LEFT
IN A REGISTER BY SOME EARLIER STATEMENT IN THIS BASIC BLOCK.
IF SUCH AN ENTRY IS FOUND, THIS ROUTINE RETURNS A POINTER TO THE PARENT NODE ABOVE
THE ORIGINAL USE OF THE VARIABLE/CONSTANT (I.E. THE EXPRESSION OR STATEMENT NODE
WHOSE EVALUATION LEFT THE VALUE OF THE VARIABLE/CONSTANT IN A REGISTER). THIS
POINTER IS CONTAINED IN THE REGCANDIDATES TABLE ENTRY.
IF THE VARIABLE/CONSTANT INDICATED BY SYMENTRY COULD NOT HAVE BEEN PREVIOUSLY LEFT IN
A REGISTER (I.E. THERE IS NO ENTRY FOR IT IN THE REGCANDIDATE TABLE), THIS ROUTINE
RETURNS ZERO).
********)%
BEGIN
MAP PEXPRNODE SYMENTRY; !POINTER TO THE SYMBOL/CONSTANT TABLE ENTRY FOR THE
!VARIABLE/CONSTANT BEING SEARCHED FOR
LOCAL RGCTBLENTRY CREGCENTRY; !POINTER TO THE ENTRY IN
!THE REGCANDIDATES LIST
!CURRENTLY BEING EXAMINED
IF .SYMENTRY[OPRCLS] NEQ DATAOPR !CAN ONLY HANDLE CONSTS AND VARS
THEN RETURN 0;
IF NOT .SYMENTRY[RGCANDFLG] !FLAG IN SYMBOL/CONSTANT TABLE ENTRIES THAT INDICATES
!WHETHER THAT VARIABLE/CONSTANT MIGHT HAVE BEEN LEFT IN
!A REGISTER (I.E. HAS A REGCANDIDATES TABLE ENTRY)
THEN RETURN 0;
%(***SEARCH THE REGCANDIDATES TABLE FOR THE ENTRY CORRESPONDING TO SYMENTRY.
SEARCH IS DONE STARTING FROM THE LATEST ENTRY AND GOING BACKWARDS (SINCE
THERE MAY BE MORE THAN ONE ENTRY FOR A GIVEN VARIABLE/CONSTANT IN THE
TABLE-AND WE ALWAYS WANT THE LAST SUCH ENTRY).
***)%
CREGCENTRY_.REGLINK<LEFT>; !POINTER TO LATEST ENTRY
UNTIL .CREGCENTRY EQL 0 DO
BEGIN
IF .CREGCENTRY[RGVAR] EQL .SYMENTRY !IF THIS ENTRY CORRESPONDS TO SYMENTRY
THEN
RETURN .CREGCENTRY[RGINITUSE]; !THEN RETURN A POINTER TO THE NODE WHOSE
!EVALUATION LEFT THE VALUE OF THE VARIABLE
!INDICATED IN A REGISTER.
CREGCENTRY_.CREGCENTRY[RGBAK]
END;
%(***IF THE RGCANDFLG WAS SET IN THE SYMBOL TABLE ENTRY AND NO ENTRY WAS FOUND
IN THE REGCANDIDATES TABLE, HAVE A COMPILER ERROR***)%
CGERR();
END; !END OF SRCHREGCANDIDATES
GLOBAL ROUTINE ADDREGCANDATE(SYMENTRY,USEPTR)=
%(**********
THIS ROUTINE ADDS AN ENTRY TO THE REGCANDIDATES TABLE FOR THE USE OF
THE VARIABLE/CONSTANT INDICATED BY THE SYMBOL/CONSTANT TABLE ENTRY
"SYMENTRY" AT THE EXPRESSION/STATEMENT NODE POINTED TO BY "USEPTR".
USEPTR IS ASSUMED TO POINT TO AN EXPRESSION/STATEMENT NODE WHOSE
EVALUATION WILL LEAVE THE VALUE OF THAT VARIABLE/CONSTANT IN A REGISTER.
IF THE REGCANDIDATES TABLE IS FULL, THIS ROUTINE OVERWRITES THE
EARLIEST ENTRY IN THE TABLE.
**********)%
BEGIN
LOCAL RGCTBLENTRY RGLNK; !ENTRY TO CREATE
LOCAL RGCTBLENTRY RGLST; !LAST LINK
MAP PEXPRNODE SYMENTRY;
IF .SYMENTRY[OPRCLS] NEQ DATAOPR !CAN ONLY HANDLE CONSTS AND VARS
THEN RETURN;
IF (RGLST_.REGLINK<LEFT>) NEQ 0 THEN
IF .RGLST[RGVAR] EQL .SYMENTRY
THEN
BEGIN
RETURN RGLST[RGINITUSE]_.USEPTR
END;
%(***SET UP NEW ENTRY***)%
NAME<LEFT>_RGCENTSIZE+1; !SET SIZE OF NODE
RGLNK_CORMAN(); !ALLOCATE NODE
IF .REGLINK EQL 0 THEN
BEGIN
%(***FIRST LINK***)%
REGLINK<RIGHT>_REGLINK<LEFT>_.RGLNK;
RGLNK[RGFOR]_RGLNK[RGBAK]_0
END
ELSE
BEGIN
%(***ADDITIONAL LINK***)%
RGLST[RGFOR]_.RGLNK; !LINK NODE TO END OF CHAIN
RGLNK[RGBAK]_.RGLST; !CREATE BACKWARD LINK
REGLINK<LEFT>_.RGLNK; !POINT TO LAST LINK
RGLNK[RGFOR]_0 !MAKE SURE NO FORWARD LINK
END;
RGLNK[RGVAR]_.SYMENTRY;
RGLNK[RGINITUSE]_.USEPTR;
%(***SET SYMBOL TABLE FLAG INDICATING REGCANDIDATES LINK EXISTS***)%
SYMENTRY[RGCANDFLG]_1;
RETURN
END; !END OF ADDREGCANDATE
GLOBAL ROUTINE SAVREGCONTAINING(SYMENTRY)=
%(********
IF THE VARIABLE/CONSTANT INDICATED BY "SYMENTRY" (A POINTER TO A SYMBOL/CONSTANT TABLE ENTRY)
COULD HAVE BEEN LEFT IN A REGISTER DURING THE EVALUATION OF SOME EXPRESSION/STATEMENT
EARLIER IN THIS BASIC BLOCK, THIS ROUTINE SETS THE FLAG "SAVREGFLG" IN THAT EARLIER
EXPRESSION/STATEMENT NODE-TO INDICATE THAT THE REGISTER CONTAINING THE VALUE
OF THE ARGUMENT UNDER THAT NODE SHOULD BE PRESERVED. THIS ROUTINE
ALSO SETS THE "SONNXTUSE" FIELD OF THAT EXPRESSION/STATEMENT NODE TO
INDICATE THE BLOCK-ISN OF THE STATEMENT BEING PROCESSED WHEN THIS ROUTINE
WAS CALLED. THE GLOBAL "BLKISN" IS ASSUMED TO BE SET TO THAT ISN.
THIS ROUTINE RETURNS "TRUE" IF THE VARIABLE/CONSTANT COULD HAVE BEEN
LEFT IN A REGISTER, "FALSE" IF NOT.
********)%
BEGIN
EXTERNAL EXCHARGS; !ROUTINE TO EXCHANGE THE 2 ARGS OF
! AN OPERATOR IF POSSIBLE (FOR RELATIONALS,
! IT REVERSES THE SENSE OF THE REL)
EXTERNAL SRCHREGCANDATE; !ROUTINE TO DETERMINE WHETHER A GIVEN VARIABLE/CONSTANT
!COULD HAVE BEEN LEFT IN A REGISTER BY EXECUTION OF
!A PREVIOUS STATEMENT. RETURNS A POINTER TO THE
!EXPRESSION/STATEMENT WHOSE EVALUATION LEAVES IT IN A NEG.
OWN PEXPRNODE PREVREFERENCE; !POINTER TO THE EXPRESSION/STATEMENT WHOSE EVALUATION
!LEAVES SYMENTRY IN A REGISTER
PREVREFERENCE_SRCHREGCANDATE(.SYMENTRY);
IF .PREVREFERENCE EQL 0 !IF THE VARIABLE/CONSTANT COULD NOT HAVE BEEN LEFT IN
THEN RETURN FALSE; !A REGISTER, RETURN FALSE
IF .PREVREFERENCE[SAVREGFLG] !IF HAVE ALREADY DETERMINED THAT THIS REGISTER
THEN RETURN TRUE; !SHOULD BE PRESERVED, DO NOT ALTER ANYTHING
IF .PREVREFERENCE[OPRCLS] EQL STATEMENT !IF THE ORIGINAL REFERENCE WAS DIRECTLY UNDER
THEN !A STATEMENT NODE
BEGIN
%(****ASSIGNMENT STATEMENTS THAT WOULD HAVE BEEN COMPUTED TO MEMORY
SHOULD BE COMPUTED TO "BOTH" IF THE VALUE OF THE LHS WILL BE
USEFUL LATER
****)%
IF .PREVREFERENCE[SRCID] EQL ASGNID AND .PREVREFERENCE[MEMCMPFLG]
THEN
BEGIN
REGISTER PEXPRNODE RHNODE; !EXPRESSION ON RHS OF ASSIGNMENT STMNT
RHNODE_.PREVREFERENCE[RHEXP];
IF .RHNODE[SAVREGFLG] !IF HAVE ALREADY DECIDED THAT SHOULD
! SAVE THE OPERAND BEING ADDED(SUBTRACTED, ETC)
! TO MEMORY, DONT CHANGE THE OPERATION
! TO BE TO BOTH
THEN RETURN FALSE;
IF .RHNODE[OPRCLS] EQL SPECOP !IF THE OPERATION IS A "SPECIALLY
! OPTIMIZED OP", ! WE CONT GENERATE OP TO BOTH
! (THIS MAY CHANGE IN A LATER VERSION)
THEN RETURN FALSE;
IF .RHNODE[OPERATOR] EQL CMPMUL !DO NOT HAVE COMPLEX MULTIPLY
OR .RHNODE[OPERATOR] EQL CMPDIV ! AND DIVIDE TO BOTH ROUTINES
THEN RETURN FALSE;
PREVREFERENCE[OPTOBOTHFLG]_1; !SET FLAG FOR "OPERATION TO BOTH"
!IN THE ASSIGNMENT STATEMENT
RHNODE[OPTOBOTHFLG]_1; !AND THE EXPRESSION ON THE RIGHT
!HAND SIDE
END
ELSE
IF .PREVREFERENCE[SRCID] EQL ENTRID !IF PREV REF WAS ON THE PARAMETER
! LIST OF THE SUBROUTINE ENTRY
OR .PREVREFERENCE[SRCID] EQL SFNID !OR OF A STMNT FN
THEN
BEGIN
REGISTER ARGUMENTLIST ARGLST; !PTR TO THE ARGLIST AT THAT ENTRY
IF (ARGLST_
(IF .PREVREFERENCE[SRCID] EQL ENTRID
THEN .PREVREFERENCE[ENTLIST]
ELSE .PREVREFERENCE[SFNLIST])
) EQL 0 THEN CGERR(); !IF THIS ENTRY HAD NO PARAMS
%(***SEARCH THE PARAM LIST FOR THE ELEMENT THAT POINTS TO "SYMENTRY"***)%
INCR I FROM 1 TO .ARGLST[ARGCOUNT]
DO
BEGIN
IF .ARGLST[.I,ARGNPTR] EQL .SYMENTRY !IF THIS ARG LIST ENTRY
THEN ! IS THE ONE FOR "SYMENTRY"
BEGIN
ARGLST[.I,ENTSAVREGFLG]_1; !SET FLAG TO SAVE THIS
! THIS PARAM IN A REG
ARGLST[.I,ENTSONNXTUSE]_.BLKISN; !LOC OF NEXT USE
RETURN TRUE
END
END;
CGERR() !IF THE PARAM LIST AT THIS ENTRY DID NOT INCLUDE "SYMENTRY"
! HAVE AN INTERNAL COMPILER BUG
END;
PREVREFERENCE[SRCSAVREGFLG]_1; !SET FLAG TO "SAVE REGISTER HOLDING VAL OF SON"
PREVREFERENCE[SRCSONNXTUSE]_.BLKISN; !"LOC OF NEXT USE OF SON" TO INDICATE ISN
!OF STMNT BEING EXANIMED NOW
RETURN TRUE
END
ELSE !IF THE ORIGINAL REFERENCE WAS DIRECTLY UNDER AN EXPRESSION
BEGIN
%(***IF THE ORIGINAL USE WAS AS ARG1 OF AN OP TO MEMORY, BUT
WE HAVE SINCE CHANGED THAT OPERATION TO BE PERFORMED TO BOTH,
THEN THE VAL WONT HAVE BEEN LEFT IN A REG***)%
IF .PREVREFERENCE[MEMCMPFLG] AND .PREVREFERENCE[OPTOBOTHFLG]
THEN RETURN FALSE;
%(***IF THE ORIGINAL USE WAS AS AN ARGUMENT OF A RELATIONAL, MAKE SURE THAT
IT IS THE FIRST ARGUMENT OF THE RELATIONAL
***)%
IF .PREVREFERENCE[OPRCLS] EQL RELATIONAL
THEN
BEGIN
IF .PREVREFERENCE[ARG1PTR] NEQ .SYMENTRY
THEN
BEGIN
%(***IF ARG1 OF THE REL WAS A REAL IMMED CONST, DO NOT
EXCHANGE THE ARGS (SINCE CANT DO COMPARE IMMED ON A REAL***)%
IF .PREVREFERENCE[A1IMMEDFLG]
THEN
BEGIN
REGISTER PEXPRNODE ARG1NODE; !ARG1 UNDER THE REL
ARG1NODE_.PREVREFERENCE[ARG1PTR];
IF .ARG1NODE[VALTP1] NEQ INTEG1
THEN RETURN FALSE !CANT SAVE THE VAL OF ARG2
! IN A REG
ELSE EXCHARGS(.PREVREFERENCE)
END
ELSE EXCHARGS(.PREVREFERENCE);
%(***IF A2NEGFLG IS NOW SET (AS A RESULT OF EXCHANGING
THE ARGS, GET RID OF A2NEGFLG BY:
A.LT.-B = -A.GT.B
ETC. (CANNOT HANDLE A2NEGFLG ON A REL IN
CODE GEN)
******)%
IF .PREVREFERENCE[A2NEGFLG]
THEN
BEGIN
PREVREFERENCE[A1NEGFLG]_NOT .PREVREFERENCE[A1NEGFLG];
PREVREFERENCE[A2NEGFLG]_0;
IF NOT EQREL(.PREVREFERENCE[OPERSP])
THEN PREVREFERENCE[OPERSP]_REVREL(.PREVREFERENCE[OPERSP]);
END;
END
END;
PREVREFERENCE[SAVREGFLG]_1; !SET FLAG TO "SAVE REG HOLDING VAL OF SON"
PREVREFERENCE[SONNXTUSE]_.BLKISN; !IN ORIGINAL REFERENCE, SET "LOC OF NEXT USE OF
!SON" TO INDICATE ISN OF STMNT BEING EXAMINED
!NOW
RETURN TRUE
END
END; !END OF SAVREGCONTAINING
GLOBAL ROUTINE INITREGCANDIDATES=
%(**********
ROUTINE TO INIT THE REGCANDIDATES TABLE THE FIRST TIME (WHEN
NO ACTUAL SYMBOL TABLE ENTRIES ARE POINTED TO BY THE REGCANDIDATES
TABLE ENTRIES - AND HENCE NO "RGCANDFLG"S MUST BE CLEARED).
SIMPLY CLEARS THE TABLE
**********)%
BEGIN
REGLINK_0 !CLEAR REGCANDIDATES TABLE POINTER
END;