Google
 

Trailing-Edge - PDP-10 Archives - BB-4157E-BM - fortran-compiler/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) 1974,1981 BY DIGITAL EQUIPMENT CORPORATION
!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