Google
 

Trailing-Edge - PDP-10 Archives - FORTRAN-10_Alpha_31-jul-86 - mova.bli
There are 12 other files named mova.bli in the archive. Click here to see a list.
!COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1974, 1986
!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: NORMA ABEL/SJW/DCE/EGM

MODULE MOVA(RESERVE(0,1,2,3), SREG=#17,VREG=#15, FREG=#16, DREGS=4)=
BEGIN


GLOBAL BIND MOVAV= #11^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