Trailing-Edge
-
PDP-10 Archives
-
BB-D480F-BB_1985_short
-
pnropt.bli
There are 12 other files named pnropt.bli in the archive. Click here to see a list.
!COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1972, 1985
!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/HPW/MD/SJW/JNG/DCE/TFV/EGM/SRM/CDM/RVM/TJK
MODULE PNROPT(RESERVE(0,1,2,3),SREG=#17,VREG=#15,FREG=#16,DREGS=4)=
BEGIN
! REQUIRES FIRST, TABLES, OPTMAC
GLOBAL BIND PNROPV = #10^24 + 0^18 + #2507; ! Version Date: 21-Dec-84
%(
***** Begin Revision History *****
113 ----- ----- MAKE REDUCE A GLOBAL FOR I/O OPTIMIZATION
114 ----- ----- CALL ARSKOPT TO DO PHASE 2 SKELETON FOR
EXPRESSIONS CREATED BY REDUCE
115 ----- ----- INTERFACE TO IOGPNR TO PROPAGATE AND REDUCE
EXPRESSIONS ON I/O LISTS
116 ----- ----- MAKE LOKDEFPT A GLOBAL ROUTINE
117 ----- ----- TAKE OUT REDUCE TO PUT IT IN TSTR
118 ----- ----- MAKE FOLDER GLOBAL
119 ----- ----- FIXES TO FOLDER FOR DATAOPR, ARRAYREF, IOLSCLS
120 ----- ----- CALL IOGPNR FOR READ/WRITE/ENCODE/DECODE
121 ----- ----- ADD RERED TO IOGPNR
122 ----- ----- STOP LOKDEFPT FROM BOMBING ON A DATAOPR
123 ----- ----- TYPO IN DOPROPAGATE CAUSING VALFLGS ON SYMBOL NODES
124 ----- ----- ZERO DEFPT1 ON AN ARRAYREF
125 ----- ----- FORGOT ASGNPROP IN 124
126 ----- ----- FOR ALL LOOPS OR MAINS ZERO DEFPTS
BETWEEN LENTRY AND TOP
127 ----- ----- ADD POTENTIAL TO REDUCE P2MUL AND P2+1 MULS
128 ----- ----- PROPAGATE THRU DO LOOPS BETTER AND THROUGH
.O VARIBALES
129 ----- ----- NEXT DAY CONTINUE ON 128
130 ----- ----- REDUCE SPECIAL SPECIAL OPS
131 ----- ----- DO NOT PROPAGATE INTO LOOPS ANY VARIABLE
THAT STARTS WITH A DOT .
132 ----- ----- MAKE OLDHEAD A MODULE OWN INSTEAD OF EXTERNAL
133 ----- ----- MAKE DOTOPROPAGATE LOOK AT I/O LISTS AND
ALSO PROPAGATE .O=.O,.O=.R,.S=.O,.I=.O
134 ----- ----- IF MULTIPLE OF 133 HAVE OCCURRED THEN
ELIMINATE .OX=.OX BY MAKING IT A CONTINUE
135 ----- ----- FIX DOTOPROPAGATE SO WE DO NOT BLOW I/O LISTS
136 ----- ----- FIX 135
137 ----- ----- FIX RUBOUT TO CHECK IF VARIABLE BEING
PROPAGATED WAS ALREADY PROPAGATED TO
138 ----- ----- TAKE INCORRECT CALL TO ASGNNN OUT OF
DOPROPAGATE
139 ----- ----- MAKE PROPCASE LOOK AT LH SIDES WHEN PROPAPAGATING TO GET ARRAYREFS
140 ----- ----- DOTOPROPAGATE LOSES NEGS/NOTS. STOP IT.
141 ----- ----- FOLD DABS
142 ----- ----- FOLD PROPAGATED DO LOOP CONTROLS WITH
THE NEG NODE ABOVE THEM
143 ----- ----- IN 142 CHECK FOR FULL NEGATIVE NOT
JUST OPERSP. STUPID!
***** Begin Version 4A *****
144 234 14167 FIX PROPAGATION OF LIB FUNCTION CALLS
WITH CONSTANT ARGUMENT TO PROGRAM ENTRY., (NEA/MD)
145 375 18450 USE .O VAR INSTEAD OF .R FOR CONSTANTS, (DCE)
146 VER5 ----- DON'T ZERO DEFPTS IN CONS1DEF,LOK1DEFPT,
LOK2DEFPT, ASGNPROP
MOVE DEFPT UP WHEN FOLDEE BECOMES A LEAF
SET DEFKEEPER FOR FOLDER
SET DEFPT OF CONSTANT PROPERLY
CALL DFCLEANUP SO .O FLAGS NOT CLEARED, (SJW)
147 421 QA651 DON'T DOTOPROPAGATE .O WHICH CAME FROM .R
(ORFIXFLG => NOT ELIGIBLE), (SJW)
148 465 20657 ZERO INDVAR BEFORE CALLING REDUCE FOR
STATEMENTS BEFORE THE LOOP, SINCE WE OTHERWISE
MIGHT FIND SOME REDUCTIONS (!!!)
149 466 VER5 DON'T TRY TO ZERO DEF POINTS FOR STATEMENTS
BETWEEN LENTRY AND TOP (REMOVES EDIT 465), (SJW)
***** Begin Version 5A *****
150 562 22540 WHEN FOLDING CONSTANTS, TAKE CARE OF EXPRESSIONS
WHICH HAVE NO PARENT POINTER (FIELD IS ZERO), (DCE)
***** Begin Version 5B *****
151 661 24100 DO NOT THROW AWAY LABELED STATEMENTS, (DCE)
152 714 26498 INTERNAL PROBLEM WITH DEF POINTS, (DCE)
***** Begin Version 6 *****
153 761 TFV 1-Mar-80 -----
Add indices for folding /GFLOATING constants
154 775 EGM 17-Jun-80 10-29566
Make DOTOPROPAGATE work reliably for the second and subsequent walks
through the statement nodes.
155 1022 TFV 27-Oct-80 ------
Preserve the bit patterns for octals and literals assigned to reals
under GFLOATING.
156 1060 DCE 6-Apr-81 -----
Fix bug with constant specop negative-number (A*0.5 where A has
a known propagated constant value).
157 1074 SRM 27-May-81 -----
Fix bug in folding logical IFs when the condition is NOT of
a REAL or DP. In PROPAGATE, it was assumed that IFNN would not
alter the data type of the constant; but .NOT. (REAL) has
type logical.
159 1104 EGM 25-Jun-81 --------
When propagating .O variables, handle the neg/not correctly for
assignments.
***** Begin Version 7 *****
158 1212 TFV 29-Apr-81 ------
Replace LITERAL with HOLLERITH.
160 1270 CDM 6-Oct-81 ------
In FOLDER, for type conversion nodes, do no conversions to arguments
for nodes that want real and have octal constant arguments.
161 1415 RVM 9-Nov-81
In VALCNV, preserve the bit pattern for logical constants that are
propagated under GFLOATING. This edit is related to edit 1414.
See REVHST.MAC.
162 1447 CDM/CKS 12-Dec-81
In DOTOPR, change
IF () AND () AND () THEN
to
IF () THEN IF () THEN IF () THEN
so that the last clause is not evaluated unless the first two
are true. Was getting an illegal memory read for reading
beyond what actually existed for a continue statement. Also
some needed prettying of code.
1542 RVM 25-May-82
In VALCNV, always convert OCTAL, HOLLERITH, LOGICAL, and
CONTROL expressions to REAL, even under /GFLOATING. This
removes edits 1022 and 1415 from this module.
***** End V7 Development *****
1742 TFV 14-Apr-83
Fix calls to MISCIO. It handles the IOLIST now.
2001 TJK 22-Sep-83
Fix STMTPROP to correctly construct AOBJN DO-loop control word,
and only when possible.
2031 TJK 6-Jan-84
LOKDEFPT had a bad case for array references. Specifically,
it never called CONS2DEF after a recursive call to itself.
Among other things, this allowed constants with neg flags to
go uncorrected, resulting in bad code.
***** Begin Version 10 *****
2211 TFV 18-Aug-83
Add INQUIRE case to PROPCASE.
2215 TJK 26-Sep-83
Have STMTPROP check for zero-trip (or one-trip for F66)
loops, and have it clear MAYBEZTRIP if not zero-trip.
2217 TJK 28-Sep-83
Have STMTPROP check to see if CTLNEG is set (for DO-loops),
and if so ICE the compiler.
2223 TJK 30-Sep-83
Have STMTPROP check to see if CTLNEG is set (for DO-loops),
and if so have it clear CTLNEG and negate the DO-loop
control expression (which is a constant), instead of
generating an ICE. Also have if defer creating any new
constants until the end of the select case for a DO-loop.
Also remove external decalaration of CGERR.
2374 TJK 15-Jun-84
Allow PNROPT to handle character data. Also fix several bugs.
2507 CDM 20-Dec-84
Remove IDDOT, which is now in FIRST.
***** End V10 Development *****
***** End Revision History *****
)%
SWITCHES NOLIST;
REQUIRE FIRST.BLI;
REQUIRE TABLES.BLI;
REQUIRE OPTMAC.BLI;
SWITCHES LIST;
SWITCHES NOSPEC;
FORWARD
SETPNOT(2),
SETPNEG(2),
FOLDER(1),
CHKPROP,
GRASPDEF(2),
GRABDEF(1),
DOPROPAGATE(1),
VALCNV(2),
FIX1NN(2),
CONS1DEF(1),
FIX2NN(2),
CONS2DEF(1),
LOKDEFPT(1),
ASGNPROP(1),
PROPAGATE,
DEFSUB(2),
IFNN(1),
ASGNNN(1),
STMTPROP(1),
BUNCHPROP(1),
PROPCASE(1),
ELIGIBLE(2),
DOTOPROPAGATE;
EXTERNAL
%1742% CSTMNT,
%1742% DOVARSUBSTITUTE,
%1742% FOLDAIF,
%1742% FOLDLIF,
%1742% LEAFSUBSTITUTE,
%1742% MISCIO,
%1742% MISCOCI,
%1742% SWAPEM;
EXTERNAL CNSTCMB,COPRIX,SPKABA,C1H,C1L,C2H,C2L,CMBEQLARGS,BLCMB,ARCMB,
TBLSEARCH,PREV,LOOPNO;
OWN DEFKEP,DEFKEEPER;
OWN OLDHEAD;
OWN PAPPY; !PARENT POINTER
EXTERNAL INDVAR,CORMAN;
EXTERNAL TOP,BOTTOM,LEND,LENTRY;
MAP PEXPRNODE TOP:LENTRY:LEND;
EXTERNAL MAKPR1;
EXTERNAL REDUCE;
FORWARD FIX1NN,FIX2NN;
FORWARD STMTPROP,ASGNNN;
EXTERNAL QQ;
MAP PHAZ2 QQ;
FORWARD IFNN;
!MACRO TO CALL MAKPR1 TO MAKE A NEG OR NOT NODE AND RETURN IT
MACRO MAKNEGNOT(WHICH)=
MAKPR1(.DAD,NEGNOT,WHICH,.SON[VALTYPE],0,.SON)$;
ROUTINE SETPNOT(DAD,SON)=
BEGIN
!THIS ROUTINE EXAMINES DAD, DETERMINES IF SON IS
!ARG1 OR ARG 2 AND
!COMPLEMENT THE NOTFLG OF THE CORRECT ARGUMENT
EXTERNAL TAKNOTARG;
EXTERNAL SKERR;
MAP BASE DAD:SON;
!IF ITS A STATEMENT LOOK AT ASSIGNEMNT
!LOGICAL AND ARITHMETIC IF.
IF .DAD[OPRCLS] EQL STATEMENT THEN
BEGIN
IF .DAD[SRCID] EQL ASGNID THEN
BEGIN
IF .SON EQL .DAD[RHEXP] THEN
BEGIN
IF NOT .DAD[A2NEGFLG] THEN
DAD[A2NOTFLG]_NOT .DAD[A2NOTFLG]
ELSE
DAD[RHEXP]_MAKNEGNOT(NOTOP);
END
ELSE
BEGIN
IF NOT .DAD[A1NEGFLG] THEN
DAD[A1NOTFLG]_NOT .DAD[A1NOTFLG]
ELSE
SKERR();
END;
END ELSE
IF .DAD[SRCID] EQL IFLID THEN
DAD[A1NOTFLG]_NOT .DAD[A1NOTFLG]
ELSE
IF .DAD[SRCID] EQL IFAID THEN
DAD[A1NOTFLG]_NOT .DAD[A1NOTFLG];
END ELSE
!IT MUST BE AN EXPRESSION. IT HAD BETTER NOT BE
!A FUNCTION CALL (FNCALL)
IF .DAD[ARG1PTR] EQL .SON THEN
BEGIN
IF TAKNOTARG(.DAD) AND NOT .DAD[A1NEGFLG] THEN
DAD[A1NOTFLG]_NOT .DAD[A1NOTFLG]
ELSE
DAD[ARG1PTR]_MAKNEGNOT(NOTOP);
END
ELSE
BEGIN
IF TAKNOTARG(.DAD) AND NOT .DAD[A2NEGFLG] THEN
DAD[A2NOTFLG]_NOT .DAD[A2NOTFLG]
ELSE
DAD[ARG2PTR]_MAKNEGNOT(NOTOP);
END;
END;
ROUTINE SETPNEG(DAD,SON)=
BEGIN
EXTERNAL SETNEG;
!THIS ROUTINE EXAMINES DAD, DETERMINES IF SON IS
!ARG1 OR ARG 2 AND CALLS THE ROUTINE SETNEG TO
!COMPLEMENT THE NEGFLG OF THE CORRECT ARGUMENT
MAP BASE DAD:SON;
!IF ITS A STATEMENT LOOK AT ASSIGNEMNT
!LOGICAL AND ARITHMETIC IF.
IF .DAD[OPRCLS] EQL STATEMENT THEN
BEGIN
IF .DAD[SRCID] EQL ASGNID THEN
BEGIN
IF .SON EQL .DAD[RHEXP] THEN
BEGIN
IF NOT .DAD[A2NOTFLG] THEN
DAD[A2NEGFLG]_NOT .DAD[A2NEGFLG]
ELSE
DAD[RHEXP]_MAKNEGNOT(NEGOP);
END
ELSE
DAD[A1NEGFLG]_NOT .DAD[A1NEGFLG];
END ELSE
IF .DAD[SRCID] EQL IFLID THEN
DAD[A1NEGFLG]_NOT .DAD[A1NEGFLG]
ELSE
IF .DAD[SRCID] EQL IFAID THEN
DAD[A1NEGFLG]_NOT .DAD[A1NEGFLG];
END ELSE
!IT MUST BE AN EXPRESSION. IT HAD BETTER NOT BE
!A FUNCTION CALL (FNCALL)
IF .DAD[ARG1PTR] EQL .SON THEN
BEGIN
IF SETNEG(.DAD,1) THEN ELSE DAD[ARG1PTR]_MAKNEGNOT(NEGOP);
END
ELSE
BEGIN
IF SETNEG(.DAD,0) THEN ELSE DAD[ARG2PTR]_MAKNEGNOT(NEGOP);
END;
END;
ROUTINE FOLDER(EXPR)=
BEGIN
EXTERNAL SETPVAL;
![761] KSPECG, KILFBG, KTYPCG for folding /GFLOATING constants
%[761]% EXTERNAL KSPECB,KSPECG,DNEGCNST,KILFBA,KILFBR,KILFBG;
%[761]% EXTERNAL RELSKOPT,BLSKOPT,ARSKOPT,KTYCM,KTYPCB,KTYPCG;
EXTERNAL NEGFLG,NOTFLG;
MAP PEXPRNODE EXPR;
!A CONSTANT HAS JUST PROPAGATED
!CHECK FOR AND PERFORM ANY POSSIBLE FOLDING ETC
!
%1060% LOCAL PHAZ2 OPEXPR;
%2374% LOCAL BASE TMP;
%1060% REGISTER PHAZ2 T;
OPEXPR_.EXPR; !SAVE TO SEE IF IT REALLY FOLDED
!FOR SOME OPERATIONS WE MAY BE HERE BECAUSE ONE OF
!TWO CONSTANTS IN THE EXPRESSION FOLDED, BUT NOT
!NECESSARILY BOTH. THIS IS OK, IN THAT ROUTINES LIKE RELSKOPT,
!ARSKOPT, ETC HANDLE THIS SITUATION. IT IS NOT
!ACCEPTABLE, HOWEVER, FOR SPECOPS AND INLINFNS.
!SO WE WILL TEST FOR THE THREE EXCEPTIONS AND QUIT
!IF BOTH ARGS ARE NOT CONSTANTS.
!WE MUST ALSO MAKE SURE THAT NEG/NOT FLAGS ARE FOLDED
!INTO ANY CONSTANTS THAT ARE CURRENTLY EXTANT OR CREATED.
EXPR_(
CASE .EXPR[OPRCLS] OF SET
!BOOLEAN
BEGIN
!FOLD NEG/NOT FLAGS, IF THERE
T_.EXPR[ARG1PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX1NN(.EXPR,.EXPR[ARG1PTR]);
T_.EXPR[ARG2PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
PAPPY_.EXPR[PARENT];
!SET NOT FLAG FALSE
NOTFLG_FALSE;
EXPR_BLSKOPT(.EXPR);
!IF BLSKOPT SET NOTFLG THEN WE HAVE TO PASS IT BACK UP
IF .NOTFLG THEN
SETPNOT(.PAPPY,.OPEXPR);
.EXPR
END;
!DATAOPR
BEGIN
RETURN .EXPR
END;
!RELATIONAL
BEGIN
!FOLD NEG/NOT FLAGS IF THERE
T_.EXPR[ARG1PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX1NN(.EXPR,.EXPR[ARG1PTR]);
T_.EXPR[ARG2PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
RELSKOPT(.EXPR)
END;
!FNCALL
.EXPR;
!ARITHMETIC
BEGIN
!FOLD NEG/NOT FLAGS IF THERE
T_.EXPR[ARG1PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX1NN(.EXPR,.EXPR[ARG1PTR]);
T_.EXPR[ARG2PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
!SAVE PARENT POINTER FOR THE NEGFLAG PROPAGATION HASSLE
PAPPY_.EXPR[PARENT];
!SET NEGFLG FALSE
NOTFLG_FALSE;
NEGFLG_FALSE;
EXPR_ARSKOPT(.EXPR);
!IF NEGFLG IS NOW TRUE WE HAVE TO SET THE NEGFLG ON
!PAPPY FOR THE CORRECT ARGUMENT. NOT SET BUT COMPLEMENT.
IF .NEGFLG THEN
SETPNEG(.PAPPY,.OPEXPR);
.EXPR
END;
!TYPECNV
BEGIN
LOCAL BASE ARG2NODE;
!FOLD NEG/NOT FLAGS, IF THERE
T_.EXPR[ARG2PTR];
IF .T[OPR1] NEQ CONSTFL THEN RETURN(.EXPR);
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
!IF THIS IS A CONVERSION FROM LOGICAL (INDICATED BY OPERSP)
! TO DOUBLE PRECISION DO NOT DO IT ELSE THERE WILL
! BE ROUNDING ERRORS ON A KA.
![1270] Also if node wants Real and has non-real constant
! argument then leave before conversions take place.
%1270% T_.EXPR[ARG2PTR];
IF (.EXPR[VALTYPE] EQL DOUBLPREC AND
.EXPR[OPERSP] EQL LOGICAL) OR
%1270% (.EXPR[OPERSP] EQL FROMREAL AND .T[VALTYPE] NEQ REAL)
THEN RETURN(.EXPR);
COPRIX_KTPCNVIX(EXPR);
ARG2NODE_.EXPR[ARG2PTR];
C1H_.ARG2NODE[CONST1];
C1L_.ARG2NODE[CONST2];
CNSTCMB();
MAKECNST(.EXPR[VALTYPE],.C2H,.C2L)
END;
!ARRAYREF
BEGIN
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
!FOLD NEG/NOT FLAGS, IF THERE
T_.EXPR[ARG2PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
EXPR[ARG2PTR]_ARSKOPT(.EXPR[ARG2PTR])
END;
RETURN .EXPR
END;
!CMNSUB
RETURN .EXPR;
!NEGNOT
BEGIN
LOCAL BASE ARGNODE;
!FOLD NEG/NOT FLAGS, IF THERE
T_.EXPR[ARG2PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
ARGNODE_.EXPR[ARG2PTR];
IF .ARGNODE[OPR1] NEQ CONSTFL THEN RETURN(.EXPR);
IF .EXPR[OPERSP] EQL NEGOP THEN
NEGCNST(ARGNODE)
ELSE
NOTCNST(ARGNODE)
END;
!SPECOP
BEGIN
LOCAL BASE ARG1NODE;
%[1060]% MACHOP HRREM=#572;
T_.EXPR[ARG1PTR];
IF .T[OPR1] NEQ CONSTFL THEN RETURN(.EXPR);
IF .T[OPR1] EQL CONSTFL THEN FIX1NN(.EXPR,.EXPR[ARG1PTR]);
ARG1NODE_.EXPR[ARG1PTR];
COPRIX_KSPECOPIX(EXPR);
C1H_.ARG1NODE[CONST1];
C1L_.ARG1NODE[CONST2];
%[1060]% T_.EXPR[ARG2PTR];
%[1060]% HRREM(T,C2L); ! Careful for negative numbers...
CNSTCMB();
MAKECNST(.EXPR[VALTYPE],.C2H,.C2L)
END;
!FIELDREF
BEGIN
END;
!STOERCLS
BEGIN END;
!REGCONTENTS
BEGIN END;
!LABOP
BEGIN END;
!STATEMENT
BEGIN END;
!IOLSCLS
RETURN .EXPR;
!INLINFN
BEGIN
LOCAL BASE ARGNODE;
EXTERNAL KILDAB;
T_.EXPR[ARG1PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX1NN(.EXPR,.EXPR[ARG1PTR]);
ARGNODE_.EXPR[ARG1PTR];
IF .ARGNODE[OPR1] NEQ CONSTFL THEN RETURN(.EXPR);
ARGNODE_.EXPR[ARG2PTR];
IF .ARGNODE NEQ 0 THEN
BEGIN
T_.EXPR[ARG2PTR];
IF .T[OPR1] EQL CONSTFL THEN FIX2NN(.EXPR,.EXPR[ARG2PTR]);
IF .ARGNODE[OPR1] NEQ CONSTFL THEN
RETURN(.EXPR);
END;
ARGNODE_.EXPR[ARG1PTR];
C1H_.ARGNODE[CONST1];
C1L_.ARGNODE[CONST2];
ARGNODE_.EXPR[ARG2PTR];
IF .ARGNODE NEQ 0 THEN
BEGIN
C2H_.ARGNODE[CONST1];
C2L_.ARGNODE[CONST2];
END;
!IF THIS IS DABS SPECIFICALLY SET COPRIX
IF .EXPR[OPERATOR] EQL DABSFNOP THEN
COPRIX_KILDAB
ELSE
COPRIX_KILFOPIX(EXPR);
CNSTCMB();
MAKECNST(.EXPR[VALTYPE],.C2H,.C2L)
END;
%2374% !SUBSTRING
%2374% RETURN .EXPR;
%2374% !CONCATENATION
%2374% RETURN .EXPR;
TES);
!NOW LOOK TO SEE IF ANY PROPAGATION TOOK PLACE
!IF IT DID (THE CONSTANTS FOLDED OR COMBINED) THEN
!CHECK TO SEE THAT DEFPOINTS OF ITEMS LEFT ARE SET
%2374% IF .OPEXPR NEQ .EXPR
%2374% THEN
%2374% BEGIN ! It changed
%2374%
%2374% ! Check to see that fold was indeed to a DATAOPR. For
%2374% ! example, X .AND. .TRUE. folds to X, and setting the
%2374% ! val flag might be incorrect.
%2374%
%2374% IF (T = .OPEXPR[PARENT]) NEQ 0 ! Make sure there's a parent
%2374% THEN IF .T[OPRCLS] NEQ FNCALL
%2374% THEN IF .T[OPRCLS] NEQ CONCATENATION
%2374% THEN IF .EXPR[OPRCLS] EQL DATAOPR
%2374% THEN
%2374% BEGIN ! EXPR is a DATAOPR
%2374%
%2374% SETPVAL(.OPEXPR); ! Set val flags above
%2374%
%2374% ! Determine new definition point
%2374%
%2374% TMP = (IF .EXPR[OPERSP] EQL CONSTANT
%2374% THEN .LENTRY ELSE .DEFKEEPER);
%2374%
%2374% IF .T[OPRCLS] EQL STATEMENT
%2374% THEN
%2374% BEGIN ! Parent is a statement
%2374%
%2374% IF .T[SRCOPT] NEQ 0
%2374% THEN IF .T[SRCID] NEQ DOID
%2374% THEN T[OPDEF] = .TMP;
%2374%
%2374% END ! Parent is a statement
%2374%
%2374% ELSE IF .T[OPRCLS] NEQ IOLSCLS
%2374% THEN
%2374% BEGIN ! Parent is an expression
%2374%
%2374% IF .T[ARG1PTR] EQL .OPEXPR
%2374% THEN T[DEFPT1] = .TMP
%2374%
%2374% ELSE IF .T[ARG2PTR] EQL .OPEXPR
%2374% THEN T[DEFPT2] = .TMP
%2374%
%2374% ELSE IF .T[OPRCLS] EQL SUBSTRING
%2374% THEN IF .T[ARG4PTR] EQL .OPEXPR
%2374% THEN T[DEFPTSS] = .TMP;
%2374%
%2374% END; ! Parent is an expression
%2374%
%2374% END; ! EXPR is a DATAOPR
%2374%
%2374% END; ! It changed
%2374%
%2374% RETURN .EXPR;
END; ! of FOLDER
ROUTINE CHKPROP=
BEGIN
!IF ELIGIBLE GET A DEFINITION POINT FOR THE GLOBAL
!A1NODE. IF THE DEFINITION POINT IS AN ASSIGNMENT OF
!THE VARIABLE TO A CONSTANT THEN RETURN THE CONSTANT IN
!A1NODE AND 1 ELSE REYURN 0
EXTERNAL GETDEF,ONLIST,A1NODE;
MAP PHAZ2 OLDHEAD:A1NODE;
REGISTER BASE T;
!QUIT QUICK IF A1NODE STARTS WITH A DOT. WE MAY LOSE
!.O VARS NOW BUT WILL GET THEM WITH DOTOPROPAGATE
IF .A1NODE[IDDOT] EQL SIXBIT"." THEN RETURN;
!OLDHEAD POINTS TO A DO NODE. CHECK FOR THE LEAF
!CHANGING INSIDE THE LOOP
IF NOT ONLIST(.OLDHEAD[DOCHNGL],.A1NODE) THEN
BEGIN
T_GETDEF(.A1NODE,.OLDHEAD,0);
!IF A VALID DEFINITION POINT IS RETURNED
IF .T NEQ 0 THEN
BEGIN
!IS IT AN ASSIGNMENT STATEMENT
IF .T[OPRS] EQL ASGNOS THEN
BEGIN
IF .T[LHEXP] EQL .A1NODE
AND .T[A2VALFLG] THEN
BEGIN
!ASSIGN A1NODE AND TEST FOR
!CONSTANT
A1NODE_.T[RHEXP];
IF .A1NODE[OPR1] EQL CONSTFL THEN
RETURN 1;
END;
END;
END;
END;
%2374% RETURN 0;
END; ! of CHKPROP
ROUTINE GRASPDEF(EXPR,A2FLG)=
BEGIN
!CHECK EXPR FOR POTENTIAL PROPAGATION.
!CHECK ARG 2 IF A2FKG IS SET. SUBSTITUTE THE
!CONSTANT IF PROPAGATED
EXTERNAL A1NODE;
MAP BASE A1NODE:EXPR;
A1NODE_(IF .A2FLG THEN .EXPR[ARG2PTR] ELSE .EXPR[ARG1PTR]);
IF .A1NODE[OPR1] EQL CONSTFL THEN RETURN;
%2374% IF CHKPROP()
%2374% THEN
%2374% BEGIN ! Replacing with a constant
%2374%
%2374% IF .A2FLG
%2374% THEN
%2374% BEGIN ! Replacing ARG2
%2374%
%2374% EXPR[ARG2PTR] = .A1NODE;
%2374% FIX2NN(.EXPR,.A1NODE); ! Fold neg/not flags
%2374%
%2374% END ! Replacing ARG2
%2374% ELSE
%2374% BEGIN ! Replacing ARG1
%2374%
%2374% EXPR[ARG1PTR] = .A1NODE;
%2374% FIX1NN(.EXPR,.A1NODE); ! Fold neg/not flags
%2374%
%2374% END; ! Replacing ARG1
%2374%
%2374% END; ! Replacing with a constant
END;
ROUTINE GRABDEF(EXPR)=
BEGIN
EXTERNAL DNEGCNST;
MAP PEXPRNODE EXPR;
!EXPR POINTS AT AN EXPRESSION TREE TO BE WALKED
!*****************
!HELPFUL MACROS
!*****************
MACRO SNATCH1=
BEGIN
IF .EXPR[A1VALFLG] THEN
GRASPDEF(.EXPR,0)
ELSE
GRABDEF(.EXPR[ARG1PTR]);
END$;
MACRO SNATCH2=
BEGIN
IF .EXPR[A2VALFLG] THEN
GRASPDEF(.EXPR,1)
ELSE
GRABDEF(.EXPR[ARG2PTR]);
END$;
CASE .EXPR[OPRCLS] OF SET
!BOOLEAN
BEGIN
SNATCH1;
SNATCH2;
END;
!DATAOPR
BEGIN END;
!RELATIONAL
BEGIN
SNATCH1;
SNATCH2;
END;
!FNCALL
BEGIN END;
!ARITHMETIC
BEGIN
SNATCH1;
SNATCH2;
END;
!TYPECNV
BEGIN
SNATCH2;
END;
!ARRAYREF
BEGIN
IF .EXPR[ARG2PTR] NEQ 0 THEN
SNATCH2;
END;
!CMNSUB
BEGIN END;
!NEGNOT
BEGIN
SNATCH2;
END;
!SPECOP
BEGIN
SNATCH1;
END;
!FIELDREF NOT IN RELEASE 1
BEGIN END;
!STORECLS
BEGIN END;
!REGCONTENTS
BEGIN END;
!LABOP
BEGIN END;
!STATEMENT
BEGIN END;
!IOLSCLS
BEGIN END;
!INLINFN
BEGIN
SNATCH1;
IF .EXPR[ARG2PTR] NEQ 0 THEN
SNATCH2;
END;
%2374% !SUBSTRING
%2374% BEGIN
%2374% SNATCH1;
%2374% SNATCH2;
%2374% ! Punt on ARG4 for now
%2374% END;
%2374% !CONCATENATION
%2374% BEGIN END; ! Punt for now
TES;
END;
ROUTINE DOPROPAGATE(STMT)=
BEGIN
!TO EXAMINE ALL STATEMENTS IN THE LOOP HEADED BY STMT
!FOR THE PROPAGATION OF VARIABLES
!STMT IS THE DO STATEMENT
EXTERNAL BASE A1NODE;
LOCAL PEXPRNODE P:PB;
MAP PHAZ2 STMT;
IF .STMT[SRCOPT] EQL 0 THEN RETURN;
OLDHEAD_.STMT;
P_.STMT;
PB_.STMT[DOLBL];
PB_.PB[SNHDR];
DO
BEGIN
!WE NOW HANDLE ONLY ASSIGNMENT STATEMENTS AND DO LOOPS
IF .P[SRCID] EQL ASGNID THEN
BEGIN
IF NOT .P[A1VALFLG] THEN
GRABDEF(.P[LHEXP]);
IF NOT .P[A2VALFLG] THEN
GRABDEF(.P[RHEXP])
ELSE
BEGIN
A1NODE_.P[RHEXP];
%2374% IF CHKPROP()
%2374% THEN
%2374% BEGIN ! Found it
%2374%
%2374% P[RHEXP] = .A1NODE; ! Substitute
%2374% ASGNNN(.P); ! Fix neg/nots
%2374%
%2374% END; ! Found it
END;
END ELSE
IF .P[SRCID] EQL DOID THEN
BEGIN
IF .P NEQ .STMT THEN
IF NOT .P[FLCWD] THEN
BEGIN
A1NODE_.P[DOLPCTL];
IF .A1NODE[OPR1] EQL VARFL THEN
BEGIN
IF CHKPROP() THEN
BEGIN
P[DOLPCTL]_.A1NODE;
STMTPROP(.P);
END;
END ELSE
BEGIN
GRABDEF(.P[DOLPCTL]);
!IF IT PROPAGATED WE COULD HAVE
!LEFT A NEG NODE OVER A CONSTANT
!CHECK FOR THAT AS A SPECIFIC CASE
!AND FOLD IT.
A1NODE_.P[DOLPCTL];
IF .A1NODE[OPR1] EQL NEGFL
AND .A1NODE[A2VALFLG] THEN
BEGIN
!LOOK A LEVEL FURTHER FOR THE
!CONSTANT
A1NODE_.A1NODE[ARG2PTR];
IF .A1NODE[OPR1] EQL CONSTFL THEN
P[DOLPCTL]_NEGCNST(A1NODE);
END;
END;
END;
END;
P_.P[SRCLINK];
END UNTIL .P EQL .PB[SRCLINK];
END;
ROUTINE VALCNV(LHSNOD,RHSNOD)=
BEGIN
!WHEN A CONSTANT TO PROPAGATE HAS BEEN FOUND
!WE MUST PERHAPS PERFORM SOME TYPE CONVERSION WONDERS ON
!IT. SINCE ALL CONSTANTS (REAL) ARE CARRIED IN DOUBLE
!PRECISION, WE MUST ROUND BEFORE USE IF THIS IS A REAL
!VARIABLE. IF THE VALUE TYPE ON BOTH SIDES OF THE
!ASSIGNMENT IS NOT THE SAME, WE MUST ALSO CONVERT THE CONSTANT.
!THIS IS FOR CASES LIKE A=.TRUE..
!ALSO WE DO NOT WANT TO CONVERT DP=".........
!OR DP='....'
![761] KTYPCG and KGFRL for folding /GFLOATING constants
%[761]% EXTERNAL KTYPCB,KTYPCG;
%[761]% EXTERNAL COPRIX,C1H,C1L,C2H,C2L,KDPRL,KGFRL,KGFSPR,CNSTCMB;
MAP BASE RHSNOD:LHSNOD;
!SAME VALTYPE, REAL
IF .LHSNOD[VALTYPE] EQL .RHSNOD[VALTYPE] AND .LHSNOD[VALTYPE]
EQL REAL THEN
BEGIN
![761] Fold DP to SP precision based on /GFLOATING
![761] Do not convert DP to actual SP since exponent widths can differ
%[761]% IF .GFLOAT THEN COPRIX_KGFSPR ELSE COPRIX_KDPRL;
C1H_.RHSNOD[CONST1];
C1L_.RHSNOD[CONST2];
CNSTCMB();
RETURN(MAKECNST(REAL,.C2H,.C2L));
END ELSE
BEGIN
!VALTYPES DIFFERENT
IF .LHSNOD[VALTYPE] NEQ .RHSNOD[VALTYPE] THEN
BEGIN
!CHECK FOR THOSE ADDITIONAL ONES NOT TO CONVERT
IF .LHSNOD[VALTYPE] EQL DOUBLPREC AND
%1212% (.RHSNOD[VALTYPE] EQL HOLLERITH OR
.RHSNOD[VALTYPE] EQL DOUBLOCT) THEN
RETURN(.RHSNOD); !NO CONVERSION
!WE ARE HERE AND WANT TO CONVERT
COPRIX_KKTPCNVIX(.LHSNOD[VALTP2],.RHSNOD[VALTP2]);
C1H_.RHSNOD[CONST1];
C1L_.RHSNOD[CONST2];
CNSTCMB();
RETURN(MAKECNST(.LHSNOD[VALTYPE],.C2H,.C2L));
END;
END;
!ELSE ALL IS OK JUST USE CONSTANT AS IS
RETURN(.RHSNOD);
END;
ROUTINE FIX1NN(EXPR,NUMB)=
BEGIN
!CHECK FOR A NEG AND(SHOULD NEVER BE)/OR NOT FLAG
!OVER ARG1 OF EXPR. ARG1 IS A CONSTANT. NEGATE
!OR COMPLEMENT THE CONSTANT AND FIX ARG1PTR.
!NUMB IS THE CONSTANT.
MAP PEXPRNODE EXPR:NUMB;
EXTERNAL DNEGCNST;
IF .EXPR[A1NEGFLG] THEN
BEGIN
EXPR[ARG1PTR]_NEGCNST(NUMB);
EXPR[A1NEGFLG]_0;
END;
IF .EXPR[A1NOTFLG] THEN
BEGIN
EXPR[ARG1PTR]_NOTCNST(NUMB);
EXPR[A1NOTFLG]_0;
END;
END;
ROUTINE CONS1DEF(EXPR)=
BEGIN
!DETERMINE IF A PROPAGATION CAN OCCUR
!AND DO IT FOR THE FIRST ARGUMENT OF EXPR
!OWN DEFKEEPER _ DEFPT2 IF ARG1 IS OR BECOMES A CONSTANT
! DEFPT1 IF ARG1 REMAINS A VARIABLE
EXTERNAL DNEGCNST,CHOSEN,GLOBREG,LENTRY;
MAP PEXPRNODE EXPR;
LOCAL BASE PC:PB:PA;
!WE ARE LOOKING AT A LEAF
!IF IT IS A CONSTANT OR VARIABLE THAT PROPAGATES
!RETURN 1. THIS MAY CAUSE SOME EXTRA WORK
!IN THAT THE VARIABLE CONSTANT COMBO WILL CAUSE
!AN EXTRA CALL TO LOCAL OPTIMIZATION ROUTINES
!BUT IT IS THE ONLY WAY WE CAN FOLD HAIRY EXPRESSIONS
!THAT COLLAPSE UP FROM A SINGLE PROPAGATE.
PC_.EXPR[ARG1PTR];
IF .PC[OPR1] EQL CONSTFL THEN
BEGIN
FIX1NN(.EXPR,.PC);
DEFKEEPER _ .EXPR [DEFPT2];
RETURN(1);
END;
IF .PC[OPR1] EQL VARFL THEN
BEGIN
!THE LEAF IS A VARIABLE
DEFKEEPER _
PA_.EXPR[DEFPT1];
!DONT MISTAKENLY PROPAGATE THE CONSTANT THAT
!MAY SIT AT LENTRY.
IF .PA EQL 0 OR .PA EQL .LENTRY
THEN RETURN (0);
IF .PA[SRCID] EQL ASGNID AND
.PA[LHEXP] EQL .PC THEN
!THE DEFINITION FPOINT IS AN ASSIGNMENT OF THAT
!VARIABLE
BEGIN
PB_.PA[RHEXP];
!LOOK AT THE RIGHT HAND SIDE
IF .PB[OPR1] EQL CONSTFL THEN
BEGIN
!REALLY GOT ONE!
!SAVE DEFINITION POINT
DEFKEEPER_.EXPR[DEFPT2];
PB_VALCNV(.PA[LHEXP],.PB);
EXPR[ARG1PTR]_.PB;
FIX1NN(.EXPR,.PB);
EXPR [DEFPT1] _ .LENTRY;
![714] REMOVE THE CODE WHICH PURPORTS TO "SAVE THE PROPAGATION"
![714] THIS CAN CAUSE PROBLEMS, AND APPEARS TO DO NO GOOD AT ALL!
RETURN(1)
END;
END;
END;
%2374% ! Remove some dead code, and add an explicit zero return.
%2374%
%2374% RETURN 0;
END;
ROUTINE FIX2NN(EXPR,NUMB)=
BEGIN
!EXPR[ARG2PTR] IS A CONSTANT. SEE THAT NEG AND NOT FLAGS
!ARE FOLDED INTO THE CONSTANT. NUMB IS EXPR[ARG2PTR].
!EQUIVALENT OF FIX1NN FOR ARG2.
MAP PEXPRNODE EXPR:NUMB;
EXTERNAL DNEGCNST;
IF .EXPR[A2NEGFLG] THEN
BEGIN
EXPR[ARG2PTR]_NEGCNST(NUMB);
EXPR[A2NEGFLG]_0;
END;
IF .EXPR[A2NOTFLG] THEN
BEGIN
EXPR[ARG2PTR]_NOTCNST(NUMB);
EXPR[A2NOTFLG]_0;
END;
END;
ROUTINE CONS2DEF(EXPR)=
BEGIN
!DETERMINE IF A PROPAGATION CAN OCCUR AND DO IT
!FOR THE SECOND ARGUMENT OF EXPR
!OWN DEFKEEPER _ DEFPT1 IF ARG2 IS OR BECOMES A CONSTANT
! DEFPT2 IF ARG2 REMAINS A VARIABLE
! NOTE DEFPT1 _ .LENTRY IN CONS1DEF IF ARG1 BECOMES CONSTANT
EXTERNAL DNEGCNST,CHOSEN,GLOBREG,LENTRY;
MAP PEXPRNODE EXPR;
LOCAL BASE PC:PB:PA;
!WE ARE LOOKING AT A LEAF
!SEE COMMENTS IN FRONT OF CONS1DEF
PC_.EXPR[ARG2PTR];
IF .PC[OPR1] EQL CONSTFL THEN
BEGIN
FIX2NN(.EXPR,.PC);
DEFKEEPER _ .EXPR [DEFPT1];
RETURN(1);
END;
IF .PC[OPR1] EQL VARFL THEN
BEGIN
!THE LEAF IS A VARIABLE
DEFKEEPER _
PA_.EXPR[DEFPT2];
!DO NOT INADVERTENTLY PROPAGATE AN INNOCENT
!ASSIGNMENT AT ENTRY
IF .PA EQL 0 OR .PA EQL .LENTRY
THEN RETURN (0);
IF .PA[SRCID] EQL ASGNID AND .PA[LHEXP] EQL .PC THEN
BEGIN
!THE DEFINITION POINT IS AN ASSIGNMENT OF THAT VARIABLE
PB_.PA[RHEXP];
!LOOK AT THE RIGHT HAND SIDE
IF .PB[OPR1] EQL CONSTFL THEN
BEGIN
!REALLY GOT ONE!
PB_VALCNV(.PA[LHEXP],.PB);
EXPR[ARG2PTR]_.PB;
DEFKEEPER _ .EXPR [DEFPT1];
FIX2NN(.EXPR,.PB);
EXPR [DEFPT2] _ .LENTRY;
![714] REMOVE THE CODE THAT PURPORTS TO "SAVE THE PROPAGATION"
![714] IT APPEARS TO CAUSE PROBLEMS AND DO NO GOOD AT ALL!
RETURN(1);
END;
END;
END;
%2374% ! Remove some dead code, and add an explicit zero return.
%2374%
%2374% RETURN 0;
END;
!MACROS TO CHECK ARGS AND SET VALFLAGS WHEN NEEDED.
MACRO VAL1FX(EXPR)=
BEGIN
PA_.EXPR[ARG1PTR];
IF .PA[OPRCLS] EQL DATAOPR THEN
EXPR[A1VALFLG]_1;
END$,
VAL2FX(EXPR)=
BEGIN
PA_.EXPR[ARG2PTR];
IF .PA[OPRCLS] EQL DATAOPR THEN
EXPR[A2VALFLG]_1;
END$,
VALBFX(EXPR)=
BEGIN
VAL1FX(EXPR);
VAL2FX(EXPR);
END$;
GLOBAL ROUTINE LOKDEFPT(EXPRNODE)=
BEGIN
EXTERNAL LOOP,RDCTMP,SKERR;
!LOOK AT ALL LEAVES. EXAMINE THE DEFINITION POINT FOR AN ASSIGNMENT
!OF THAT VARIABLE TO A CONSTANT. SUBSTITUTE THAT CONSTANT FOR THE
!VARIABLE. @ROCESSING IS DONE IN MOORE FLOOD ORDER. THIS HOPEFULLY
!INSURES THAT ALL PROPAGATIONS WHICH CAUSE OTHER PROPAGATIONS ARE CAUGHT
REGISTER PEXPRNODE EXPR;
LOCAL BASE PA;
LOCAL WHATSUP;
EXPR_.EXPRNODE;
!INITIALIZE THE LOCAL THAT WILL TELL US IF PROPAGATION
!DID ACTUALLY DID OCCUR.
!FOR EACH OPERCLASS THE ARGS ARE EXAMINED.
!CONS1DEF AND CONS2DEF RETURN A 1 IF A PROPAGATION
!OCCURRED AND A 0 OTHERWISE. IN ALL CASES WE WAIT TO
!FOLD UNTIL BOTH ARGS HAVE BEEN EXAMINED. THIS IS DONE
!FOR TWO REASONS:
! 1. THE NODE MIGHT CHANGE FORM IN THE MIDDLE
! 2.IT SHOULD BE FASTER IF ONLY ONE PROPAGATES
WHATSUP_0;
!GET OUT IF ITS NOT AN EXPRESSION
IF .EXPR[OPRCLS] EQL DATAOPR THEN RETURN(.EXPR);
!HANDLE THE CASE WHERE THEY ARE ALEEADY BOTH CONSTANTS
!AND FOR SOME REASON HAVE NOT BEEN *LOCALLY* FOLDED
%2374% IF .EXPR[VALTYPE] NEQ CHARACTER
%2374% THEN IF .EXPR[A1VALFLG] THEN
BEGIN
PA_.EXPR[ARG1PTR];
IF .PA[OPR1] EQL CONSTFL THEN
IF .EXPR[A2VALFLG] THEN
BEGIN
PA_.EXPR[ARG2PTR];
IF .PA[OPR1] EQL CONSTFL THEN
BEGIN
%2374% DEFKEEPER = .LENTRY;
EXPR_FOLDER(.EXPR);
RETURN(.EXPR);
END;
END;
END;
CASE .EXPR[OPRCLS] OF SET
!BOOLEAN
BEGIN
IF NOT .EXPR[A1VALFLG] THEN
BEGIN
EXPR[ARG1PTR]_LOKDEFPT(.EXPR[ARG1PTR]);
END;
IF .EXPR[A1VALFLG] THEN
WHATSUP_CONS1DEF(.EXPR);
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
EXPR[ARG2PTR]_LOKDEFPT(.EXPR[ARG2PTR]);
END;
IF .EXPR[A2VALFLG] THEN
WHATSUP_.WHATSUP+CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
END;
!DATAOPR
SKERR();
!RELATIONAL
BEGIN
IF NOT .EXPR[A1VALFLG] THEN
BEGIN
EXPR[ARG1PTR]_LOKDEFPT(.EXPR[ARG1PTR]);
END;
IF .EXPR[A1VALFLG] THEN
WHATSUP_CONS1DEF(.EXPR);
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
EXPR[ARG2PTR]_LOKDEFPT(.EXPR[ARG2PTR]);
END;
IF .EXPR[A2VALFLG] THEN
WHATSUP_.WHATSUP+CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
END;
!FNCALL
BEGIN
EXTERNAL SETPVAL;
!THIS IS VERY SAD. IF A LIBRARY FUNCTION, IT
!COULD BE MOVED TO PROGRAM ENTRY, BUT ARGLISTS
!HAVE NO RROM FOR DEFINITION POINT INFO.
!WE WILL TRY FOR A CONSTANT ARGUMENT
!THIS WILL APPLY ONLY (MOST PROBABLY) TO BENCHMARKS
LOCAL BASE TMP1;
LOCAL ARGUMENTLIST AG;
AG_.EXPR[ARG2PTR];
!FOR A LIBRARY FUNCTION OF ONE ARGUMENT
IF .EXPR[OPERSP] EQL LIBARY AND .LOOP NEQ 0 THEN
BEGIN
IF .AG[ARGCOUNT] EQL 1 THEN
BEGIN
REGISTER BASE TMP;
TMP_.AG[1,ARGNPTR];
IF .TMP[OPR1] EQL CONSTFL THEN
BEGIN
EXTERNAL GETOPTEMP;
OWN BASE FRONT:STMT;
!SET VAL FLG ON OLD PARENT
SETPVAL(.EXPR);
FRONT_.SORCPTR<LEFT>; !FIRST STATEMENT OF PROG
!THIS COULD BE AN ENTRY FOR A SUBPROGRAM
STMT_.FRONT[SRCLINK];
WHILE .STMT[SRCID] EQL ENTRID DO
BEGIN
FRONT_.STMT; !DEFINE
!FRONT AS THE ENTRY STATEMENT
STMT_.STMT[SRCLINK];
END;
NAME<LEFT>_ASGNSIZ + SRCSIZ;
STMT_CORMAN();
STMT[OPRCLS]_STATEMENT;
STMT[OPERSP]_ASGNID;
STMT[A1VALFLG]_1;
!USE .O INSTEAD OF .R (TO GET CORRECT
! TYPE INFORMATION)
TMP_STMT[RHEXP]_.EXPR;
STMT[LHEXP]_GETOPTEMP(.TMP[VALTYPE]);
!SET THE NEW PARENT OF THE FUNCTION CALL
EXPR[PARENT]_.STMT;
STMT[SRCLINK]_.FRONT[SRCLINK];
FRONT[SRCLINK]_.STMT;
RETURN(.STMT[LHEXP]);
END;
END;
END;
INCR I FROM 1 TO .AG[ARGCOUNT] DO
BEGIN
TMP1_.AG[.I,ARGNPTR]; !LOOK AT ARG
IF .TMP1[OPRCLS] NEQ DATAOPR
%2374% THEN
%2374% BEGIN ! Not a DATAOPR
%2374%
%2374% AG[.I,ARGNPTR] = TMP1 = LOKDEFPT(.TMP1);
%2374% IF .TMP1[OPRCLS] EQL DATAOPR
%2374% THEN AG[.I,AVALFLG] = 1;
%2374%
%2374% END; ! Not a DATAOPR
END;
RETURN(.EXPR);
END;
!ARITHMETIC
BEGIN
IF NOT .EXPR[A1VALFLG] THEN
BEGIN
EXPR[ARG1PTR]_LOKDEFPT(.EXPR[ARG1PTR]);
END;
IF .EXPR[A1VALFLG] THEN
WHATSUP_CONS1DEF(.EXPR);
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
EXPR[ARG2PTR]_LOKDEFPT(.EXPR[ARG2PTR]);
END;
IF .EXPR[A2VALFLG] THEN
WHATSUP_.WHATSUP+CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
IF .EXPR[OPR1] EQL MULOPF THEN
EXPR_REDUCE(.EXPR);
END;
!TYPECNV
BEGIN
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
EXPR[ARG2PTR]_LOKDEFPT(.EXPR[ARG2PTR]);
END;
IF .EXPR[A2VALFLG] THEN
WHATSUP_CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
END;
!ARRAYREF
BEGIN
%2031% IF NOT .EXPR[A2VALFLG]
%2374% THEN IF .EXPR[ARG2PTR] NEQ 0 ! Be paranoid
%2031% THEN EXPR[ARG2PTR] = LOKDEFPT(.EXPR[ARG2PTR]);
%2031%
%2031% ! A2VALFLG may be set by LOKDEFPT, so check again
%2031%
%2031% IF .EXPR[A2VALFLG]
%2031% THEN IF .EXPR[ARG2PTR] NEQ 0
%2031% THEN WHATSUP = CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
END;
!CMNSUB
RETURN(.EXPR);
!NEGNOT
BEGIN
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
EXPR[ARG2PTR]_LOKDEFPT(.EXPR[ARG2PTR]);
END;
IF .EXPR[A2VALFLG] THEN
WHATSUP_CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
END;
!SPECOP
BEGIN
EXTERNAL INDVARR;
IF NOT .EXPR[A1VALFLG] THEN
BEGIN
EXPR[ARG1PTR]_LOKDEFPT(.EXPR[ARG1PTR]);
END;
IF .EXPR[A1VALFLG] THEN
WHATSUP_CONS1DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
!POTEATIALLY REDUCE IT
IF (.EXPR[OPR1] EQL P2MULOPF) OR (.EXPR[OPR1] EQL P2PL1OPF) THEN
IF (.EXPR[VALTP1] EQL INTEG1) AND (.EXPR[ARG1PTR] EQL .INDVAR) THEN
IF EXTSIGN(.EXPR[ARG2PTR]) GTR 0 THEN
EXPR_REDUCE(.EXPR);
END;
!FIELDREF
RETURN(.EXPR);
!STORECLS
RETURN(.EXPR);
!RECONTENTS
RETURN(.EXPR);
!LABOP
!ILLEGAL
RETURN(.EXPR);
!STATEMENT
!ILLEGAL
RETURN(.EXPR);
!IOLSCLS
RETURN(.EXPR);
!INLINFN
BEGIN
IF NOT .EXPR[A1VALFLG] THEN
BEGIN
EXPR[ARG1PTR]_LOKDEFPT(.EXPR[ARG1PTR]);
END;
IF .EXPR[A1VALFLG] THEN
WHATSUP_CONS1DEF(.EXPR);
IF .EXPR[ARG2PTR] NEQ 0 THEN
IF NOT .EXPR[A2VALFLG] THEN
BEGIN
EXPR[ARG2PTR]_LOKDEFPT(.EXPR[ARG2PTR]);
END;
IF .EXPR[A2VALFLG] THEN
WHATSUP_.WHATSUP+CONS2DEF(.EXPR);
IF .WHATSUP GTR 0 THEN EXPR_FOLDER(.EXPR);
END;
%2374% !SUBSTRING
%2374% BEGIN
%2374% ! Don't bother with WHATSUP and FOLDER for now. Note
%2374% ! that if we decide to do this, DEFKEEPER will have to
%2374% ! be set up correctly for substrings. However, we
%2374% ! will still create .Dnnnn substring descriptors, so
%2374% ! this is currently a win.
%2374%
%2374% IF NOT .EXPR[A1VALFLG]
%2374% THEN EXPR[ARG1PTR] = LOKDEFPT(.EXPR[ARG1PTR]);
%2374%
%2374% IF .EXPR[A1VALFLG] ! Note that it may be set by LOKDEFPT
%2374% THEN CONS1DEF(.EXPR);
%2374%
%2374% IF NOT .EXPR[A2VALFLG]
%2374% THEN EXPR[ARG2PTR] = LOKDEFPT(.EXPR[ARG2PTR]);
%2374%
%2374% IF .EXPR[A2VALFLG] ! Note that it may be set by LOKDEFPT
%2374% THEN CONS2DEF(.EXPR);
%2374%
%2374% EXPR[ARG4PTR] = LOKDEFPT(.EXPR[ARG4PTR]);
%2374%
%2374% RETURN .EXPR; ! All done
%2374% END;
%2374% !CONCATENATION
%2374% BEGIN
%2374% LOCAL BASE TMP;
%2374% LOCAL ARGUMENTLIST AG;
%2374% AG = .EXPR[ARG2PTR];
%2374%
%2374% INCR I FROM 2 TO .AG[ARGCOUNT] ! Skip first argument
%2374% DO
%2374% BEGIN ! For each argument
%2374%
%2374% AG[.I,ARGNPTR] = TMP = LOKDEFPT(.AG[.I,ARGNPTR]);
%2374% IF .TMP[OPRCLS] EQL DATAOPR
%2374% THEN AG[.I,AVALFLG] = 1;
%2374%
%2374% END; ! For each argument
%2374%
%2374% RETURN .EXPR; ! All done
%2374% END;
TES;
!NOW ONCE MORE LOOK AT WHAT HAS BECOME OF THE EXPRESSION
!AND SET THE VAL FLAGS IF APPROPRIATE. FULL CASE IS NEEDED
!CAUSE PHASE 1 SEEMS TO HAVE THE NTY HABIT OF LEAVING
!JUNK IN ARG1 OF NODES THAT SHOULD HAVE ARG1 ZERO.
CASE .EXPR[OPRCLS] OF SET
!BOOLEAN
VALBFX(EXPR);
!DATAOPR
BEGIN END;
!RELATIONAL
VALBFX(EXPR);
!FNCALL
BEGIN END; ! Never here
!ARITHMETIC
VALBFX(EXPR);
!TYPECNV
VAL1FX(EXPR);
!ARRAYREF
VAL2FX(EXPR);
!CMNSUB
BEGIN END;
!NEGNOT
VAL2FX(EXPR);
!SPECOP
VAL1FX(EXPR);
!FIELDREF
BEGIN END;
!STORECLS
BEGIN END;
!REGCONTENTS
BEGIN END;
!LABOP
BEGIN END;
!STATEMENT
BEGIN END;
!IOLSCLS
BEGIN END;
!INLINFN
BEGIN
VAL1FX(EXPR);
IF .EXPR[ARG2PTR] NEQ 0 THEN
VAL2FX(EXPR);
END;
%2374% !SUBSTRING
%2374% BEGIN END; ! Never here
%2374% !CONCATENATION
%2374% BEGIN END; ! Never here
TES;
RETURN .EXPR
END;
SWITCHES NOSPEC;
!***************************************************
!DELETE A LOGICAL IF FROM THE FLOW OF CONTROL
MACRO WIPEOUT(NUMB)=
BEGIN
HEAD[SRCID]_CONTID;
IF .NUMB LSS 0 THEN
BEGIN
PB_.HEAD[SRCLINK];
HEAD[SRCLINK]_.HEAD[LIFSTATE];
PA_.HEAD[LIFSTATE];
PA[SRCLINK]_.PB;
END;
END$;
ROUTINE ASGNPROP(HEAD)=
BEGIN
!PROPAGATE STUFF FOR AN ASIGNMENT STATEMENT
MAP PHAZ2 HEAD;
LOCAL PHAZ2 PA;
!THIS REGISTER IS TO PREVENT BLISS GENERATION OF
!EXCESSIVE LOCALS
REGISTER TMP;
!LOOK AT THE LEFT HAND SIDE FIRST.
!IF IT IS NOT A LEAF TRY TO PROPAGATE WITH IN THE
!EXPRESSION.
IF NOT .HEAD[A1VALFLG] THEN
BEGIN
PA_.HEAD[LHEXP];
!AN ARRAY REF IS ALL THAT IS LEGEL
!SO WE WILL LOOK ONLY AT ARG2.
!IF IT IS NOT A LEAF PROPAGATE AND REDUCE
IF NOT .PA[A2VALFLG] THEN
BEGIN
TMP_LOKDEFPT(.PA[ARG2PTR]);
PA[ARG2PTR]_.TMP;
END;
!IT HAS NOT BECOME A LEAF, THEREFOR IT
!HAS NOT PROPAGATED, SO TRY A REDUCTION.
IF NOT .PA[A2VALFLG] THEN
BEGIN
TMP_REDUCE(.PA[ARG2PTR]);
PA[ARG2PTR]_.TMP;
END;
END;
!DONE WITH LEFT HAND SIDE. NOW LOOK AT RIGHT HAND SIDE.
!IF IT IS NOT A LEAF TRY PROPAGATION.
IF NOT .HEAD[A2VALFLG] THEN
BEGIN
TMP_LOKDEFPT(.HEAD[RHEXP]);
HEAD[RHEXP]_.TMP;
!IT MAY NOW HAVE BECOME A LEAF. MAKE SURE
!THAT THE NEG ANF NOT FLGS ARE PICKED UP.
IF .HEAD[A2VALFLG] THEN
BEGIN
PA_.HEAD[RHEXP];
IF .PA[OPR1] EQL CONSTFL THEN
ASGNNN(.HEAD);
END;
END ELSE
!IT WAS A LEAF TO BEGIN WITH. PROPAGATE.
STMTPROP(.HEAD);
END;
GLOBAL ROUTINE PROPAGATE=
!THIS IS THE CONTROLLING ROUTINE FOR CONSTANT PROPAGATION
!AND REDUCTION IN STRENGTH
BEGIN
EXTERNAL DFCLEANUP;
EXTERNAL IOGPNR; !WALK I/O LISTS <IOPT>
EXTERNAL BASE LENTRY;
EXTERNAL CHOSEN,GLOBREG,CSTMNT,FOLDAIF,ISN,LOOP,RDUCINIT;
LABEL SELCT;
LOCAL HEAD,PA,PB,PC;
MAP PHAZ2 HEAD:TOP:PC:PA:PB;
MAP BASE CSTMNT;
!THIS REGISTER TO PREVENT BLISS FROM GENERATING EXCESSIVE TEMPS
REGISTER TMP;
!GO THROUGH BUSY LIST TRYING TO PROPAGATE CONSTANTS
!INITIALIZE SPECIAL REDUCTION VARIABLES
RDUCINIT();
HEAD_.TOP;
IF .HEAD[SRCID] EQL DOID THEN
HEAD_.HEAD[BUSY];
DO
BEGIN
CSTMNT_.HEAD;
ISN_.CSTMNT[SRCISN];
SELCT:
SELECT .HEAD[SRCID] OF NSET
ASGNID:
BEGIN
ASGNPROP(.HEAD);
END;
IFLID: BEGIN
!LOOK AT THE EXPRESION. IF ITS A LEAF CALL THE
!STATEMENT PROPAGATION ROUTINE ELSE
!DO THE REGULAR EXPRESSION PROPRAGATION.
PA_.HEAD[LIFEXPR];
IF .PA[OPRCLS] EQL DATAOPR THEN
STMTPROP(.HEAD)
ELSE
BEGIN
TMP_LOKDEFPT(.HEAD[LIFEXPR]);
HEAD[LIFEXPR]_.TMP;
END;
!IF THE EXPRESSION HAS BECOME A CONSTANT
!THEN GET RID OF THE STATEMENT
PA_.HEAD[LIFEXPR];
IF .PA[OPR1] EQL CONSTFL THEN
BEGIN
!MAKE SURE THAT ANY NEG NOT FLAGS ON THE
!STATEMENT HAVE BEEN INCLUDED
IFNN(.HEAD);
![1074] Must reset PA since IFNN may have created a new node with a new type
%[1074]% PA_.HEAD[LIFEXPR];
IF .PA[VALTP1] EQL INTEG1 THEN
WIPEOUT(PA[CONST2])
ELSE
WIPEOUT(PA[CONST1]);
END;
END;
IFAID: BEGIN
!EXAMINE THE EXPRESSION.
PA_.HEAD[AIFEXPR];
IF .PA[OPRCLS] EQL DATAOPR THEN
STMTPROP(.HEAD)
ELSE
BEGIN
!ITS NOT A LEAF, TRY PROPAGATION.
TMP_LOKDEFPT(.HEAD[AIFEXPR]);
HEAD[AIFEXPR]_.TMP;
!LOOK AGAIN TO SEE WHAT THE EXPRESSION HAS BECOMEME
END;
!IF IT REDUCED TO A CONSTANT, FOLD THE
!STATEMENT, CUZ THE CONSTANT WILL NOT BE ALLOCATED
PA_.HEAD[AIFEXPR];
IF .PA[OPR1] EQL CONSTFL THEN
BEGIN
!FIRST MAKE SURE THAT ANY NEG/NOT FLAGS ON THE STATEMENT
!HAVE BEEN PICKED UP.
IFNN(.HEAD);
CSTMNT_.HEAD;
FOLDAIF();
END;
END;
DOID:
BEGIN
!THIS IS AN INNER DO LOOP. LOOK AT THE
!CONTROL EXPRESSION
DOPROPAGATE(.HEAD);
PA_.HEAD[DOLPCTL];
!IT MAY ALREADY BE A CONSTANT IN WHICH
!CASE WE WANT TO QUIT WHILE AHEAD
IF .PA[OPR1] EQL CONSTFL THEN LEAVE SELCT;
HEAD[DOLPCTL]_LOKDEFPT(.HEAD[DOLPCTL]);
PA_.HEAD[DOLPCTL];
IF NOT .HEAD[FLCWD] AND .PA[OPR1] EQL CONSTFL THEN
STMTPROP(.HEAD);
END;
CALLID:
BEGIN
!ZERO OPTIMIZERS INFO IN EXPRESSIONS ON LIST.
!ALSO PROPAGATE CONSTANTS TO EXPRESSIONS ONLY.
!PROPAGATING CONSTANTS TO VARIABLES IS PRECLUDED
!BY THE FACT THAT THERE ARE NO DEFINITION POINTS FOR
!SINGLE VARIABLES ON ARGUMENT LISTS.
IF .HEAD[CALLIST] NEQ 0 THEN
BEGIN
LOCAL ARGUMENTLIST AG;
LOCAL BASE T1;
AG_.HEAD[CALLIST];
INCR I FROM 1 TO .AG[ARGCOUNT] DO
BEGIN
T1_.AG[.I,ARGNPTR];
IF .T1[OPRCLS] NEQ DATAOPR THEN
AG[.I,ARGNPTR]_LOKDEFPT(.T1);
END;
END;
END;
READID: IOGPNR(.HEAD);
WRITID: IOGPNR(.HEAD);
DECOID: IOGPNR(.HEAD);
ENCOID: IOGPNR(.HEAD);
REREDID: IOGPNR(.HEAD);
TESN;
HEAD_.HEAD[BUSY];
END UNTIL .HEAD EQL 0;
!NOW GO THROUGH ALL THE STATEMENTS CREATED BY THE OPTIMIZER
!THESE ARE NOT IN THE GRAPH
HEAD_.TOP[SRCLINK];
WHILE .HEAD NEQ .BOTTOM DO
BEGIN
!SKIP OVER STATEEMENTS IN INNER DO LOOPS
IF .HEAD[SRCID] EQL DOID THEN
BEGIN
HEAD_.HEAD[DOLBL];
!INDIRECT THROUGH THE SYMBOL TABEL TO GET ENDING STATEMENT
HEAD_.HEAD[SNHDR];
END ELSE
IF .HEAD[SRCOPT] EQL 0 THEN
IF .HEAD[SRCID] EQL ASGNID THEN
ASGNPROP(.HEAD);
HEAD_.HEAD[SRCLINK];
IF .HEAD EQL 0 THEN RETURN;
END;
!CLEAR DEFPT BITS FROM SYMBOL TABLE EXCEPT FOR .O
DFCLEANUP();
END;
ROUTINE DEFSUB(NITIONPT, !DEFINITION POINT
OLDARG)= !OLD ARGUMENT FOR RETURNING
BEGIN
!CHECK TO SEE IF THE DEFINITION POINT PASSED IS AN ASSIGNMENT OF
!OLDARG TO A CONSTANT. IF SO, RETURN CONSTANT ELSE
!RETURN OLDARG.
EXTERNAL DNEGCNST;
MAP BASE NITIONPT;
LOCAL INQUEST; MAP BASE INQUEST;
IF .NITIONPT[SRCID] EQL ASGNID THEN
IF .NITIONPT[LHEXP] EQL .OLDARG THEN
BEGIN
INQUEST_.NITIONPT[RHEXP];
IF .INQUEST[OPR1] EQL CONSTFL THEN
BEGIN
%2374% INQUEST = VALCNV(.NITIONPT[LHEXP],.INQUEST);
IF .NITIONPT[A2NEGFLG] THEN
BEGIN
INQUEST_NEGCNST(INQUEST);
NITIONPT[A2NEGFLG]_0;
END;
IF .NITIONPT[A2NOTFLG] THEN
BEGIN
INQUEST_NOTCNST(INQUEST);
NITIONPT[A2NOTFLG]_0;
END;
RETURN(.INQUEST);
END;
END;
.OLDARG
END;
ROUTINE IFNN(STMT)=
BEGIN
!STMT POINTS TO AN ARITHMETIC OR LOGICAL IF.
!LIFEXPR OR AIFEXPR HAVE BECOME CONSTANTS.
!CHECK THE NEG/NOT FLAGS AND FOLD THEM INTO THE CONSTANT.
MAP BASE STMT;
LOCAL BASE T1;
T1_.STMT[LIFEXPR];
IF .STMT[A1NEGFLG] THEN
BEGIN
STMT[LIFEXPR]_NEGCNST(T1);
STMT[A1NEGFLG]_0;
END;
IF .STMT[A1NOTFLG] THEN
BEGIN
STMT[LIFEXPR]_NOTCNST(T1);
STMT[A1NOTFLG]_0;
END;
END;
ROUTINE ASGNNN(STMT)=
BEGIN
!STMT IS AN ASIGNMENT STATEMENT.
!THE RIGHT HAND SIDE IS A CONSTANT. CHECK THE NEG/NOT FLAGS
!AND FOLD THEM INTO THE CONSTANT.
MAP BASE STMT;
LOCAL BASE T1;
T1_.STMT[RHEXP];
IF .STMT[A2NEGFLG] THEN
BEGIN
STMT[RHEXP]_NEGCNST(T1);
STMT[A2NEGFLG]_0;
END;
IF .STMT[A2NOTFLG] THEN
BEGIN
STMT[RHEXP]_NOTCNST(T1);
STMT[A2NOTFLG]_0;
END;
END;
ROUTINE STMTPROP(STMT)=
BEGIN
!HANDLES A SINGLE VARIABLE AS A STATEMENT EXPRESSION AND TRIES TO
!PROPAGATE IT IF POSSIBLE
EXTERNAL CSTMNT,FOLDAIF,DNEGCNST;
MAP PHAZ2 STMT;
SELECT .STMT[SRCID] OF NSET
ASGNID: BEGIN
LOCAL BASE PA:PB;
PA_.STMT[RHEXP];
IF .PA[OPR1] EQL VARFL THEN
BEGIN
IF .STMT[SRCOPT] EQL 0 THEN RETURN;
PB_.STMT[OPDEF];
IF .PB EQL 0 THEN RETURN;
STMT[RHEXP]_DEFSUB(.PB,.STMT[RHEXP]);
!CHECK FOR NEG AND NOT FLAGS IF IT PROPAGATED
PA_.STMT[RHEXP];
IF .PA[OPR1] NEQ CONSTFL THEN RETURN;
!HERE WE KNOW ITS A CONSTANT
!CATCH THOSE NASTY LITTLE NEG/NOT FLAGS.
ASGNNN(.STMT);
END;
!RESET VAL FLGS
PA_.STMT[RHEXP];
IF .PA[OPRCLS] EQL DATAOPR THEN STMT[A2VALFLG]_1;
END;
DOID: BEGIN
!NUMBER OF TIMES THROUGH A LOOP HAS BECOME A CONSTANT
!BUT THAT MAY NOT BE MEANINGFUL. ON INNER DO LOOPS
!THE FLAG NOFLCWDREG (SET BY P2S) SAYS THAT THIS
!LOOP SHOULD NOT BE AN AOBJN LOOP. THE FLAG WILL BE SET
!1. THE INDEX VARIABLE WAS AT A TOP LEVEL ARITHMETIC IF
!2. THE INDEX VARIABLE WAS AT A TOP LEVEL LOGICAL IF
!3. THE INDEX WAS AN ITEM ON AN I/O (BETTER B O) LIST
!4. THE INDEX WAS AT A TOP LEVEL COMPUTED GO TO
!5. THE INDEX WAS ON THE LHS OF AN ASSIGNMENT
%2223% LOCAL BASE OLDCTL:INITIAL, CTLVAL;
%2223%
%2223% STMT[MAYBEZTRIP] = 0; ! Assume not ztrip, then set if ztrip
%2223% OLDCTL = .STMT[DOLPCTL]; ! .OLDCTL points to an INTCONST node
%2223%
%2223% ! Set CTLVAL to the control expression value, and also
%2223% ! absorb CTLNEG and leave it cleared.
%2223%
%2223% IF .STMT[CTLNEG] ! Check CTLNEG
%2223% THEN
%2223% BEGIN
%2223% STMT[CTLNEG] = 0; ! Clear CTLNEG
%2223% CTLVAL = -.OLDCTL[CONST2]; ! Use negated value
%2223% END
%2223% ELSE CTLVAL = .OLDCTL[CONST2];
%2223%
%2223% ! Now .CTLVAL is the negative iteration count
%2223% ! See if the loop is zero-trip (one for F66)
%2223%
%2223% IF .CTLVAL GEQ 0 ! Make it zero-trip (one-trip for F66)
%2223% THEN
%2223% BEGIN
%2223% IF F77 ! Zero-trip loops allowed?
%2223% THEN
%2223% BEGIN
%2223% CTLVAL = 0; ! Zero-trip
%2223% STMT[MAYBEZTRIP] = 1; ! Set flag
%2223% END
%2223% ELSE CTLVAL = -1; ! One-trip
%2223% END;
%2223%
%2223% ! Now see if we can convert this loop to an AOBJN loop
%2223%
%2223% IF .STMT[INNERDOFLG] AND NOT .STMT[NOFLCWDREG]
%2223% THEN IF .CTLVAL GEQ -#377777 AND .STMT[SSIZONE]
%2223% THEN
%2223% BEGIN
%2223% ! So far so good, now check the initial value
%2223%
%2223% INITIAL = .STMT[DOM1]; ! Initial value
%2223%
%2223% IF .INITIAL[OPERATOR] EQL INTCONST
%2223% THEN IF .INITIAL[CONST2] GEQ 0 AND .INITIAL[CONST2] LEQ #377777
%2223% THEN
%2223% BEGIN
%2223% ! The initial value is also OK, convert to AOBJN
%2223%
%2223% STMT[SSIZONE] = 0; ! Clear SSIZONE flag
%2223% STMT[FLCWD] = 1; ! Set AOBJN flag
%2223% CTLVAL = .CTLVAL^18+.INITIAL[CONST2]; ! AOBJN word
%2223% END;
%2223% END;
%2223%
%2223% ! See if the control value has changed, and if so create a
%2223% ! new constant for it.
%2223%
%2223% IF .OLDCTL[CONST2] NEQ .CTLVAL
%2223% THEN STMT[DOLPCTL] = MAKECNST(INTEGER,0,.CTLVAL);
%2223%
%2223% END; ! Of SELECT case DOID
IFLID: BEGIN
LOCAL BASE PA:PB;
EXTERNAL FOLDLIF,CSTMNT;
PA_.STMT[OPDEF];
IF .PA EQL 0 THEN RETURN;
STMT[LIFEXPR]_DEFSUB(.PA,.STMT[LIFEXPR]);
PB_.STMT[LIFEXPR];
IF .PB[OPR1] NEQ CONSTFL THEN RETURN;
!FIRST CHECK FOR NOT FLG AND NEG FLG
IFNN(.STMT);
PB_.STMT[LIFEXPR];
PA_.STMT[LIFSTATE]; !SAVE FOR LATER
CSTMNT_.STMT;
FOLDLIF();
!THE OPTIMIZER WILL TRY TO BE CLEVEL
!LIFSTATE WILL BE EXAMINED. IF IT IS AN UNCONDITIONAL BRANCH
!WE WILL DELETE ALL DEAD CODE UP TO THE NEXT LABELED
!STATEMENT.
!A COMPUTED GO TO IS NOT CONSIDIERED AN UNCONDITIONAL
!BRANCH BECAUSE IT MAY GO TO THE NEXT STATEMENT IF THE
!VALUE OF THE VARIABLE IS OUT OF RANGE
!REMEMBER PA IS A POINTER TO THE STATEMENT IN QUESTION
IF .PA[SRCID] EQL GOTOID OR .PA[SRCID] EQL AGOID THEN
BEGIN
PB_.PA[SRCLINK];
WHILE .PB[SRCLBL] EQL 0 DO
BEGIN
PB_.PB[SRCLINK];
END;
PA[SRCLINK]_.PB;
END;
END;
IFAID: BEGIN
LOCAL BASE PA:PB;
PA_.STMT[OPDEF];
IF .PA EQL 0 THEN RETURN;
STMT[AIFEXPR]_DEFSUB(.PA,.STMT[AIFEXPR]);
PB_.STMT[AIFEXPR];
IF .PB[OPR1] NEQ CONSTFL THEN RETURN
!FIRST CHECK FOR NOT FLG AND NEG FLG
IFNN(.STMT);
CSTMNT_.STMT;
FOLDAIF();
END;
TESN;
END;
MAP PEXPRNODE INDVAR:LENTRY:LEND;
FORWARD PROPCASE;
ROUTINE BUNCHPROP(STMT)=
BEGIN
!STARTING AT STATEMENT STMT LEAFSUBSTITUTE
!ITEMS IN THE VECTORS (ITMCT SET UP
!PRIOR TO CALL) THEN USE THE PROPAGATION ROUTINES
!TO FOLD THE PROPAGTED CONSTANTS
EXTERNAL CSTMNT,ISN,SPECCASE,LOWLIM;
EXTERNAL FOLDLIF,FOLDAIF,LOKDEFPT;
MAP BASE STMT:CSTMNT;
SPECCASE_0;
LOWLIM_1;
WHILE .STMT NEQ 0 DO
BEGIN
CSTMNT_.STMT;
ISN_.CSTMNT[SRCISN];
PROPCASE(.STMT);
STMT_.STMT[SRCLINK];
END;
END;
ROUTINE PROPCASE(STMT)=
BEGIN
!***************************************************************
! Propagation and folding of .Onnnn variables created by the
! optimizer.
!***************************************************************
%1742% ! Rewritten by TFV on 14-Apr-83
MAP BASE STMT;
REGISTER BASE T;
CASE .STMT[SRCID] OF SET
BEGIN ! ASSIGNMENT
IF NOT .STMT[A1VALFLG]
THEN
BEGIN
LEAFSUBSTITUTE(.STMT[LHEXP]);
STMT[LHEXP] = LOKDEFPT(.STMT[LHEXP]);
END;
LEAFSUBSTITUTE(.STMT[RHEXP]);
STMT[RHEXP] = LOKDEFPT(.STMT[RHEXP]);
T = .STMT[RHEXP];
IF .T[OPR1] EQL CONSTFL
THEN ASGNNN(.STMT); ! CATCH NEG/NOT NASTIES
END; ! ASSIGNMENT
BEGIN END; ! ASSIGN
BEGIN ! CALL
LOCAL BASE TMP;
LOCAL ARGUMENTLIST AG;
IF (AG = .STMT[CALLIST]) NEQ 0
THEN
BEGIN
DECR I FROM .AG[ARGCOUNT] TO 1 DO
BEGIN
TMP = .AG[.I,ARGNPTR];
IF .TMP[OPRCLS] NEQ LABOP
THEN IF .TMP[OPRCLS] EQL DATAOPR
THEN AG[.I,ARGNPTR] = SWAPEM(.TMP)
ELSE LEAFSUBSTITUTE(.TMP);
END;
END;
END; ! CALL
BEGIN END; ! CONTINUE
DOVARSUBSTITUTE(.STMT); ! DO
BEGIN END; ! ENTRY
BEGIN END; ! COMMONNSUB
BEGIN END; ! GOTO
BEGIN END; ! ASSIGNED GOTO
BEGIN END; ! COMPUTED GOTO
BEGIN ! ARITHMETIC IF
LEAFSUBSTITUTE(.STMT[AIFEXPR]);
STMT[AIFEXPR] = LOKDEFPT(.STMT[AIFEXPR]);
T = .STMT[AIFEXPR];
IF .T[OPR1] EQL CONSTFL
THEN
BEGIN
IFNN(.STMT);
FOLDAIF();
END;
END; ! ARITHMETIC IF
BEGIN ! LOGICAL IF
LEAFSUBSTITUTE(.STMT[LIFEXPR]);
CSTMNT = .STMT[LIFSTATE];
PROPCASE(.CSTMNT);
CSTMNT = .STMT;
STMT[LIFEXPR] = LOKDEFPT(.STMT[LIFEXPR]);
T = .STMT[LIFEXPR];
IF .T[OPR1] EQL CONSTFL
THEN
BEGIN
IFNN(.STMT);
FOLDLIF();
END;
END; ! LOGICAL IF
IF .STMT[RETEXPR] NEQ 0 ! RETURN
THEN LEAFSUBSTITUTE(.STMT[RETEXPR]);
BEGIN END; ! STOP
%1742% MISCIO(.STMT); ! READ
%1742% MISCIO(.STMT); ! WRITE
%1742% MISCIO(.STMT); ! DECODE
%1742% MISCIO(.STMT); ! ENCODE
%1742% MISCIO(.STMT); ! REREAD
%1742% MISCIO(.STMT); ! FIND
%1742% MISCOCI(.STMT); ! CLOSE
BEGIN END; ! INPUT (not implemented)
BEGIN END; ! OUTPUT (not implemented)
%1742% MISCIO(.STMT); ! BACKSPACE
%1742% MISCIO(.STMT); ! BACKFILE
%1742% MISCIO(.STMT); ! REWIND
%1742% MISCIO(.STMT); ! SKIP FILE
%1742% MISCIO(.STMT); ! SKIP RECORD
%1742% MISCIO(.STMT); ! UNLOAD
BEGIN END; ! RELEASE (not implemented)
%1742% MISCIO(.STMT); ! ENDFILE
BEGIN END; ! END
BEGIN END; ! PAUSE
%1742% MISCOCI(.STMT); ! OPEN
BEGIN END; ! SFN
BEGIN END; ! FORMAT
BEGIN END; ! BLT
BEGIN END; ! REGMASK - change set of available registers -
! inserted by global register allocator
%2211% MISCOCI(.STMT); ! INQUIRE
TES;
END;
ROUTINE ELIGIBLE(LNODE,RNODE)=
BEGIN
!CHECK LNODE AND RNODE
!FOR THE FOLLOWING COMBINATIONS WE WISH TO
!"PROPAGATE":
! LNODE RNODE
! _____ _____
!
! .O NOT FROM .R ANY DATAOPR
! .I .O
!
%2374% ! The following combination is no longer allowed:
%2374% !
%2374% ! .S .O
%2374% !
%2374% ! This substitution is incorrect if the .O propagates to a
%2374% ! variable which is redefined within the body of a DO loop,
%2374% ! resulting in a different increment each time through the
%2374% ! loop. However, note that the following could probably be
%2374% ! allowed:
%2374% !
%2374% ! .I any CONSTANT
%2374% ! .S any CONSTANT
%2374% !
%2374% ! This isn't being done in this edit to avoid having to worry
%2374% ! about introducing new neg/not problems, etc. Maybe someday,
%2374% ! though.
%2374% !
MAP BASE LNODE:RNODE;
!QUIT QUICK IF WE ARE NOT EVEN DEALING WITH
!DATA ITEMS
IF .LNODE[OPRCLS] NEQ DATAOPR THEN RETURN;
IF .RNODE[OPRCLS] NEQ DATAOPR THEN RETURN;
!CHECK .O ON LEFT HAND SIDE
!CAN'T PROPAGATE .O IF IT CAME FROM A .R
IF .LNODE [IDDOTO] EQL SIXBIT ".O"
THEN
IF .LNODE [ORFIXFLG]
THEN RETURN 0
ELSE RETURN 1;
!CHECK .O ON RIGHT WITH OTHERS SPECIFICALLY ON LEFT
%2374% IF .RNODE[OPERSP] NEQ CONSTANT
%2374% THEN IF .RNODE[IDDOTO] EQL SIXBIT ".O"
%2374% THEN IF .LNODE[IDDOTO] EQL SIXBIT ".I"
%2374% THEN RETURN 1;
%2374% RETURN 0;
END; ! of ELIGIBLE
GLOBAL ROUTINE DOTOPROPAGATE=
BEGIN
!ROUTINE TO CAUSE .O VARIABLES TO PROPAGATE THROUGHOUT
!THE PROGRAM UNIT
EXTERNAL VERYFRST,GLOBREG,CHOSEN,PREV,ITMCT;
OWN GOTSUM,STMT,OLDSTMT,HEAD;
MAP BASE STMT:PREV;
!*!*!*!*!*!*!*!*!*!*START OF LOCAL ROUTINE!*!*!*!*!*!*!
ROUTINE RUBOUT(STSUB)=
BEGIN
!STSUB IS THE STATEMENT AT WHICH
!TO START THE SUBSTITUTION SHOULD WE
!HAVE TO
LABEL SETCHOSEN;
EXTERNAL SAVSPACE;
REGISTER BASE RHNOD:LHNOD;
RHNOD_.STMT[RHEXP];
LHNOD_.STMT[LHEXP];
!MAKE THE STATEMENT A CONTINUE
!IF RHNOD=LHNOD AND THERE ARE NO
!$%&#' NEG OR NOT FLAGS SET
IF .RHNOD EQL .LHNOD THEN
BEGIN
IF (.STMT[A1NGNTFLGS] EQL 0)
AND
(.STMT[A2NGNTFLGS] EQL 0)
THEN
STMT[SRCID]_CONTID;
END ELSE
!IS LEFT HAND .O AND
!RIGHT HAND CONSTANT
!ALSO CHECK THE %&$#" NEG/NOTS AGAIN
IF ELIGIBLE(.LHNOD,.RHNOD)
AND (.STMT[A1NGNTFLGS] EQL 0)
AND (.STMT[A2NGNTFLGS] EQL 0) THEN
BEGIN
!DO NOT ALLOCATE THE .O VARIABLE
!AND REMOVE THE ASSIGNMENT FROM THE
!LOOP
LHNOD[IDATTRIBUT(NOALLOC)]_1;
![661] IF THE STATEMENT IS LABELED, TRY TO MOVE THE LABEL TO THE
![661] NEXT STATEMENT; OTHERWISE MAKE IT A CONTINUE.
%[661]% IF .STMT[SRCLBL] NEQ 0 THEN
%[661]% BEGIN !TRY TO REMOVE THE LABEL
%[661]% LOCAL BASE NXTSTMT;
%[661]% NXTSTMT_.STMT[SRCLINK];
%[661]% IF .NXTSTMT[SRCLBL] NEQ 0 THEN !BOTH LABELED
%[661]% STMT[SRCID]_CONTID !NO LUCK, JUST MAKE CONTINUE NODE
%[661]% ELSE (NXTSTMT[SRCLBL]_.STMT[SRCLBL];
%[661]% STMT[SRCLBL]_0)
%[661]% END;
%[661]%
%[661]% IF .STMT[SRCLBL] EQL 0 THEN !RECLAIM SPACE AND RELINK
%[661]% BEGIN
%[661]% PREV[SRCLINK]_.STMT[SRCLINK];
%[661]%
%[661]% !GIVE BACK THE SPACE FOR THE ASSIGNMENT
%[661]% SAVSPACE(ASGNSIZ+SRCSIZ-1,.STMT);
%[661]% STMT_.PREV
%[661]% END;
!QUEUE THE INFO IN THE SUBSTITUTION
!VECTORS
GLOBREG[.HEAD]_.LHNOD;
SETCHOSEN:
BEGIN
INCR I FROM 1 TO .HEAD DO
BEGIN
IF .GLOBREG[.I] EQL
.RHNOD THEN
BEGIN
CHOSEN[.HEAD]_.CHOSEN[.I];
LEAVE SETCHOSEN
END
END;
CHOSEN[.HEAD]_.RHNOD
END;
!IF THE QUEUE IS FULL PROCESS IT
IF .HEAD EQL 15 THEN
BEGIN
GOTSUM_1;
ITMCT_15;
OLDSTMT_.STMT;
BUNCHPROP(.STSUB);
HEAD_1;
END ELSE
HEAD_.HEAD+1;
END; !LINKING AND QUING
END;
!*!*!*!*!*!*!*!*!*!END OF LOCAL ROUTINE!*!*!*!*!
!FIRST CHECK TO BE SURE THERE WERE ANY .O VARIABLES AT ALL
IF .VERYFRST EQL 0 THEN RETURN;
DOTOHFLG_1;
!SET UP ITERATION CONTROL
GOTSUM_1;
WHILE .GOTSUM DO
BEGIN
%[775]% OLDSTMT_0; ! Reset pointer for each pass
GOTSUM_0;
HEAD_1;
PREV_STMT_.SORCPTR<LEFT>;
!FOR ALL STATEMENTS
WHILE .STMT NEQ 0 DO
BEGIN
!IS IT AN ASSIGNMENT
IF .STMT[OPRS] EQL ASGNOS
THEN
BEGIN
RUBOUT(IF .OLDSTMT EQL 0
THEN .SORCPTR<LEFT>
ELSE .OLDSTMT
);
END
ELSE
%2374% BEGIN ! It's not an assignment
!CHECK FOR AN I/O AND WALK THE I/O LIST
%1447% IF .STMT[OPRS] GEQ READOS THEN
%1447% IF .STMT[OPRS] LEQ REREDOS THEN
%1447% IF .STMT[IOLIST] NEQ 0
%1447% THEN
BEGIN
LOCAL OPREV,OOLD,OSTMT;
!SAVE CONTROLLING POINTERS
OPREV_.PREV;
OSTMT_.STMT;
!NEED TO SAVE THIS CUZ WE CANNOT
!COPE WITH REMAINDERS THAT COULD
!POTENTIALLY START IN THE MIDDLE OF
!AN I/O LIST
OOLD_.OLDSTMT;
!SET UP POINTERS ON I/O LIST
PREV_.STMT[IOLIST];
STMT_.PREV[CLINK];
!EXAMINE I/O LIST
WHILE .STMT NEQ 0 DO
BEGIN
IF .STMT[OPRS] EQL ASGNOS THEN
RUBOUT(
IF .OOLD EQL 0 THEN
.SORCPTR<LEFT> ELSE
.OOLD);
PREV_.STMT;
STMT_.STMT[SRCLINK];
END;
!RESTORE OLD POINTERS
PREV_.OPREV;
STMT_.OSTMT;
OLDSTMT_.OOLD;
END;
%2374% END; ! It's not an assignment
PREV_.STMT;
STMT_.STMT[SRCLINK];
END; !WHILE ON STMT
!ARE THERE SOME LEFT IN THE QUEUE ALTHOUGH WE HAVE LOOKED
!AT THE WHOLE PROGRAM
IF .HEAD NEQ 1 THEN
BEGIN
!MAKE SURE WE GO AROUND AGAIN TO
!.OX=.OX IF NOTHING ELSE
GOTSUM_1;
ITMCT_.HEAD-1;
BUNCHPROP(IF .OLDSTMT EQL 0 THEN .SORCPTR<LEFT> ELSE .OLDSTMT);
END;
END; !WHILE ON GOTSUM
DOTOHFLG_0;
END; !DOTOPROPAGATE
END
ELUDOM