Google
 

Trailing-Edge - PDP-10 Archives - bb-d868e-bm_tops20_v41_2020_dist_1of2 - language-sources/gt1n.bli
There are 18 other files named gt1n.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) 1977,1978 BY DIGITAL EQUIPMENT CORPORATION
!FILENAME:	H1GTRE.BLI
!DATE:		24 MAY 73	MGM/FLD

%3.%	GLOBAL BIND H1GTV=2;	!MODULE VERSION NUMBER

!  REVISION HISTORY:
!
!  9-19-77  ROUTINE GENGRAPH IS MODIFIED TO FIX BUG#46,
!           NESTED IF THEN ELSE EXPRESSIONS.(COMMON SUB-
!           EXPRESSIONS).
!
!   6-2-77   ROUTINE GTGOTM IS MODIFIED TO FIX BUG #11
!            IN BLISS10.DOC.GADD AND GSTO WAS REPLACED
!            BY GOTM AND DID NO GOOD. THIS WAS DONE FOR OPTIMIZATION.
!	     NOW IN THIS CASE FORGET ABOUT OPTIMIZATION.
!            CASE IS X[]_.X[]+2;.
!

! GRAPH TABLE GENERATION AND INTERPRETATION ROUTINES
!----------------------------------------------------



ROUTINE TREGP(X)= (((.X AND NOT(#37^16)) EQL 0) AND (.X<RTEF> GEQ 16));

%3.1%	GLOBAL ROUTINE FIXOCCF(L,F,T)=
    BEGIN LOCAL YR; 
    !  THIS ROUTINE FIXES THE <OCCF> AND <USEF> FIELDS
    !  IN THOSE CASES WHERE A NODE IS RE-FOUND BEFORE ITS
    !  USE HAS GONE TO ZERO.
    INCR I FROM .F TO .T DO
	IF .GT[.L,.I]<LEFTHALF> EQL GTLEX THEN
	    BEGIN
	    GT[.GT[.L,.I]<LINKF>,0]<OCCF> _
	        MAXER(.GT[.GT[.L,.I]<LINKF>,0]<OCCF>-1,0);
	    IF .GT[.GT[.L,.I]<LINKF>,0]<RESULTF> THEN
		IF (YR_TREGNUM(.GT[.GT[.L,.I]<LINKF>,1])) GEQ 16  THEN
		    DUN(.YR);
	    END
	ELSE IF(YR_TREGNUM(.GT[.L,.I])) GEQ 16 THEN DUN(.YR);
    END;

ROUTINE FIXALLOCCF(L)=
    BEGIN LOCAL N; N_.GT[.L,0]<SUBNF>+2;
    INCR I FROM 3 TO .N DO
	IF .GT[.L,.I]<LEFTHALF> EQL GTLEX THEN
         IF NOT .GT[.GT[.L,.I]<LINKF>,0]<RESULTF> THEN
	    FIXALLOCCF(.GT[.L,.I]<LINKF>);
    FIXOCCF(.L,3,.N)
    END;

%3.1%	GLOBAL ROUTINE MAKGT(N,OP,PTR,DIR)=
    BEGIN LOCAL S,L,GTL;
    !  THIS ROUTINE BUILDS A GRAPH-TABLE ENTRY IN CASE THERE
    !  WASN'T ONE. THE SUBNODE ENTRIES ARE POINTED TO BY THE
    !  VARIABLE PTR -- THERE DIRECTION RELATIVE TO PTR IS KEPT
    !  IN DIR.
    S_2+.N/2;
    GT[L_GETSPACE(.S),0]_ .GRAPHHEAD[GTL_GTHASH(.OP)];
    GRAPHHEAD[.GTL]_.L;
    GT[.L,0]<OCCF>_1;
    GT[.L,0]<SUBNF>_.N;
    GT[.L,1]_0;
    GT[.L,2]_.OP;
    INCR I FROM 0 TO .N-1 DO
	    GT[.L,.I+3]_@(.PTR+.I*.DIR);
    .L
    END;
ROUTINE GTGOTM(O1,O2,OP)=
    BEGIN LOCAL L1,L2,L3,L4,L5; BIND NNDM=7^33;
    !
    ! THIS ROUTINE ATTEMPTS TO RECOGNIZE AND OPTIMIZE THE
    ! CASES IN WHICH A 'TO-MEMORY' OPERATOR MAY BE 
    ! GENERATED. A SPECIAL GT-NODE IS BUILT IN THESE CASES
    ! SO THAT A SPECIAL CODE GENERATOR, 'GOTM', WILL BE
    ! BE CALLED.
    !

    ROUTINE OKOP(X)=(.X<HPRIORITY> GTR #21 AND .X<HPRIORITY> LSS #37
		      AND .X<HPRIORITY> NEQ #30);
    ROUTINE NNTYPE(X)=(.X<LEFTHALF> EQL HNEG OR .X<LEFTHALF> EQL HNOT);
    ROUTINE DOTTYPE(X)= .X<HPRIORITY>EQL #21;
    FUNCTION FIND(E,ATT)=
	BEGIN
	IF NNTYPE(.GT[.ATT,2]) THEN
	    IF .GT[.ATT,3]<LEFTHALF> NEQ GTLEX
		THEN RETURN 0 ELSE ATT_.GT[.ATT,3]<LINKF>;
        L5_IF .GT[.ATT,3]<LEFTHALF> EQL GTLEX
             THEN .GT[.ATT,3]<LINKF> ELSE 0;
	IF DOTTYPE(.GT[.ATT,2]) THEN 
	  (IF .L5 NEQ 0 THEN NOT DOTTYPE(.GT[.L5,2]) ELSE 1) AND
	  (.GT[.ATT,3] EQL .E)
	ELSE 0
	END;



    IF .OP<LEFTHALF> EQL HSTO THEN
	IF (.O1 AND NNDM) EQL 0 THEN
	    IF .O2<LEFTHALF> EQL GTLEX THEN
		IF OKOP(.GT[L1_.O2<LINKF>,2]) THEN
		  IF NOT(.GT[.L1,0]<RESULTF>) THEN
		    BEGIN  L4_4-.GT[.L1,2]<HUNARY>;
		    IF .GT[.L1,.L4]<LEFTHALF> EQL GTLEX THEN
			IF FIND(.O1,.GT[.L1,.L4]<LINKF>) THEN
			    BEGIN ! PHEW--WE GOT ONE
				! DONOT BOTHER TO OPTIMIZE X[1]_.X[1]+5
				! BECAUSE IT DOES NOT ANYWAY.
				!IT GOES TO GOTM,GADD,GSTO AND GOING TO GOTM UNNECESSARY
				!  5_27_77
			     IF .STUTYPE EQL 1 AND .O1<LEFTHALF> EQL GTLEX
			       THEN (STUTYPE_0; RETURN 0);
			    L2_MAKGT(4,NGOTM<0,0>,GT[.L1,2],+1);
			    GT[.L2,4]_ IF .GT[.L1,.L4]<LEFTHALF> EQL GTLEX
				THEN .GT[.GT[.L1,.L4]<LINKF>,0]<OCCF> LEQ 1 ELSE 1;
			    GT[.L2,4]<LEFTHALF>_.L5;
			    GT[.L2,5]_.GT[.L1,.L4];
			    GT[.L2,6]_ IF .OP<HUNARY>
				THEN 0 ELSE .GT[.L1,3];
			    GT[.L1,0]<OCCF>_MAXER(.GT[.L1,0]<OCCF>-1,0);
			    RETURN (GTLEX^18 + .L2)
			    END;
		    END;
    END;
%3.1%	GLOBAL ROUTINE GENGRAPH(OP,N)=
    BEGIN LOCAL S,GTL,L,X,XR,YR; 
	  EXTERNAL NOIFOPT;
    !    
    !    THIS ROUTINE GENERATES THE GRAPH TABLE AND RETURNS A
    !    GRAPH-TABLE LEXEME FOR THE (SUB) TREE(S).  BEFORE A
    !    NEW ENTRY IS MADE THE EXISTING TABLE IS SEARCHED
    !    FOR A COMMON SUB-EXPRESSION, AND, IF FOUND, THE LEXEME
    !    FOR THIS ENTRY IS RETURNED AFTEN APPROPRIATE ADJUSTMENT
    !    OF THE OCCURRENCE COUNTS.
    !
    IDCHECKER(OP,.N);
    IF NOT(.CODETOG) THEN RETURN LITLEXEME(0);

    IF NOT .NOIFOPT				%9-19-77% 
    THEN
    BEGIN
    L_.GRAPHHEAD[GTL_GTHASH(.OP)];
    IF (X_GTGOTM(@(OP-2),@(OP-1),@OP)) NEQ 0 THEN RETURN .X;
    WHILE .L NEQ 0 DO
	BEGIN
	IF .OP EQL .GT[.L,2] THEN
	    BEGIN
	    X_ INCR I FROM 1 TO .N DO
	    	IF @(OP-.I) NEQ .GT[.L,.I+2] THEN BREAK 0
			ELSE IF TREGP(@(OP-.I)) THEN BREAK 0;
	    IF .X NEQ 0 THEN
		!SUCCESS, WE HAVE FOUND A MATCHING ENTRY.
		    BEGIN
		    IF (GT[.L,0]<OCCF>_.GT[.L,0]<OCCF>+1) GTR 1^8-1 THEN ERROR(.NSYM,#773);
		    IF .GT[.L,0]<RESULTF> THEN
			IF (XR_TREGNUM(.GT[.L,1])) GEQ 16 THEN
			    INCRUSEN(.XR);
		IF .GT[.L,0]<RESULTF> THEN FIXALLOCCF(.L) ELSE
		IF .GT[.L,0]<OCCF> GTR 1 THEN FIXOCCF(.L,3,.N+2);
		    RETURN (GTLEX^18+.L)
		    END
	    END;
	L_.GT[.L,0]<LINKF>;
	END;
    END;

    !IF WE REACH THIS POINT WE HAVE SEARCHED THE ENTIRE GRAPH TABLE (SUB-LIST)
    ! AND HAVE NOT FOUND A COMMON SUBEXPRESSION.  THEREFORE WE CREATE
    ! A GRAPH TABLE ENTRY AND LINK IT INTO THE LIST.
    !
    MAKGT(.N,.OP,OP-1,-1)+GTLEX^18
    END;
%3.1%	GLOBAL ROUTINE GTPURGE(TOG)=
    BEGIN LOCAL L,L1,L2; 
    !
    !    THIS ROUTINE PURGES THE GRAPH TABLE OF ALL ENTRIES WHICH
    !    DO NOT HAVE VALID RESULTS STILL HELD IN REGISTERS OR
    !    ARE CONSTITUENTS OF SUCH RESULTS.  IT OPERATES BY FIRST
    !    MARKING ALL SUCH ENTRIES AND THEN RELEASING ALL UNMARKED
    !    ENTRIES.
    !
    !    DEPENDING ON THE VALUE OF 'TOG' WE  DO A MORE OR
    !    LESS DRASTIC PURGE (2=>MORE,  0=>LESS). IN PARTICULAR
    !        TOG=0:	WE SAVE ANY ENTRY WITH A RESULT
    !    		STILL CONTAINED IN A REG.
    !        TOG=1:	WE SAVE ONLT THOSE ENTRIES WITH A NON-ZERO
    !    		'SAVE' FIELD -- IE, THOSE ENTRIES BEING
    !    		PRESERVED ACROSS A 'FORK'.
    !	     TOG=2:	WE SAVE ONLY THOSE ENTRIES WITH A 
    !			SAVE FIELD VALUE GREATER THAN ONE,
    !			THIS IS USUALLY THE CASE JUST BEFIRE
    !			TERMINATING A FORK.
    !
    ROUTINE GTMARK(GTE)=
	BEGIN LOCAL F;
	!
	!  THIS ROUTINE PROPAGATES MARK BITS DOWN AND
	!  FUNNYBITS BACK UP TO PARENTS.
	!
	F_.GT[.GTE,0]<FUNNYBIT>;
	IF .GT[.GTE,0]<MARKBIT> THEN RETURN .F;
	INCR I FROM 3 TO .GT[.GTE,0]<SUBNF>+2 DO
	    IF .GT[.GTE,.I]<LEFTHALF> EQL GTLEX THEN
		F_.F OR GTMARK(.GT[.GTE,.I]<LINKF>);
	GT[.GTE,0]<MARKBIT>_1;
	GT[.GTE,0]<FUNNYBIT>_.F;
	.F
	END;

    INCR I FROM 0 TO GTMASK DO
	BEGIN
	L_.GRAPHHEAD[.I]; 
	WHILE .L NEQ 0 DO
	    BEGIN
	    IF .GT[.L,0]<OCCF> NEQ 0 THEN GTMARK(.L) ELSE
	    CASE .TOG OF
		SET
		IF .GT[.L,0]<ROSF> NEQ 0 THEN
		  IF NOT .GT[.L,0]<RESULTF> THEN GTMARK(.L) ELSE
		  IF TREGNUM(.GT[.L,1]) GEQ 16 THEN GTMARK(.L);
		IF .GT[.L,0]<SAVGEF> GTR 0 THEN GTMARK(.L);
		IF .GT[.L,0]<SAVGEF> GTR 1 THEN GTMARK(.L);
		TES;
	    L_.GT[.L,0]<LINKF>;
	    END;
	END;

    INCR I FROM 0 TO GTMASK DO
	BEGIN
	L_.GRAPHHEAD[.I];  GRAPHHEAD[.I]_0;
	WHILE .L NEQ 0 DO
	    BEGIN
	    L1_.GT[.L,0]<LINKF>;
	    IF .GT[.L,0]<MARKBIT>
		THEN
		    BEGIN
		    GT[.L,0]<LINKF>_.GRAPHHEAD[.I]; GRAPHHEAD[.I]_.L;
		    IF .GT[.L,0]<FUNNYBIT> THEN
			BEGIN
			GT[.L,0]<RESULTF>_0; GT[.L,0]<FUNNYBIT>_0;
			IF (L2_TREGNUM(.GT[.L,1])) GEQ 16 THEN
				SCAN( CTRCTH(.L2),
				    .L,GTLEXP,ERASE)
			END;
		    GT[.L,0]<MARKBIT>_0;
		    END
		ELSE
		    BEGIN
		    IF (L2_TREGNUM(.GT[.L,1])) GEQ 16 THEN
			SCAN ( CTRCTH(.L2),
			    .L,GTLEXP,ERASE);
		    RELEASESPACE(.L,2+.GT[.L,0]<SUBNF>/2)
		    END;
	    L_.L1
	    END;
	END;
    END;
ROUTINE GTID(TOG)=
    BEGIN LOCAL L,NS,OC,RN;
    !
    !    THIS ROUTINE INCREMENTS (TOG=1) OR DECREMENTS (TOG=-1)
    !    ALL 'SAVGE' FIELDS IN THE GRAPH TABLE.  THIS IS DONE TO
    !    PRESERVE THE EXISTING GRAPH TABLE ACROSS
    !    FORKS (E.G. IF-THEN-ELSE).
    !
    INCR I FROM 0 TO GTMASK DO
	BEGIN
	L_.GRAPHHEAD[.I];
	WHILE .L NEQ 0 DO
            BEGIN
	    IF (NS_.GT[.L,0]<SAVGEF>+.TOG) GTR 1^7-1 THEN ERROR(.NDEL,#771) ELSE
	    IF .NS GEQ 0 THEN GT[.L,0]<SAVGEF>_.NS ELSE
		BEGIN
		OC_.GT[.L,0]<OCCF>; GT[.L,0]<OCCF>_0;
		IF .GT[.L,0]<RESULTF> THEN
		    IF (RN_TREGNUM(.GT[.L,1])) GEQ 16 THEN
			WHILE (OC_.OC-1) GEQ 0 DO DUN(.RN);
		END;
	    L_.GT[.L,0]<LINKF>;
	    END;
	END;
    END;


%3.1%	GLOBAL ROUTINE GTINCR=GTID(+1);


%3.1%	GLOBAL ROUTINE GTDECR= GTID(-1);


%3.1%	GLOBAL ROUTINE FIXSIDEEFFECTS=
    BEGIN
    IF .CODETOG THEN
	BEGIN
	IF .NPTFLG AND .SESTOG GEQ 2 THEN CLEARSOME() ELSE
        IF .SESTOG GEQ 8 THEN CLEARSOME() ELSE
	IF .SESTOG GEQ 4 THEN CLEARTEMP();
	GTPURGE(0);
	END;
   END;



%3.1%	GLOBAL ROUTINE GENCODE(LEX,TOG)=
    IF NOT.CODETOG THEN LITLEXEME(0) ELSE
    BEGIN LOCAL R; 
    !
    ! THIS ROUTINE CONTROLS THE ACTUAL GENERATION OF MACHINE
    ! CODE FROM THE TREE STORED IN THE GRAPH-TABLE. THE INPUT
    ! PARAMETER 'LEX' CONTAINS A LEXEME POINTING TO THE
    ! (SUB) TREE WHOSE CODE IS TO BE PRODUCED. THE PARAMETER
    ! 'TOG' CONTROLS THE ACTION OF THE ROUTINE AFTER CODE
    ! HAS BEEN PRODUCED. TOG CONTROLS SUCH THINGS AS HOW THE
    ! GRAPH-TABLE IS CLEANED UP AFTERWARDS.
    !
    VTARGET_.VTARGET OR ( .DEL<LEFTHALF> NEQ HSEMCOL OR .FUTDEL<HCLASS> EQL DCLRTR );
    R_IF ((.TOG GTR 0) AND (.LEX<LEFTHALF> EQL GTLEX)) THEN GENERATOR(.LEX) ELSE .LEX;
    IF .TOG THEN FIXSIDEEFFECTS();
    VTARGET_0;
    .R
    END;
%%
%    THIS ROUTINE WILL SET THE OCCURRENCE COUNTS IN THE GRAPH
  TABLE AND/OR USE-FIELDS IN THE REGISTER TABLE TO REFLECT THE
  USE TO BE EXPECTED FROM A STRUCTURE PARAMETER LEXEME.  THE
  ROUTINE MUST MERELY BE CALLED BEFORE THE 1ST USE OF THE LEXEME
  IN THE STRUCTURE EXPANSION.  IF "CNT" IS NEGATIVE, WE UNLOCK
  REGISTERS THAT NEED IT (CALLED AFTER THE EXPANSION IS COMPLETE).
  THE NEW VALUE OF "LEX" IS RETURNED (AND SHOULD BE SUBSTITUTED
  FOR THE ACTUALS PASSED.
%
%%

%3.1%	GLOBAL ROUTINE FOCGPH(LEX,CNT)=
    BEGIN
    LOCAL REGIND, NEWUSE, GTVEC NODE;
    
    REGIND_NEWUSE_0;
      IF .LEX<LEFTHALF> EQL GTLEX
        THEN BEGIN
               NODE_.LEX<LINKF>;
               NODE[0]<OCCF>_.NODE[0]<OCCF>+.CNT;
               NEWUSE_IF .NODE[0]<RESULTF> THEN
                        IF (REGIND_TREGNUM(.NODE[1])) GEQ 16
                          THEN .RT[.REGIND]<USEF>+.CNT
             END
        ELSE
             IF (REGIND_TREGNUM(.LEX)) GEQ 16
               THEN NEWUSE_.RT[.REGIND]<USEF>+.CNT;
      IF .REGIND GEQ 16
        THEN (INCRUSEN(.REGIND); RT[.REGIND]<USEF>_.NEWUSE);
    .LEX
    END;



!END OF H1GTRE.BLI