"VERSION 1.4" "This version written by CLR 2/85 based entirely on SAMs previous version. The differences are: a) Bit masks used instead of lists of names for efficiency. b) Attempt to flush dead SETs. There are two interesting structures: 1) Each temp atom's value is a uvector of fixes. The first element is its number (starting at 0) and increasing so each temp has a number. The rest of the elements are essentially constitute a string of 1 bit bytes big enough for the total number of temps. The bit being on indicates a temp that can't be merged with this one. 2) The lists of live variables associated with branches is also the same kind of bit string." > > "NAME-UV is a vector of temp names. It is used to get from a number back to the name of a temp. NOTE: temp values start at 0 so 1 always must be added to index into this vector." (UVSIZE) FIX> L-INS L-LEVEL FIX L-ASSIGN ]>>> B-LIVES UVECTOR B-FALL-DEADS UVECTOR B-JUMP-DEADS > > :FORM> .OUTCHAN> )> > ) (VCODE: ) (VC:VECTOR .VCODE) LOOP-LABELS:) > <==? <1 .X> `ENDIF>> ;"Note: ENDIFs go in twice!" >)> >> .CODE> )> > )> )> )> > .LEVEL> > .LOOP-LABELS> )> >> )> )> ;"This pass never seems to find anything it can merge." )> )> )> > > .LOOP-LABELS> )> > :FORM> .OUTCHAN> )> ,ANY-FLUSHED-INS> "ADD-LIST ORs a bit into a uvector. In the old world it addes an atom to a LIST." :UVECTOR>) (WD:FIX <+ 1>) (BIT:FIX )) >>> "ADD-LIST? same as ADD-LIST except returns #FALSE () if already there." "AUX" (NUM:FIX <1 :UVECTOR>) TEM:FIX (WD:FIX <+ 1>) (BIT:FIX )) > >> 0> >)>> "REM-LIST kill a bit in the uvector same way as ADD-LIST." :UVECTOR>) (WD:FIX <+ 1>) (BIT:FIX )) .BIT>>>> "REM-LIST? return false if not there, else remove it and return true" :UVECTOR>) TEM:FIX (WD:FIX <+ 1>) (BIT:FIX )) > > .BIT> 0> >)>> "IN-LIST? see if bit is on" "AUX" (NUM:FIX <1 :UVECTOR>) (WD:FIX <+ 1>) (BIT:FIX )) > 0> <>) (ELSE .L)>> L2:) ;"I know this isn't the most efficient way, but I'm too tired to figure it out now, and it doesn't get called much." ) (ELSE )>> .L1>> "VALUE" ATOM) .TEMP) ( <1 .TEMP>) (ELSE >)>> ) %<>) ( <2 .TEMP>) (ELSE >)>> ) ( ) (ELSE .INST)>> ;"REMOVE-DEADS also counts number of ins (and one extra per ENDIF)" ) INST OP (CODE-SIZE:FIX 1)) )> > > > `DEAD> >> T) (<==? .OP `ENDIF> > <>)>>) (ELSE > >>)>>> ) "VALUE" ATOM) > LIST> > > `DEAD-FALL> <==? .FOO `DEAD-JUMP>>> > ()> >) (ELSE )>>> ) (LOOP-LABELS: ())) ) LABEL:LABEL (DID-ENDIF <>)) > ] LABEL>> >)> ) ( >> > .DID-ENDIF>> > ] LABEL>>) ( > ) (<==? .OP `LOOP> ) (<==? .OP `ACTIVATION> ] LABEL>> ) ( <==? .OP `FCN>> > !.ALL-VARS)> >>) (<==? .OP `TEMP> > !.ALL-VARS)> >>) (<==? .OP `MAKTUP> !.ALL-VARS)> -3>>)>)> )> >> .LOOP-LABELS> ;"CONSTRUCT-TEMPS SETGs each temp to a uvector. THe first element ins this temp's number and the rest are essentially bit masks for the unmeargeabl lists" "AUX" (UVSIZE >) (UV-OF-NAMES ) (I:FIX 0)) )> > >> .ATM> >> .L>> .ALL-VARS> > ;"Since only bit masks stored">
%<>] BRANCH>> ;"END is required to be the location of the return label." ) )) > > <==? <1 .INST> `ACTIVATION>> )> >) ( >> > >> FORM> > > `IFSYS> <2 .INST>>> <==? .OP `IFCANNOT>> <=? <2 .INST> <2 .INST2>>>>> ;"ENDIF followed immediately by IFSYS, IFCAN, IFCANNOT that is mutually exclusive should act like jump to beyond the NEXT ENDIF" > <2 .INST> <2 .INST2>>>) (ELSE >)>) (<==? .OP `JUMP> > > ) (ELSE )>) ( <==? .OP `MRETURN> <==? .OP `RTUPLE>> > ) (<==? .OP `SCALL> > > > .ACT-LABELS>)> > >> ) (> )> >) ( <==? .OP `ACALL> <==? .OP `INTGO> <==? .OP `AGAIN> <==? .OP `RETRY> <==? .OP `CONS> <==? .OP `LIST> <==? .OP `UBLOCK> <==? .OP `UUBLOCK>> > > > .ACT-LABELS>)> >) (<==? .OP `NTHR> >> > <==? <1 .TO> `BRANCH-FALSE>> > > > ) (ELSE )>)>) (<==? .OP `DISPATCH> > ) (ELSE )>> >) ( <==? .OP `IFCAN> <==? .OP `IFCANNOT>> >)> > >) (ELSE >)>) (<==? .OP `LOCATION> > .TO .RETURN-LABEL (.TO !.ACT-LABELS)> ) (<==? .OP `ICALL> ;"ICALLs are weird." > ;"the index of the return label" ;"If there is an = FOO in the ICALL, this is actually set at the return label, so make that happen." >> > .I) !)>)> .TO .TO .ACT-LABELS> ) (> >> > > > ) (ELSE )>) (ELSE >)>)> > )>> .CODE> > BRANCH> )>)> > LABEL> )>)> T> ;"NOT-MERGEABLE-IFSYS-TYPES returns true if the ifsys args aren't a subset" ) (<=? .B "TOPS20"> T) (<=? .A "UNIX"> <> ;"B must be VAX, MAC or UNIX") (<=? .B "UNIX"> <> ;"A must be VAX, MAC or UNIX") ( T)>> >> > > "AUX" (LEVEL:FIX 0)) > > > FORM> >> > >> FORM> <==? <1 .INST> `IFSYS> > T) (ELSE >)>> .MTUP>> >) (ELSE )>) (ELSE >)>) ( <==? .OP `IFCAN> <==? .OP `IFCANNOT>> >)>)>>> )) > .CUR-LEV>)>> >> ASSIGN:]>>) > > ) (ELSE )> > > .OUTCHAN> )>) (ELSE )) ) .IN> .LV> .LV> )>> .ASSIGN>)> > > > ) .I> .LIVE-TEMPS> .LIVE-TEMPS> )>> .ASSIGN>)>)>) ( > .LIVE-TEMPS>> >) (ELSE ;"had better be a form" > >)> )>>> > ;"First put all temps from both into LIVES" <1 .BP>>>> .LIVES .B-LIVES> ;"Now make any to be added to B-LIVES unmeargable with those there and flag the fact that a change occured" <1 .BP>>)) ;"Something was added to B-LIVES" ;"Now do the unmergeables" ) (MSK:FIX 1)) 0> > .LIVES> )>)> > >>)> > >> .LIVES .B-LIVES> .LIVES> ;"ICALL is weird. Even though it can have an = FOO, this assignment effectively takes place at the exit label." > > > .LIVES> > ATOM> >)>) (<==? .OP `SETLR> > .LIVES> > ATOM> >)> > ATOM> >)>) (<==? .OP `SETRL> > .LIVES> > ATOM> >)> > ATOM> >)>) (<==? .OP `TEMP> > .LIVES> )>> >) (<==? .OP `MAKTUP> ) ( > .LIVES> )>> >) (<==? .OP `DISPATCH> > ATOM> >)> > ATOM> >)>) ( > >> > `STACK> )>)> ) ONE) )> > <==? .ONE +> <==? .ONE ->> >) ( > >) ( > <==? <1 .ONE> `TYPE> > ATOM>> > >) (ELSE >)>>)>)> .LIVES> "VALUE" UVECTOR) > .NL) (ELSE .L)>> > )> > > 0> > ) (<==? .LIVE 0> )>> >> > )> > )>)> > >>)> >> .LIVES>)> T> ) INST ATM1 ATM2) > > <==? <1 .INST> `SET> > ATOM> > ATOM> >>> )> )> >>> ) INST) > > `TEMP> <==? <1 .INST> `MAKTUP>>> ) ONE-LONG) <==? > =>> ) (<==? .ATM1> ) (<==? .ATM2> )> >>)> )> >> T> ) ONE-SHORT) <==? > =>> ) (<==? .OLD-TEMP> .ONE-SHORT> <1 .LONG <1 .ONE-SHORT <1 .LONG>>>)> > )> > )> )> >>> T> ) INST OP) > >> > <==? .OP `MAKTUP>> >)>)> )> >>> > <==? > =>> )> ) ONE-SHORT) <==? > =>> )> > > <1 .LONG <1 .ONE-SHORT .ONE-LONG>>)> >> )> > ) (ELSE >>)>> >>)>> TEMP2:) > >> >>>>> ) INST OP) > >> > <==? .OP `MAKTUP>> >)>)> )> >>> > <==? > =>> )> ) ONE-SHORT) <==? > =>> )> > > >> <1 .LONG >>) ( <1 .ONE-LONG <1 <1 .ONE-LONG>>>)>)> <1 .LONG <1 .ONE-SHORT .ONE-LONG>>)> >> )> > ) (ELSE >>)>> >>)>> TEMP2:) >> >>>>> > > >)> >) ( > ) .OLD-TEMP> )>> .ASSIGN>)> >)> >> > > >) (<==? .OP `ICALL> 3> .NEW-TEMP .OLD-TEMP>)>) (<==? .OP `CHTYPE> .NEW-TEMP .OLD-TEMP> > <==? <1 .I> `TYPE> <==? <2 .I> .OLD-TEMP>> <2 .I .NEW-TEMP>)>> >) (ELSE .NEW-TEMP .OLD-TEMP>)>)>> .CODE>> NEW-ATOM:ATOM OLD-ATOM:ATOM) )) <1 .RL .NEW-ATOM>)>> .L> T> )) > -1>)>> >> ASSIGN:]>>) > -1> ) (ELSE )> > > ) (ELSE )) ) .IN> .LV> )>> .ASSIGN>)> > > > ) .I> .LIVE-TEMPS> )>> .ASSIGN>)>)>) ( >>> .LIVE-TEMPS>> >) (ELSE ;"had better be a form" > >)> )>>> ) JD) ;"Add to LIVES any atoms that are not already there. Do this without modifying B-LIVES. Declare all atoms added DEAD in the appropriate place." ;"Since we know that LIVES is a subset of B-LIVES, much of the code goes away." > > >> > >)>> .LIVES .B-LIVES .ND1> ) (ELSE > >) (ELSE )>)> .LIVES> )) <1 .UP2>>>> .U1 .U2 .U3> .U3> ;"ICALL is weird. Even though it can have an = FOO, this assignment effectively takes place at the exit label." > > ATOM>> > >)> ATOM DEAD-VAR> .LIVES .SETTER>)>) (<==? .OP `SETLR> ATOM>> > >)> ATOM DEAD-VAR> .LIVES .SETTER>)> ATOM DEAD-VAR> .LIVES .SETTER>)>) (<==? .OP `SETRL> ATOM>> > >)> ATOM DEAD-VAR> .LIVES .SETTER>)> ATOM DEAD-VAR> .LIVES .SETTER>)>) (<==? .OP `TEMP> .LIVES>)>> >) (<==? .OP `MAKTUP> ) ( .LIVES>)>> >) (<==? .OP `DISPATCH> ATOM DEAD-VAR> .LIVES %<>>)> ATOM DEAD-VAR> .LIVES %<>>)>) ( > >> ATOM>> > > >)>)>) (ELSE >)> ) ONE) )> > <==? .ONE +> <==? .ONE ->> >) ( >) ( > <==? <1 .ONE> `TYPE> ATOM>> .LIVES .SETTER> >) (ELSE >)>>)>)> .LIVES> > L:UVECTOR SETTER: "AUX" (ATM:ATOM ATOM>)) > <1 .RINST >)>> BJL:) >> >> > >) (ELSE )> :FORM> ;"BEGIN TEMPORARY HACK" ;> ; ;"END TEMOPRARY HACK" > 1>> ((`DEAD-JUMP !.JUMP-DEADS))>)> > 1>> ((`DEAD-FALL !.FALL-DEADS))>)> > !)> >)> >>) ( > > `SET> <3 .INST>> DEAD-VAR>>> DEAD-VAR>> DEAD-VAR>> > DEAD-VAR>>> <==? .OP `ACALL>> 1>> ()> <>) ( <==? .OP `SYSOP> <==? .OP `SYSCALL>> ATOM>> <>) (<==? .OP `POP> > >> T) (ELSE >> T)>>) (ELSE > > !)> >)> >>)>) ( > FORM> > <==? <1 .INST> `ENDIF>>> >>)>> .VCODE>> > <>)) > > )) ) ( <==? .OP `ACALL>> > 1>> ()> ) ( > <1 .RINST .ONE> ) ( <==? .OP `CHTYPE> > <==? <1 .ONE> `TYPE> DEAD-VAR>> <2 .ONE ATOM>> >) (ELSE )>> >) (ELSE ())>> ) (MSK:FIX 1)) 0> !.L)> > )>)> > >>)> >> .UV> .L>