Trailing-Edge
-
PDP-10 Archives
-
BB-D480C-SB_1981
-
cmpblo.bli
There are 12 other files named cmpblo.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) 1973,1981 BY DIGITAL EQUIPMENT CORPORATION
!AUTHOR: S. MURPHY/HPW/TFV
MODULE CMPBLO(SREG=#17,VREG=#15,FREG=#16,DREGS=4,RESERVE(0,1,2,3))=
BEGIN
GLOBAL BIND CMPBLV = 6^24 + 0^18 + 48; ! Version Date: 23-Jul-81
%(
***** 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
***** End Revision History *****
)%
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<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;
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<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;