MODULE CMPB(SREG=#17,VREG=#15,FREG=#16,DREGS=4,RESERVE(0,1,2,3))= BEGIN !THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED ! OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. !COPYRIGHT (C) 1973,1977 BY DIGITAL EQUIPMENT CORPORATION !AUTHOR: S. MURPHY/HPW GLOBAL BIND CMPBV = 2^24 + 1^18 + 47; !VERSION DATE: 14-JUNE-74 %( REVISION HISTORY 46 ----- ----- MAKE REGCANDIDATES TABLE INTO A LINKED LIST 47 ----- ----- MUST END A BASIC BLOCK WHEN HAVE A CALL INSIDE A LOGICAL IF )% FORWARD CMPBLOCK(0),SRCHREGCANDATE(1),ADDREGCANDATE(2),SAVREGCONTAINING(1); EXTERNAL CGERR; !ROUTINE FOR INTERNAL COMPILER ERRORS SWITCHES NOLIST; REQUIRE FIRST.BLI; REQUIRE TABLES.BLI; SWITCHES LIST; EXTERNAL SAVSPACE,CORMAN; 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= %(************ THE TOP LEVEL ROUTINE FOR THE FIRST PASS OF THE BASIC BLOCK REGISTER ALLOCATOR. THIS ROUTINE CAUSES COMPLEXITY WALK TO BE PERFORMED FOR EVERY STATEMENT IN A BASIC BLOCK. A BASIC BLOCK IS TERMINATED BY: 1. A LABEL WHICH IS REFERENCED OTHER THAN AS A FORMAT 2. A DO STATEMENT 3. FOR PURPOSES OF REGISTER ALLOCATION, A CALL STATEMENT (SINCE SUBROUTINES ARE ASSUMED TO CLOBBER ALL REGISTERS) 4. AN ENTRY POINT THIS ROUTINE IS CALLED WITH THE GLOBAL 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, RETURNS CSTMNT=0. THIS ROUTINE CLEARS THE REGCANDIDATES TABLE WHEN IT HAS COMPLETED THE PASS OVER A BASIC BLOCK. IF THE LAST STATEMENT OF THE BASIC BLOCK WAS A DO STATEMENT IT LEAVES THE LOOP INDEX IN THE REGCANDIDATES TABLE FOR CONSIDERATION THE NEXT BASIC BLOCK. IT IS ASSUMED THAT WHEN THIS ROUTINE IS CALLED FOR A GIVEN BASIC BLOCK, THE REGCANDIDATES TABLE IS IN THE STATE IN WHICH THIS ROUTINE LEFT IT AFTER PROCESSING THE PRECEEDING BASIC BLOCK. ************)% BEGIN EXTERNAL CSTMNT; !POINTER TO CURRENT STATEMENT BEING PROCESSED EXTERNAL ISN; !GLOBAL USED FOR ERROR DIAGNOSTICS, ! CONTAINS THE INTERNAL SEQ NO OF THE ! STMNT BEING PROCESSED MAP BASE CSTMNT; EXTERNAL CMSTMN; !ROUTINE TO PERFORM COMPLEXITY WALK OVER A STATEMENT OWN PEXPRNODE STLABEL; !POINTER TO LABEL TABLE ENTRY FOR THE LABEL ON THIS !STATEMENT (IF ANY) ROUTINE CLRREGCANDIDATES= %(********** LOCAL ROUTINE TO CLEAR THE REGCADIDATES TABLE **********)% BEGIN LOCAL RGCTBLENTRY RGLST; !PREVIOUS LINK LOCAL RGCTBLENTRY RGLNK; !CURRENT LINK RGLNK_.REGLINK; !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; BLKISN_1; !1ST STMNT IN THE BLOCK HAS BLOCK-ISN 1 %(***WALK THRU ALL STATEMENTS IN THE BLOCK***)% UNTIL .CSTMNT EQL 0 !UNTIL REACH END OF PROGRAM DO BEGIN ISN_.CSTMNT[SRCISN]; !THIS GLOBAL MUST INDICATE THE SEQ NO OF ! THE STMNT BEING PROCESSED (FOR ERROR DIAGS) CMSTMN(); !PERFORM COMPLEXITY WALK FOR THE STATEMENT POINTED TO !BY CSTMNT IF .CSTMNT[SRCID] EQL DOID !IF THIS STATEMENT WAS A DO STATEMENT THEN BEGIN CLRREGCANDIDATES(); !CLEAR THE REGCANDIDATES TABLE %(***SET THE FIRST ENTRY IN THE REGCANDIDATES TABLE TO THE DO LOOP INDEX***)% ADDREGCANDATE(.CSTMNT[DOSYM],.CSTMNT); %(***RETURN WITH CSTMNT POINTING TO THE STATEMENT AFTER THE DO STATEMENT***)% CSTMNT_.CSTMNT[SRCLINK]; RETURN END ELSE IF .CSTMNT[SRCID] EQL CALLID !IF THIS STATEMENT WAS A CALL STATEMENT OR .CSTMNT[SRCID] EQL SFNID ! OR A STMNT FN OR (IF .CSTMNT[SRCID] EQL IFLID ! OR A LOGICAL IF THEN BEGIN REGISTER BASE SUBSTMNT; SUBSTMNT_.CSTMNT[LIFSTATE]; IF .SUBSTMNT[SRCID] EQL CALLID ! CONTAINING A CALL STMNT THEN TRUE ELSE FALSE END ELSE FALSE ) THEN BEGIN CLRREGCANDIDATES(); !CLEAR THE REGCANDIDATES TABLE CSTMNT_.CSTMNT[SRCLINK]; !RETURN WITH CSTMNT POINTING TO THE STATEMENT RETURN !AFTER THE CALL STATEMENT END ELSE IF (STLABEL_.CSTMNT[SRCLBL]) NEQ 0 !IF THIS STMNT HAS A LABEL THEN BEGIN IF .STLABEL[SNDOLVL] NEQ 0 ! WHICH TERMINATES A DO LOOP THEN ! THEN THIS STMNT TERMINATES A BEGIN ! BASIC BLOCK CLRREGCANDIDATES(); !CLEAR THE REGCANDIDATES TABLE CSTMNT_.CSTMNT[SRCLINK]; !RETURN WITH CSTMNT POINTING TO THE STMNT AFTER RETURN ! THE LOOP TERMINATION STMNT END; END; CSTMNT_.CSTMNT[SRCLINK]; !GO ON TO THE NEXT STATEMENT %(*****IF THE NEXT STATEMENT HAS A LABEL WHICH IS REFERENCED OTHER THAN AS A FORMAT OR DO LOOP TERMINATOR, RETURN WITH CSTMNT POINTING TO THAT STATEMENT*****)% IF .CSTMNT EQL 0 !IF HAVE REACHED END OF PROGRAM THEN BEGIN END ELSE IF .CSTMNT[SRCID] EQL ENTRID !IF THE NEXT STMNT IS AN ENTRY, OR .CSTMNT[SRCID] EQL SFNID ! OR A STMNT FN, IT THEN ! WILL START A NEW BASIC BLOCK BEGIN CLRREGCANDIDATES(); !CLEAR TABLE OF VARS LEFT IN REGS RETURN END ELSE IF (STLABEL_.CSTMNT[SRCLBL]) NEQ 0 !IF NEXT STMNT HAS A LABEL THEN BEGIN IF .STLABEL[SNREFNO] GTR 1 !NUMBER OF TIMES THIS LABEL IS REFERENCED OTHER THAN !AS A FORMAT (INCLUDING THE DEFINITION AS A NEQ) THEN BEGIN IF .STLABEL[SNREFNO]-1 !IF THE NO OF REFS TO THIS LABEL GTR .STLABEL[SNDOLVL] ! GTR THAN NO OF DO LOOPS IT TERMINATES ! (IE IF REF'D OTHER THAN BY DO) THEN ! THEN THE PRECEEDING STMNT ENDED BASIC BLOCK BEGIN CLRREGCANDIDATES(); !CLEAR THE REGCANDIDATES TABLE RETURN END END END; BLKISN_.BLKISN+1; !INCR SEQ NO OF STMNT BEING PROCESSED END; !END OF LOOP TO WALK THRU ALL STATEMENTS IN THE BLOCK CLRREGCANDIDATES(); !AT END OF PROGRAM, TURN OFF ALL "RGCANDFLG"S END; !END OF ROUTINE CMPBLO 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; !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) NEQ 0 THEN IF .RGLST[RGVAR] EQL .SYMENTRY THEN BEGIN RETURN RGLST[RGINITUSE]_.USEPTR END; %(***SET UP NEW ENTRY***)% NAME_RGCENTSIZE+1; !SET SIZE OF NODE RGLNK_CORMAN(); !ALLOCATE NODE IF .REGLINK EQL 0 THEN BEGIN %(***FIRST LINK***)% REGLINK_REGLINK_.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_.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[VALTYPE] EQL DOUBLPREC !FOR DOUBLE PRECISION OPERATIONS AND .KA10FLG !ON THE KA10 THEN RETURN FALSE; ! WE DONT HAVE ROUTINES TO DO OPS TO BOTH 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;