Google
 

Trailing-Edge - PDP-10 Archives - FORTRAN-10_V7wLink_Feb83 - 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) DIGITAL EQUIPMENT CORPORATION 1973, 1983
!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;