Machine-Independent MDL for TOPS-20 and VAX.
[pdp10-muddle.git] / mim / development / mim / mimc / death.mud
diff --git a/mim/development/mim/mimc/death.mud b/mim/development/mim/mimc/death.mud
new file mode 100644 (file)
index 0000000..6454d31
--- /dev/null
@@ -0,0 +1,1206 @@
+<PACKAGE "DEATH">
+"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."
+
+
+
+<ENTRY REMOVE-DEADS FIXUP-DEATH DEBUG-DEATH MAINTAIN-DECLS>
+
+<USE "NEWSTRUC">
+
+<SETG DEBUG-DEATH %<>>
+<SETG MAINTAIN-DECLS %<>>
+
+"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."
+
+<GDECL (NAME-UV) <VECTOR [REST ATOM]> (UVSIZE) FIX>
+
+<NEWTYPE DEAD-VAR ATOM>
+
+<NEWSTRUC LABEL                VECTOR
+         L-INST        <OR ATOM FORM>
+         L-INS         <LIST [REST FIX]>
+         L-LEVEL       FIX
+         L-ASSIGN      <OR FALSE <LIST [REST !<LIST ATOM FIX>]>>>
+
+<NEWSTRUC BRANCH       VECTOR
+         B-INST        FORM
+         B-OUTS        <LIST [REST FIX]>
+         B-LIVES       UVECTOR
+         B-FALL-DEADS  UVECTOR
+         B-JUMP-DEADS  <OR FALSE UVECTOR>>
+
+
+<DEFMAC /32 ('X) <FORM LSH .X -5>>
+
+<DEFINE FIXUP-DEATH (CODE:LIST "AUX" (OUTCHAN .OUTCHAN))
+   <COND (,DEBUG-DEATH
+         <PRINTSTRING "Fixup-death: " .OUTCHAN>
+         <PRIN1 <2 <1 .CODE>:FORM> .OUTCHAN>
+         <CRLF .OUTCHAN>
+         <PRINTSTRING "Removing deads" .OUTCHAN>
+         <CRLF .OUTCHAN>)>
+   <SETG ANY-FLUSHED-INS <>>
+   <BIND ((CODELEN:FIX <REMOVE-DEADS .CODE>)
+         (VCODE:<SPECIAL VECTOR> <IVECTOR .CODELEN>) (VC:VECTOR .VCODE) 
+         LOOP-LABELS:<LIST [REST LABEL]>)
+      <MAPF <>
+           <FUNCTION (X)
+                <COND (<AND <TYPE? .X FORM>
+                            <NOT <EMPTY? .X>>
+                            <==? <1 .X> `ENDIF>>
+                       <PUT .VC 1 .X> ;"Note:  ENDIFs go in twice!"
+                       <SET VC <REST .VC>>)>
+                <PUT .VC 1 .X>
+                <SET VC <REST .VC>>>
+           .CODE>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "Preparing labels and temps" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <SET LOOP-LABELS <PREPARE-LABELS-AND-TEMPS .VCODE>>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "Preparing branches" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <PREPARE-BRANCHES .VCODE 1 .CODELEN .CODELEN ()>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "Backwalking" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <REPEAT ((LEVEL 1))
+        <COND (,DEBUG-DEATH
+               <PRINTSTRING "Pass " .OUTCHAN>
+               <PRIN1 .LEVEL .OUTCHAN>
+               <CRLF .OUTCHAN>)>
+        <SETG SOMETHING-CHANGED %<>>
+        <BACKWALK-FROM-LABEL .VCODE <NTH .VCODE .CODELEN> .LEVEL>
+        <MAPF %<>
+              <FUNCTION (LABEL:LABEL)
+                 <BACKWALK-FROM-LABEL .VCODE .LABEL .LEVEL>>
+              .LOOP-LABELS>
+        <COND (<NOT ,SOMETHING-CHANGED>
+               <RETURN>)>
+        <SET LEVEL <+ .LEVEL 1>>>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "SET optimization" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <OPTIMIZE-SETS .VCODE>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "General optimization" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <OPTIMIZE-TEMPS .VCODE>
+      ;"This pass never seems to find anything it can merge."
+      <COND (<NOT ,MAINTAIN-DECLS>
+            <COND (,DEBUG-DEATH
+                   <PRINTSTRING "Optional optimization pass (ignoring decls)"
+                                .OUTCHAN>
+                   <CRLF .OUTCHAN>)>
+            <OPTIMIZE-TEMPS/BASH-DECLS .VCODE>)>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "Preparing deads" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <PREPARE-DEADS-FROM-LABEL .VCODE <NTH .VCODE .CODELEN>>
+      <MAPF %<>
+           <FUNCTION (LABEL:LABEL)
+              <PREPARE-DEADS-FROM-LABEL .VCODE .LABEL>>
+           .LOOP-LABELS>
+      <COND (,DEBUG-DEATH
+            <PRINTSTRING "Inserting deads" .OUTCHAN>
+            <CRLF .OUTCHAN>)>
+      <INSERT-DEADS .CODE .VCODE>>
+   <COND (,DEBUG-DEATH
+         <PRINTSTRING "Death complete: " .OUTCHAN>
+         <PRIN1 <2 <1 .CODE>:FORM> .OUTCHAN>
+         <CRLF .OUTCHAN>)>
+   ,ANY-FLUSHED-INS>
+
+"ADD-LIST ORs a bit into a uvector.  In the old world it addes an atom to
+ a LIST."
+
+<DEFINE ADD-LIST (ATM:ATOM L:UVECTOR "VALUE" UVECTOR
+                 "AUX" (NUM:FIX <1 <GVAL .ATM>:UVECTOR>)
+                       (WD:FIX <+ </32 .NUM> 1>) (BIT:FIX <MOD .NUM 32>))
+       <PUT .L .WD <ORB <NTH .L .WD> <LSH 1 .BIT>>>>
+
+"ADD-LIST? same as ADD-LIST except returns #FALSE () if already there."
+
+<DEFINE ADD-LIST? (ATM:ATOM L:UVECTOR "VALUE" <OR FALSE UVECTOR>
+                  "AUX" (NUM:FIX <1 <GVAL .ATM>:UVECTOR>) TEM:FIX
+                        (WD:FIX <+ </32 .NUM> 1>) (BIT:FIX <MOD .NUM 32>))
+       <COND (<==? <ANDB <SET TEM <NTH .L .WD>> <SET BIT <LSH 1 .BIT>>> 0>
+              <PUT .L .WD <ORB .TEM .BIT>>)>>
+
+"REM-LIST kill a bit in the uvector same way as ADD-LIST."
+
+<DEFINE REM-LIST (ATM:ATOM L:UVECTOR
+                 "AUX" (NUM:FIX <1 <GVAL .ATM>:UVECTOR>)
+                       (WD:FIX <+ </32 .NUM> 1>) (BIT:FIX <MOD .NUM 32>))
+       <PUT .L .WD <ANDB <NTH .L .WD>  <ROT <XORB 1 -1> .BIT>>>>
+
+"REM-LIST? return false if not there, else remove it and return true"
+
+<DEFINE REM-LIST? (ATM:ATOM L:UVECTOR
+                  "AUX" (NUM:FIX <1 <GVAL .ATM>:UVECTOR>) TEM:FIX
+                        (WD:FIX <+ </32 .NUM> 1>) (BIT:FIX <MOD .NUM 32>))
+       <SET BIT <LSH 1 .BIT>>
+       <COND (<N==? <ANDB <SET TEM <NTH .L .WD>> .BIT> 0>
+              <PUT .L .WD <XORB .TEM .BIT>>)>>
+
+"IN-LIST? see if bit is on"
+
+<DEFINE IN-LIST? (ATM:ATOM L:UVECTOR "VALUE" <OR FALSE UVECTOR>
+                 "AUX" (NUM:FIX <1 <GVAL .ATM>:UVECTOR>)
+                       (WD:FIX <+ </32 .NUM> 1>) (BIT:FIX <MOD .NUM 32>))
+       <COND (<==? <ANDB <NTH .L .WD> <LSH 1 .BIT>> 0> <>)
+             (ELSE .L)>>
+
+<DEFINE INTERSECT-LISTS (L1:<LIST [REST ATOM]> L2:<LIST [REST ATOM]>)
+   ;"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."
+   <MAPF ,LIST
+        <FUNCTION (A1:ATOM)
+           <COND (<MEMQ .A1 .L2> <MAPRET .A1>)
+                 (ELSE <MAPRET>)>>
+        .L1>>
+
+<DEFINE ATOM-PART (TEMP:<OR ATOM ADECL LIST> "VALUE" ATOM)
+   <COND (<TYPE? .TEMP ATOM> .TEMP)
+        (<TYPE? .TEMP ADECL> <1 .TEMP>)
+        (ELSE <ATOM-PART <1 .TEMP>>)>>
+
+<DEFINE DECL-PART (TEMP:<OR ATOM ADECL LIST>)
+   <COND (<TYPE? .TEMP ATOM> %<>)
+        (<TYPE? .TEMP ADECL> <2 .TEMP>)
+        (ELSE <DECL-PART <1 .TEMP>>)>>
+
+<DEFINE INST-PART (INST)
+   <COND (<TYPE? .INST BRANCH> <B-INST .INST>)
+        (<TYPE? .INST LABEL> <L-INST .INST>)
+        (ELSE .INST)>>
+
+;"REMOVE-DEADS also counts number of ins (and one extra per ENDIF)"
+
+<DEFINE REMOVE-DEADS (CODE:LIST)
+   <REPEAT ((RCODE:LIST <REST .CODE>) INST OP (CODE-SIZE:FIX 1))
+      <COND (<EMPTY? .RCODE> <RETURN .CODE-SIZE>)>
+      <SET INST <1 .RCODE>>
+      <COND (<AND <TYPE? .INST FORM>
+                 <NOT <EMPTY? .INST>>
+                 <KILL-FUNNY-DEADS .INST>
+                 <COND (<==? <SET OP <1 .INST>> `DEAD>
+                        <PUTREST .CODE <SET RCODE <REST .RCODE>>>
+                        T)
+                       (<==? .OP `ENDIF>
+                        <SET CODE-SIZE <+ .CODE-SIZE 1>>
+                        <>)>>)
+           (ELSE
+            <SET CODE-SIZE <+ .CODE-SIZE 1>>
+            <SET RCODE <REST <SET CODE .RCODE>>>)>>>
+
+<DEFINE KILL-FUNNY-DEADS (INST:FORM "AUX" (N:FIX <LENGTH .INST>) "VALUE" ATOM)
+       <REPEAT (L FOO)
+               <COND (<AND <TYPE? <SET L <NTH .INST .N>> LIST>
+                           <NOT <EMPTY? .L>>
+                           <OR <==? <SET FOO <1 .L>> `DEAD-FALL>
+                               <==? .FOO `DEAD-JUMP>>>
+                      <PUTREST <REST .INST <- .N 2>> ()>
+                      <SET N <- .N 1>>)
+                     (ELSE <RETURN T>)>>>
+
+<DEFINE PREPARE-LABELS-AND-TEMPS (CODE:VECTOR
+                                 "AUX" 
+                                 (ALL-VARS:LIST ()) (NTEMPS:FIX 0)
+                                 (CODELEN:FIX <LENGTH .CODE>)
+                                 (LOOP-LABELS:<LIST [REST LABEL]> ()))
+   <REPEAT ((I:FIX 1) INST OP (LOOP-LABEL? %<>) LABEL:LABEL (DID-ENDIF <>))
+      <SET INST <NTH .CODE .I>>
+      <COND (<TYPE? .INST ATOM>
+            <SETG .INST .I>
+            <SET LABEL <CHTYPE [.INST () 0 %<>] LABEL>>
+            <COND (.LOOP-LABEL?
+                   <SET LOOP-LABELS (.LABEL !.LOOP-LABELS)>
+                   <SET LOOP-LABEL? %<>>)>
+            <PUT .CODE .I .LABEL>)
+           (<AND <TYPE? .INST FORM> <NOT <EMPTY? .INST>>>
+            <SET OP <1 .INST>>
+            <COND (<OR <==? .OP `END>
+                       <AND <==? .OP `ENDIF>
+                            .DID-ENDIF>>
+                   <SET DID-ENDIF <>>
+                   <PUT .CODE .I <CHTYPE [.INST () 0 %<>] LABEL>>)
+                  (<AND <==? .OP `ENDIF> <NOT .DID-ENDIF>>
+                   <SET DID-ENDIF T>)
+                  (<==? .OP `LOOP>
+                   <SET LOOP-LABEL? T>)
+                  (<==? .OP `ACTIVATION>
+                   <SET LABEL <CHTYPE [.INST () 0 %<>] LABEL>>
+                   <SET LOOP-LABELS (.LABEL !.LOOP-LABELS)>
+                   <PUT .CODE .I .LABEL>)
+                  (<OR <==? .OP `GFCN> 
+                       <==? .OP `FCN>>
+                   <SET ALL-VARS (<SET INST <REST .INST 3>> !.ALL-VARS)>
+                   <SET NTEMPS <+ .NTEMPS <LENGTH .INST>>>)
+                  (<==? .OP `TEMP>
+                   <SET ALL-VARS (<SET INST <REST .INST>> !.ALL-VARS)>
+                   <SET NTEMPS <+ .NTEMPS <LENGTH .INST>>>)
+                  (<==? .OP `MAKTUP>
+                   <SET ALL-VARS (<REST .INST> !.ALL-VARS)>
+                   <SET NTEMPS <+ .NTEMPS <LENGTH .INST> -3>>)>)>
+      <COND (<==? .I .CODELEN> <RETURN>)>
+      <SET I <+ .I 1>>>
+   <CONSTRUCT-TEMPS .NTEMPS .ALL-VARS>
+   .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"
+
+<DEFINE CONSTRUCT-TEMPS (NTEMPS:FIX ALL-VARS:<LIST [REST LIST]>
+                        "AUX" (UVSIZE </32 <+ .NTEMPS 32 31>>)
+                              (UV-OF-NAMES <IVECTOR .NTEMPS>) (I:FIX 0))
+       <MAPF <>
+             <FUNCTION (L:LIST)
+                  <MAPF <>
+                        <FUNCTION (ATM "AUX" UV:UVECTOR)
+                             <COND (<==? .ATM => <MAPLEAVE>)>
+                             <SETG <SET ATM <ATOM-PART .ATM>>
+                                   <SET UV <IUVECTOR .UVSIZE 0>>>
+                             <PUT .UV 1 .I>
+                             <PUT .UV-OF-NAMES <+ .I 1> .ATM>
+                             <SET I <+ .I 1>>>
+                        .L>>
+             .ALL-VARS>
+       <SETG NAME-UV .UV-OF-NAMES>
+       <SETG UVSIZE <- .UVSIZE 1>>             ;"Since only bit masks stored">
+
+<DEFMAC MAKE-BRANCH ('INST)
+   <FORM CHTYPE [.INST () <FORM IUVECTOR ',UVSIZE 0>
+                <FORM IUVECTOR ',UVSIZE 0> %<>] BRANCH>>
+
+;"END is required to be the location of the return label."
+
+<DEFINE PREPARE-BRANCHES (CODE:VECTOR START:FIX END:FIX RETURN-LABEL:FIX
+                         ACT-LABELS:<LIST [REST FIX]>)
+   <REPEAT ((I:FIX .START) INST OP TO ASSIGN LAB:LABEL INST2
+           (DONT-BRANCH-IFSYS <>))
+      <SET INST <NTH .CODE .I>>
+      <COND (<TYPE? .INST LABEL>
+            <SET INST <L-INST .INST>>
+            <COND (<AND <TYPE? .INST FORM> <==? <1 .INST> `ACTIVATION>>
+                   <SET ACT-LABELS (.I .RETURN-LABEL !.ACT-LABELS)>)>
+            <MAKE-CONNECTION .CODE .I <+ .I 1>>)
+           (<AND <TYPE? .INST FORM> <NOT <EMPTY? .INST>>>
+            <SET OP <1 .INST>>
+            <COND (<==? .OP `ENDIF>
+                   <COND (<AND <TYPE? <SET INST2 <NTH .CODE <+ .I 2>>> FORM>
+                               <NOT <EMPTY? .INST2>>
+                               <OR <AND <==? <SET OP <1 .INST2>> `IFSYS>
+                                        <NOT-MERGEABLE-IFSYS-TYPES <2 .INST2>
+                                                                   <2 .INST>>>
+                                   <AND <OR <==? .OP `IFCAN>
+                                            <==? .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"
+                          <SET DONT-BRANCH-IFSYS T>
+                          <PUT .CODE .I <MAKE-BRANCH .INST>>
+                          <MAKE-CONNECTION
+                           .CODE
+                           .I
+                           <FUNNY-FIND-ENDIF .CODE
+                                             <+ .I 1>
+                                             <2 .INST>
+                                             <2 .INST2>>>)
+                         (ELSE
+                          <MAKE-CONNECTION .CODE .I <+ .I 1>>)>)
+                  (<==? .OP `JUMP>
+                   <PUT .CODE .I <MAKE-BRANCH .INST>>
+                   <SET TO <3 .INST>>
+                   <COND (<GASSIGNED? .TO>
+                          <MAKE-CONNECTION .CODE .I ,.TO>)
+                         (ELSE
+                          <MAKE-CONNECTION .CODE .I .RETURN-LABEL>)>)
+                  (<OR <==? .OP `RETURN> 
+                       <==? .OP `MRETURN>
+                       <==? .OP `RTUPLE>>
+                   <PUT .CODE .I <MAKE-BRANCH .INST>>
+                   <MAKE-CONNECTION .CODE .I .RETURN-LABEL>)
+                  (<==? .OP `SCALL>
+                   <PUT .CODE .I <MAKE-BRANCH .INST>>
+                   <COND (<NOT <EMPTY? .ACT-LABELS>>
+                          <MAPF %<>
+                                <FUNCTION (ACT)
+                                   <MAKE-CONNECTION .CODE .I .ACT>>
+                                .ACT-LABELS>)>
+                   <SET TO <7 .INST>>
+                   <COND (<AND <GASSIGNED? .TO> <N==? ,.TO <+ .I 1>>>
+                          <MAKE-CONNECTION .CODE .I ,.TO>)
+                         (<NOT <GASSIGNED? .TO>>
+                          <MAKE-CONNECTION .CODE .I .RETURN-LABEL>)>
+                   <MAKE-CONNECTION .CODE .I <+ .I 1>>)
+                  (<OR <==? .OP `CALL>
+                       <==? .OP `ACALL>
+                       <==? .OP `INTGO>
+                       <==? .OP `AGAIN>
+                       <==? .OP `RETRY>
+                       <==? .OP `CONS>
+                       <==? .OP `LIST>
+                       <==? .OP `UBLOCK>
+                       <==? .OP `UUBLOCK>>
+                   <COND (<NOT <EMPTY? .ACT-LABELS>>
+                          <PUT .CODE .I <MAKE-BRANCH .INST>>
+                          <MAPF %<>
+                                <FUNCTION (ACT)
+                                   <MAKE-CONNECTION .CODE .I .ACT>>
+                                .ACT-LABELS>)>
+                   <MAKE-CONNECTION .CODE .I <+ .I 1>>)
+                  (<==? .OP `NTHR>
+                   <SET TO <NTH .INST <LENGTH .INST>>>
+                   <COND (<AND <TYPE? .TO LIST>
+                               <NOT <EMPTY? .TO>>
+                               <==? <1 .TO> `BRANCH-FALSE>>
+                          <SET TO <3 .TO>>
+                          <PUT .CODE .I <MAKE-BRANCH .INST>>
+                          <MAKE-CONNECTION .CODE .I <+ .I 1>>
+                          <COND (<GASSIGNED? .TO>
+                                 <MAKE-CONNECTION .CODE .I ,.TO>)
+                                (ELSE
+                                 <MAKE-CONNECTION .CODE .I .RETURN-LABEL>)>)>)
+                  (<==? .OP `DISPATCH>
+                   <PUT .CODE .I <MAKE-BRANCH .INST>>
+                   <MAPF %<>
+                         <FUNCTION (TO)
+                            <COND (<GASSIGNED? .TO>
+                                   <MAKE-CONNECTION .CODE .I ,.TO>)
+                                  (ELSE
+                                   <MAKE-CONNECTION .CODE .I .RETURN-LABEL>)>>
+                         <REST .INST 3>>)
+                  (<OR <==? .OP `IFSYS>
+                       <==? .OP `IFCAN>
+                       <==? .OP `IFCANNOT>>
+                   <COND (<NOT .DONT-BRANCH-IFSYS>
+                          <PUT .CODE .I <MAKE-BRANCH .INST>>)>
+                   <MAKE-CONNECTION .CODE .I <+ .I 1>>
+                   <COND (.DONT-BRANCH-IFSYS <SET DONT-BRANCH-IFSYS <>>)
+                         (ELSE
+                          <MAKE-CONNECTION .CODE .I <FIND-ENDIF .CODE .I>>)>)
+                  (<==? .OP `LOCATION>
+                   <SET TO ,<3 .INST>>
+                   <PREPARE-BRANCHES .CODE <+ .I 1> .TO .RETURN-LABEL
+                                     (.TO !.ACT-LABELS)>
+                   <SET I .TO>)
+                  (<==? .OP `ICALL>
+                   ;"ICALLs are weird."
+                   <SET TO ,<2 .INST>> ;"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."
+                   <SET ASSIGN <MEMQ = <REST .INST 2>>>
+                   <COND (.ASSIGN
+                          <SET LAB <NTH .CODE .TO>>
+                          <L-ASSIGN .LAB ((<2 .ASSIGN> .I)
+                                          !<L-ASSIGN .LAB>)>)>
+                   <PREPARE-BRANCHES .CODE <+ .I 1> .TO .TO .ACT-LABELS>
+                   <SET I .TO>)
+                  (<OR <SET TO <MEMQ + .INST>>
+                       <SET TO <MEMQ - .INST>>>
+                   <SET TO <2 .TO>>
+                   <PUT .CODE .I <MAKE-BRANCH .INST>>
+                   <MAKE-CONNECTION .CODE .I <+ .I 1>>
+                   <COND (<GASSIGNED? .TO>
+                          <MAKE-CONNECTION .CODE .I ,.TO>)
+                         (ELSE
+                          <MAKE-CONNECTION .CODE .I .RETURN-LABEL>)>)
+                  (ELSE
+                   <MAKE-CONNECTION .CODE .I <+ .I 1>>)>)>
+      <SET I <+ .I 1>>
+      <COND (<==? .I .END> <RETURN .CODE>)>>
+   .CODE>
+            
+<DEFINE MAKE-CONNECTION (CODE:VECTOR FROM:FIX TO:FIX 
+                        "AUX" FROM-BRANCH TO-LABEL)
+   <COND (<TYPE? <SET FROM-BRANCH <NTH .CODE .FROM>> BRANCH>
+         <B-OUTS .FROM-BRANCH (.TO !<B-OUTS .FROM-BRANCH>)>)>
+   <COND (<TYPE? <SET TO-LABEL <NTH .CODE .TO>> LABEL>
+         <L-INS .TO-LABEL (.FROM !<L-INS .TO-LABEL>)>)>
+   T>
+
+;"NOT-MERGEABLE-IFSYS-TYPES returns true if the ifsys args aren't a subset"
+
+<DEFINE NOT-MERGEABLE-IFSYS-TYPES (A B)
+       <COND (<=? .A "TOPS20"> <N=? .B "TOPS20">)
+             (<=? .B "TOPS20"> T)
+             (<=? .A "UNIX"> <> ;"B must be VAX, MAC or UNIX")
+             (<=? .B "UNIX"> <> ;"A must be VAX, MAC or UNIX")
+             (<N=? .A .B> T)>>
+
+<DEFINE FIND-ENDIF (CODE:VECTOR I:FIX)
+       <REAL-FIND-ENDIF .CODE .I <>>>
+
+<DEFINE FUNNY-FIND-ENDIF (CODE:VECTOR I:FIX "TUPLE" MTUP)
+       <REAL-FIND-ENDIF .CODE .I .MTUP>>
+
+<DEFINE REAL-FIND-ENDIF (CODE:VECTOR I:FIX MTUP:<OR FALSE <PRIMTYPE VECTOR>>
+                        "AUX" (LEVEL:FIX 0))
+   <REPEAT (INST OP)
+      <SET I <+ .I 1>>
+      <SET INST <NTH .CODE .I>>
+      <COND (<AND <TYPE? .INST LABEL>
+                 <TYPE? <SET INST <L-INST .INST>> FORM>
+                 <NOT <EMPTY? .INST>>>
+            <SET OP <1 .INST>>
+            <COND (<==? .OP `ENDIF>
+                   <COND
+                    (<0? .LEVEL>
+                     <COND
+                      (<AND .MTUP
+                            <TYPE? <SET INST <NTH .CODE <+ .I 2>>>
+                                   FORM>
+                            <==? <1 .INST> `IFSYS>
+                            <MAPF <>
+                                  <FUNCTION (S)
+                                       <COND (<NOT-MERGEABLE-IFSYS-TYPES
+                                               .S <2 .INST>>
+                                              T)
+                                             (ELSE <MAPLEAVE <>>)>>
+                                  .MTUP>>
+                       <SET I <+ .I 1>>)
+                      (ELSE <RETURN .I>)>)
+                    (ELSE <SET LEVEL <- .LEVEL 1>>)>)
+                  (<OR <==? .OP `IFSYS>
+                       <==? .OP `IFCAN>
+                       <==? .OP `IFCANNOT>>
+                   <SET LEVEL <+ .LEVEL 1>>)>)>>>
+
+<DEFINE BACKWALK-FROM-LABEL (CODE:VECTOR LABEL:LABEL CUR-LEV:FIX)
+   <MAPF %<>
+        <FUNCTION (IN:FIX "AUX" (INST <NTH .CODE .IN>))
+           <COND (<TYPE? .INST BRANCH>
+                  <BACKWALK .CODE .IN <UVECTOR !<B-LIVES .INST>> .CUR-LEV>)>>
+        <L-INS .LABEL>>>   
+
+<DEFINE BACKWALK (CODE:VECTOR I:FIX LIVE-TEMPS:UVECTOR CUR-LEV:FIX)
+   <REPEAT (INST INS:<LIST [REST FIX]>
+           ASSIGN:<OR FALSE <LIST [REST !<LIST ATOM FIX>]>>)
+      <SET INST <NTH .CODE .I>>
+      <COND (<TYPE? .INST LABEL>
+            <COND (<L=? .CUR-LEV <L-LEVEL .INST>> <RETURN>)
+                  (ELSE <L-LEVEL .INST .CUR-LEV>)>
+            <SET ASSIGN <L-ASSIGN .INST>>
+            <SET INS <L-INS .INST>>
+            <COND (<EMPTY? .INS>
+                   <COND (<==? .CUR-LEV 1>
+                          <PRINTSTRING 
+                           "FILE-DEATH: Warning--unreachable code at "
+                           .OUTCHAN>
+                          <PRIN1 <L-INST .INST> .OUTCHAN>
+                          <CRLF .OUTCHAN>
+                          <RETURN>)>)
+                  (ELSE
+                   <MAPF %<>
+                         <FUNCTION (IN "AUX" (LV:UVECTOR <UVECTOR !.LIVE-TEMPS>))
+                            <COND (.ASSIGN
+                                   <MAPF <>
+                                         <FUNCTION (LL:!<LIST ATOM FIX>)
+                                              <COND (<==? <2 .LL> .IN>
+                                                     <REM-LIST <1 .LL> .LV>
+                                                     <UNMERGEABLE <1 .LL> .LV>
+                                                     <MAPLEAVE>)>>
+                                         .ASSIGN>)>
+                            <BACKWALK .CODE .IN .LV .CUR-LEV>>
+                         <REST .INS>>
+                   <SET I <1 .INS>>
+                   <COND (.ASSIGN
+                          <MAPF <>
+                                <FUNCTION (LL:!<LIST ATOM FIX>)
+                                     <COND (<==? <2 .LL> .I>
+                                            <REM-LIST <1 .LL> .LIVE-TEMPS>
+                                            <UNMERGEABLE <1 .LL> .LIVE-TEMPS>
+                                            <MAPLEAVE>)>>
+                                .ASSIGN>)>)>)
+           (<TYPE? .INST BRANCH>
+            <SET LIVE-TEMPS <MERGE-TEMPS .LIVE-TEMPS .INST>>
+            <SET LIVE-TEMPS <UPDATE-TEMPS <B-INST .INST> .LIVE-TEMPS>>
+            <SET I <- .I 1>>)
+           (ELSE       ;"had better be a form"
+            <SET LIVE-TEMPS <UPDATE-TEMPS .INST .LIVE-TEMPS>>
+            <SET I <- .I 1>>)>
+      <COND (<0? .I> <RETURN>)>>>
+
+<DEFINE MERGE-TEMPS (LIVES:UVECTOR BRANCH:BRANCH
+                    "AUX" B-LIVES:UVECTOR (TEMP-OFFS:FIX 0))
+   ;"Add to each list the items on the other list."
+   ;"Every time a temp is added to B-LIVES, it must be declared UNMERGEABLE 
+     with the ones already there."
+   <SET B-LIVES <B-LIVES .BRANCH>>
+   ;"First put all temps from both into LIVES"
+   <MAPR <>
+        <FUNCTION (LP:UVECTOR BP:UVECTOR)
+             <PUT .LP 1 <ORB <1 .LP> <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"
+   <MAPR <>
+        <FUNCTION (LP:UVECTOR BP:UVECTOR
+                   "AUX" (ADDED:FIX <XORB <1 .LP> <1 .BP>>))
+             <COND (<N==? .ADDED 0>
+                    ;"Something was added to B-LIVES"
+                    <SETG SOMETHING-CHANGED T>
+                    ;"Now do the unmergeables"
+                    <REPEAT ((TNO:FIX <+ .TEMP-OFFS 1>) (MSK:FIX 1))
+                            <COND (<N==? <ANDB .MSK .ADDED> 0>
+                                   <SET ADDED <XORB .ADDED .MSK>>
+                                   <UNMERGEABLE <NTH ,NAME-UV .TNO> .LIVES>
+                                   <COND (<==? .ADDED 0> <RETURN>)>)>
+                            <SET MSK <LSH .MSK 1>>
+                            <SET TNO <+ .TNO 1>>>)>
+             <SET TEMP-OFFS <+ .TEMP-OFFS 32>>
+             <PUT .BP 1 <1 .LP>>>
+        .LIVES .B-LIVES>
+   <B-LIVES .BRANCH .B-LIVES>
+   .LIVES>
+
+;"ICALL is weird.  Even though it can have an = FOO, this assignment 
+  effectively takes place at the exit label."
+
+<DEFINE UPDATE-TEMPS (INST:FORM LIVES:UVECTOR 
+                     "AUX" OP ITEM TWO THREE FOUR)
+   <COND (<NOT <EMPTY? .INST>>
+         <SET OP <1 .INST>>
+         <COND (<==? .OP `SET>
+                <REM-LIST <SET TWO <2 .INST>> .LIVES>
+                <UNMERGEABLE .TWO .LIVES>
+                <COND (<TYPE? <SET THREE <3 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .THREE .LIVES>>)>)
+               (<==? .OP `SETLR>
+                <REM-LIST <SET TWO <2 .INST>> .LIVES>
+                <UNMERGEABLE .TWO .LIVES>
+                <COND (<TYPE? <SET THREE <3 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .THREE .LIVES>>)>
+                <COND (<TYPE? <SET FOUR <4 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .FOUR .LIVES>>)>)
+               (<==? .OP `SETRL>
+                <REM-LIST <SET THREE <3 .INST>> .LIVES>
+                <UNMERGEABLE .THREE .LIVES>
+                <COND (<TYPE? <SET TWO <2 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .TWO .LIVES>>)>
+                <COND (<TYPE? <SET FOUR <4 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .FOUR .LIVES>>)>)
+               (<==? .OP `TEMP>
+                <MAPF %<>
+                      <FUNCTION (T "AUX" ATM)
+                         <COND (<TYPE? .T LIST>
+                                <REM-LIST <SET ATM <ATOM-PART .T>>
+                                          .LIVES>
+                                <UNMERGEABLE .ATM .LIVES>)>>
+                      <REST .INST>>)
+               (<==? .OP `MAKTUP>
+                <MAPF %<>
+                      <FUNCTION (T "AUX" ATM)
+                         <COND (<==? .T => <MAPLEAVE>)
+                               (<TYPE? .T LIST>
+                                <REM-LIST <SET ATM <ATOM-PART .T>>
+                                          .LIVES>
+                                <UNMERGEABLE .ATM .LIVES>)>>
+                      <REST .INST>>)
+               (<==? .OP `DISPATCH>
+                <COND (<TYPE? <SET TWO <2 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .TWO .LIVES>>)>
+                <COND (<TYPE? <SET THREE <3 .INST>> ATOM>
+                       <SET LIVES <ADD-LIVE .THREE .LIVES>>)>)
+               (<AND <N==? .OP `FCN>
+                     <N==? .OP `GFCN>
+                     <N==? .OP `LOOP>
+                     <N==? .OP `END>
+                     <N==? .OP `ICALL>
+                     <N==? .OP `OPT-DISPATCH>>
+                <SET ITEM <MEMQ = <REST .INST>>>
+                <COND (.ITEM
+                       <COND (<N==? <SET TWO <2 .ITEM>> `STACK>
+                              <REM-LIST .TWO .LIVES>
+                              <UNMERGEABLE .TWO .LIVES>)>)>
+                <REPEAT ((RINST <REST .INST>) ONE)
+                   <COND (<EMPTY? .RINST> <RETURN>)>
+                   <SET ONE <1 .RINST>>
+                   <COND (<OR <==? .ONE =>
+                              <==? .ONE +>
+                              <==? .ONE ->>
+                          <SET RINST <REST .RINST 2>>)
+                         (<TYPE? .ONE ATOM>
+                          <SET LIVES <ADD-LIVE .ONE .LIVES>>
+                          <SET RINST <REST .RINST>>)
+                         (<AND <==? .OP `CHTYPE>
+                               <TYPE? .ONE FORM>
+                               <NOT <LENGTH? .ONE 1>>
+                               <==? <1 .ONE> `TYPE>
+                               <TYPE? <SET TWO <2 .ONE>> ATOM>>
+                          <SET LIVES <ADD-LIVE .TWO .LIVES>>
+                          <SET RINST <REST .RINST>>)
+                         (ELSE
+                          <SET RINST <REST .RINST>>)>>)>)>
+   .LIVES>
+
+<DEFINE ADD-LIVE (ATM:ATOM L:UVECTOR 
+                 "AUX" NL:<OR FALSE UVECTOR>
+                 "VALUE" UVECTOR)
+   <SET NL <ADD-LIST? .ATM .L>>
+   <COND (.NL <UNMERGEABLE .ATM .L> .NL)
+        (ELSE .L)>>
+
+<DEFINE UNMERGEABLE (NEW-LIVE:ATOM LIVES:UVECTOR
+                   "AUX" NL-LIST:UVECTOR NUM:FIX WD:FIX BIT:FIX
+                         (TEMP-OFFS:FIX 0))
+   ;"The error tests were removed to make things run faster.  Believe it
+     or not, this function is one of the big time sinks of the package."
+   <COND (<NOT <GASSIGNED? .NEW-LIVE>>
+         <ERROR TEMP-WITHOUT-LIST!-ERRORS .NEW-LIVE UNMERGEABLE>)>
+   <COND (<N==? .NEW-LIVE `STACK>
+         <SET NL-LIST ,.NEW-LIVE>
+         <SET NUM <1 .NL-LIST>>
+         <SET NL-LIST <REST .NL-LIST>>
+         <MAPF <>
+               <FUNCTION (LIVE:FIX "AUX" ATM)
+                    <COND (<N==? .LIVE 0>
+                           <REPEAT ((TNO:FIX .TEMP-OFFS) (MSK:FIX 1))
+                                   <COND (<AND <N==? <ANDB .LIVE .MSK> 0>
+                                               <SET LIVE <XORB .LIVE .MSK>>
+                                               <COND (<N==? .TNO .NUM>)
+                                                     (<==? .LIVE 0>
+                                                      <RETURN>)>>
+                                          <SET ATM <NTH ,NAME-UV
+                                                        <+ .TNO 1>>>
+                                          <COND (<NOT <GASSIGNED? .ATM>>
+                                                 <ERROR
+                                                  TEMP-WITHOUT-LIST!-ERRORS
+                                                  .ATM UNMERGEABLE>)>
+                                          <ADD-LIST .ATM .NL-LIST>
+                                          <ADD-LIST .NEW-LIVE <REST ,.ATM>>
+                                          <COND (<==? .LIVE 0> <RETURN>)>)>
+                                   <SET TNO <+ .TNO 1>>
+                                   <SET MSK <LSH .MSK 1>>>)>
+                    <SET TEMP-OFFS <+ .TEMP-OFFS 32>>>
+               .LIVES>)>
+   T>
+
+<DEFINE OPTIMIZE-SETS (CODE:VECTOR)
+   <REPEAT ((I:FIX 1) (CODELEN:FIX <LENGTH .CODE>) INST ATM1 ATM2)
+      <SET INST <NTH .CODE .I>>
+      <COND (<AND <TYPE? .INST FORM>
+                 <NOT <LENGTH? .INST 2>>
+                 <==? <1 .INST> `SET>
+                 <TYPE? <SET ATM1 <2 .INST>> ATOM>
+                 <TYPE? <SET ATM2 <3 .INST>> ATOM>
+                 <NOT <IN-LIST? .ATM1 <REST ,.ATM2>>>>
+            <MAYBE-MERGE .CODE .ATM1 .ATM2>)>
+      <COND (<==? .I .CODELEN> <RETURN>)>
+      <SET I <+ .I 1>>>>
+
+<DEFINE MAYBE-MERGE (CODE:VECTOR ATM1:ATOM ATM2:ATOM)
+   <REPEAT WHOLE-THING ((I:FIX 1) (CODELEN:FIX <LENGTH .CODE>) INST)
+      <SET INST <NTH .CODE .I>>
+      <COND (<AND <TYPE? .INST FORM> 
+                 <NOT <EMPTY? .INST>>
+                 <OR <==? <1 .INST> `TEMP>
+                     <==? <1 .INST> `MAKTUP>>>
+            <REPEAT ((LONG:LIST <REST .INST>) ONE-LONG)
+               <COND (<OR <EMPTY? .LONG>
+                          <==? <SET ONE-LONG <1 .LONG>> =>>
+                      <RETURN>)
+                     (<==? <ATOM-PART .ONE-LONG> .ATM1>
+                      <PROBABLY-MERGE .CODE .LONG .ATM1 .ATM2>
+                      <RETURN T .WHOLE-THING>)
+                     (<==? <ATOM-PART .ONE-LONG> .ATM2>
+                      <PROBABLY-MERGE .CODE .LONG .ATM2 .ATM1>
+                      <RETURN T .WHOLE-THING>)>
+               <SET LONG <REST .LONG>>>)>
+      <COND (<==? .I .CODELEN> <RETURN>)>
+      <SET I <+ .I 1>>>
+   T>
+
+<DEFINE PROBABLY-MERGE (CODE:VECTOR LONG:LIST NEW-TEMP:ATOM OLD-TEMP:ATOM
+                       "AUX" (OUTCHAN:CHANNEL .OUTCHAN))
+   <REPEAT ((MEDIUM:LIST .LONG) (SHORT:LIST <REST .LONG>) ONE-SHORT)
+      <COND (<OR <EMPTY? .SHORT> <==? <SET ONE-SHORT <1 .SHORT>> =>> <RETURN>)
+           (<==? <ATOM-PART .ONE-SHORT> .OLD-TEMP>
+            <COND (<MERGEABLE? <1 .LONG> .ONE-SHORT>
+                   <COND (<TYPE? .ONE-SHORT LIST>
+                          <1 .LONG <1 .ONE-SHORT <1 .LONG>>>)>
+                   <PUTREST .MEDIUM <REST .SHORT>>
+                   <COND (,DEBUG-DEATH
+                          <PRINTSTRING "Merging " .OUTCHAN>
+                          <PRIN1 .OLD-TEMP .OUTCHAN>
+                          <PRINTSTRING " with " .OUTCHAN>
+                          <PRIN1 .NEW-TEMP .OUTCHAN>
+                          <CRLF .OUTCHAN>)>
+                   <UNMERGEABLE .NEW-TEMP <REST ,.OLD-TEMP>>
+                   <PERFORM-MERGE .CODE .NEW-TEMP .OLD-TEMP>)>
+            <RETURN>)>
+      <SET SHORT <REST <SET MEDIUM .SHORT>>>>
+   T>
+
+<DEFINE OPTIMIZE-TEMPS (CODE:VECTOR)
+   <REPEAT ((I:FIX 1) (CODELEN:FIX <LENGTH .CODE>) INST OP)
+      <SET INST <NTH .CODE .I>>
+      <COND (<AND <TYPE? .INST FORM> 
+                 <NOT <EMPTY? .INST>>>
+            <SET OP <1 .INST>>
+            <COND (<OR <==? .OP `TEMP> <==? .OP `MAKTUP>>
+                   <REALLY-OPTIMIZE .CODE <REST .INST>>)>)>
+      <COND (<==? .I .CODELEN> <RETURN>)>
+      <SET I <+ .I 1>>>>
+
+<DEFINE REALLY-OPTIMIZE (CODE:VECTOR TEMPS:LIST 
+                        "AUX" (OUTCHAN:CHANNEL .OUTCHAN)
+                        OLD-TEMP:ATOM NEW-TEMP:ATOM)
+   <COND (<NOT <EMPTY? .TEMPS>>
+         <REPEAT ((LONG:LIST .TEMPS) ONE-LONG)
+            <COND (<OR <EMPTY? .LONG> <==? <SET ONE-LONG <1 .LONG>> =>> <RETURN>)>
+            <REPEAT ((MEDIUM:LIST .LONG) (SHORT:LIST <REST .MEDIUM>) ONE-SHORT)
+               <COND (<OR <EMPTY? .SHORT> <==? <SET ONE-SHORT <1 .SHORT>> =>>
+                      <RETURN>)>
+               <COND (<MERGEABLE? .ONE-LONG .ONE-SHORT>
+                      <SET NEW-TEMP <ATOM-PART .ONE-LONG>>
+                      <SET OLD-TEMP <ATOM-PART .ONE-SHORT>>
+                      <COND (<TYPE? .ONE-SHORT LIST>
+                             <1 .LONG <1 .ONE-SHORT .ONE-LONG>>)>
+                      <PUTREST .MEDIUM <SET SHORT <REST .SHORT>>>
+                      <COND (,DEBUG-DEATH
+                             <PRINTSTRING "Merging " .OUTCHAN>
+                             <PRIN1 .OLD-TEMP .OUTCHAN>
+                             <PRINTSTRING " with " .OUTCHAN>
+                             <PRIN1 .NEW-TEMP .OUTCHAN>
+                             <CRLF .OUTCHAN>)>
+                      <UNMERGEABLE .NEW-TEMP <REST ,.OLD-TEMP>>
+                      <PERFORM-MERGE .CODE .NEW-TEMP .OLD-TEMP>)
+                     (ELSE
+                      <SET SHORT <REST <SET MEDIUM .SHORT>>>)>>
+            <SET LONG <REST .LONG>>>)>>          
+         
+<DEFINE MERGEABLE? (TEMP1:<OR ATOM ADECL LIST> TEMP2:<OR ATOM ADECL LIST>)
+   <AND <==? <DECL-PART .TEMP1> <DECL-PART .TEMP2>>
+       <NOT <AND <TYPE? .TEMP1 LIST> <TYPE? .TEMP2 LIST>>>
+       <NOT <IN-LIST? <ATOM-PART .TEMP1> <REST ,<ATOM-PART .TEMP2>>>>>>
+
+<DEFINE OPTIMIZE-TEMPS/BASH-DECLS (CODE:VECTOR)
+   <REPEAT ((I:FIX 1) (CODELEN:FIX <LENGTH .CODE>) INST OP)
+      <SET INST <NTH .CODE .I>>
+      <COND (<AND <TYPE? .INST FORM> 
+                 <NOT <EMPTY? .INST>>>
+            <SET OP <1 .INST>>
+            <COND (<OR <==? .OP `TEMP> <==? .OP `MAKTUP>>
+                   <REALLY-OPTIMIZE/BASH-DECLS .CODE <REST .INST>>)>)>
+      <COND (<==? .I .CODELEN> <RETURN>)>
+      <SET I <+ .I 1>>>>
+
+<DEFINE REALLY-OPTIMIZE/BASH-DECLS (CODE:VECTOR TEMPS:LIST 
+                                   "AUX" (OUTCHAN:CHANNEL .OUTCHAN)
+                                   OLD-TEMP:ATOM NEW-TEMP:ATOM)
+   <COND (<NOT <EMPTY? .TEMPS>>
+         <REPEAT ((LONG:LIST .TEMPS) ONE-LONG)
+            <COND (<OR <EMPTY? .LONG> <==? <SET ONE-LONG <1 .LONG>> =>> 
+                   <RETURN>)>
+            <REPEAT ((MEDIUM:LIST .LONG) (SHORT:LIST <REST .MEDIUM>) ONE-SHORT)
+               <COND (<OR <EMPTY? .SHORT> <==? <SET ONE-SHORT <1 .SHORT>> =>>
+                      <RETURN>)>
+               <COND (<MERGEABLE?/BASH-DECLS .ONE-LONG .ONE-SHORT>
+                      <SET NEW-TEMP <ATOM-PART .ONE-LONG>>
+                      <SET OLD-TEMP <ATOM-PART .ONE-SHORT>>
+                      <COND (<AND <DECL-PART .ONE-LONG>
+                                  <N==? <DECL-PART .ONE-LONG> 
+                                        <DECL-PART .ONE-SHORT>>>
+                             <COND (<TYPE? .ONE-LONG ADECL>
+                                    <1 .LONG <SET ONE-LONG <1 .ONE-LONG>>>)
+                                   (<TYPE? .ONE-LONG LIST>
+                                    <1 .ONE-LONG <1 <1 .ONE-LONG>>>)>)>
+                      <COND (<TYPE? .ONE-SHORT LIST>
+                             <1 .LONG <1 .ONE-SHORT .ONE-LONG>>)>
+                      <PUTREST .MEDIUM <SET SHORT <REST .SHORT>>>
+                      <COND (,DEBUG-DEATH
+                             <PRINTSTRING "Merging " .OUTCHAN>
+                             <PRIN1 .OLD-TEMP .OUTCHAN>
+                             <PRINTSTRING " with " .OUTCHAN>
+                             <PRIN1 .NEW-TEMP .OUTCHAN>
+                             <CRLF .OUTCHAN>)>
+                      <UNMERGEABLE .NEW-TEMP <REST ,.OLD-TEMP>>
+                      <PERFORM-MERGE .CODE .NEW-TEMP .OLD-TEMP>)
+                     (ELSE
+                      <SET SHORT <REST <SET MEDIUM .SHORT>>>)>>
+            <SET LONG <REST .LONG>>>)>>
+
+<DEFINE MERGEABLE?/BASH-DECLS (TEMP1:<OR ATOM ADECL LIST> 
+                              TEMP2:<OR ATOM ADECL LIST>)
+   <AND <NOT <AND <TYPE? .TEMP1 LIST> <TYPE? .TEMP2 LIST>>>
+       <NOT <IN-LIST? <ATOM-PART .TEMP1> <REST ,<ATOM-PART .TEMP2>>>>>>
+
+<DEFINE PERFORM-MERGE (CODE:VECTOR NEW-TEMP:ATOM OLD-TEMP:ATOM)
+   <MAPF %<>
+        <FUNCTION (INST "AUX" OP L ASSIGN)
+           <COND (<TYPE? .INST BRANCH>
+                  <COND (<IN-LIST? .OLD-TEMP <B-LIVES .INST>>
+                         <REM-LIST .OLD-TEMP <B-LIVES .INST>>
+                         <ADD-LIST .NEW-TEMP <B-LIVES .INST>>)>
+                  <SET INST <B-INST .INST>>)
+                 (<TYPE? .INST LABEL>
+                  <COND (<SET ASSIGN <L-ASSIGN .INST>>
+                         <MAPF <>
+                               <FUNCTION (LL:!<LIST ATOM FIX>)
+                                    <COND (<==? <1 .LL> .OLD-TEMP>
+                                           <PUT .LL 1 .NEW-TEMP>
+                                           <MAPLEAVE>)>>
+                               .ASSIGN>)>
+                  <SET INST <L-INST .INST>>)>
+           <COND (<AND <TYPE? .INST FORM> <NOT <EMPTY? .INST>>>
+                  <SET OP <1 .INST>>
+                  <COND (<==? .OP `LOOP>
+                         <MAPF %<>
+                               <FUNCTION (L) 
+                                  <REPLACE-ATOM .L .NEW-TEMP .OLD-TEMP>>
+                               <REST .INST>>)
+                        (<==? .OP `ICALL>
+                         <COND (<G=? <LENGTH .INST> 3>
+                                <REPLACE-ATOM <REST .INST 3>
+                                              .NEW-TEMP
+                                              .OLD-TEMP>)>)
+                        (<==? .OP `CHTYPE>
+                         <REPLACE-ATOM <REST .INST> .NEW-TEMP .OLD-TEMP>
+                         <MAPF %<>
+                               <FUNCTION (I)
+                                  <COND (<AND <TYPE? .I FORM>
+                                              <NOT <LENGTH? .I 1>>
+                                              <==? <1 .I> `TYPE>
+                                              <==? <2 .I> .OLD-TEMP>>
+                                         <2 .I .NEW-TEMP>)>>
+                               <REST .INST>>)
+                        (ELSE
+                         <REPLACE-ATOM <REST .INST> .NEW-TEMP .OLD-TEMP>)>)>>
+        .CODE>>
+
+<DEFINE REPLACE-ATOM (L:<PRIMTYPE LIST> NEW-ATOM:ATOM OLD-ATOM:ATOM)
+   <MAPR %<>
+        <FUNCTION (RL "AUX" (ONE <1 .RL>))
+           <COND (<==? .ONE .OLD-ATOM>
+                  <1 .RL .NEW-ATOM>)>>
+        .L>
+   T>
+
+<DEFINE PREPARE-DEADS-FROM-LABEL (CODE:VECTOR LABEL:LABEL)
+   <MAPF %<>
+        <FUNCTION (IN:FIX "AUX" (INST <NTH .CODE .IN>))
+           <COND (<TYPE? .INST BRANCH>
+                  <PREPARE-DEADS .CODE .IN <UVECTOR !<B-LIVES .INST>> -1>)>>
+        <L-INS .LABEL>>>
+
+<DEFINE PREPARE-DEADS (CODE:VECTOR I:FIX LIVE-TEMPS:UVECTOR
+                      FROM:FIX)
+   <REPEAT (INST INS:<LIST [REST FIX]>
+           ASSIGN:<OR FALSE <LIST [REST !<LIST ATOM FIX>]>>)
+      <SET INST <NTH .CODE .I>>
+      <COND (<TYPE? .INST LABEL>
+            <COND (<==? <L-LEVEL .INST> -1> <RETURN>)
+                  (ELSE <L-LEVEL .INST -1>)>
+            <SET ASSIGN <L-ASSIGN .INST>>
+            <SET INS <L-INS .INST>>
+            <COND (<EMPTY? .INS>
+                   <ERROR UNREACHABLE-CODE!-ERRORS PREPARE-DEADS>)
+                  (ELSE
+                   <MAPF %<>
+                         <FUNCTION (IN "AUX" (LV:UVECTOR <UVECTOR !.LIVE-TEMPS>))
+                            <COND (.ASSIGN
+                                   <MAPF <>
+                                         <FUNCTION (LL:!<LIST ATOM FIX>)
+                                              <COND (<==? <2 .LL> .IN>
+                                                     <REM-LIST <1 .LL> .LV>
+                                                     <MAPLEAVE>)>>
+                                         .ASSIGN>)>
+                            <PREPARE-DEADS .CODE .IN .LV .I>>
+                         <REST .INS>>
+                   <SET FROM .I>
+                   <SET I <1 .INS>>
+                   <COND (.ASSIGN
+                          <MAPF <>
+                                <FUNCTION (LL:!<LIST ATOM FIX>)
+                                     <COND (<==? <2 .LL> .I>
+                                            <REM-LIST <1 .LL> .LIVE-TEMPS>
+                                            <MAPLEAVE>)>>
+                                .ASSIGN>)>)>)
+           (<TYPE? .INST BRANCH>
+            <SET LIVE-TEMPS 
+                 <MERGE-DEADS .LIVE-TEMPS .INST <==? .FROM <+ .I 1>>>>
+            <SET LIVE-TEMPS <UPDATE-DEADS <B-INST .INST> .LIVE-TEMPS>>
+            <SET FROM .I>
+            <SET I <- .I 1>>)
+           (ELSE       ;"had better be a form"
+            <SET LIVE-TEMPS <UPDATE-DEADS .INST .LIVE-TEMPS>>
+            <SET FROM .I>
+            <SET I <- .I 1>>)>
+      <COND (<0? .I> <RETURN>)>>>
+
+<DEFINE MERGE-DEADS (LIVES:UVECTOR BRANCH:BRANCH FALL?
+                    "AUX" B-LIVES:UVECTOR
+                    (ND1:UVECTOR <IUVECTOR ,UVSIZE 0>) 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."
+   <SET B-LIVES <B-LIVES .BRANCH>>
+   <MAPR <>
+        <FUNCTION (LP:UVECTOR BP:UVECTOR NDP:UVECTOR "AUX" L:FIX B:FIX)
+             <COND (<N==? <SET L <1 .LP>> <SET B <1 .BP>>>
+                    <PUT .LP 1 <ORB .L .B>>
+                    <PUT .NDP 1 <XORB .L .B>>)>>
+        .LIVES .B-LIVES .ND1>
+   <COND (.FALL?
+         <B-FALL-DEADS .BRANCH .ND1>)
+        (ELSE
+         <SET JD <B-JUMP-DEADS .BRANCH>>
+         <COND (.JD
+                <B-JUMP-DEADS .BRANCH <INTERSECT-UVS .ND1 .JD>>)
+               (ELSE
+                <B-JUMP-DEADS .BRANCH .ND1>)>)>
+   .LIVES>
+
+<DEFINE INTERSECT-UVS (U1:UVECTOR U2:UVECTOR "AUX" (U3:UVECTOR <IUVECTOR ,UVSIZE>))
+       <MAPR <>
+             <FUNCTION (UP1 UP2 UP3)
+                  <PUT .UP3 1 <ANDB <1 .UP1> <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."
+
+<DEFINE UPDATE-DEADS (INST:FORM LIVES:UVECTOR "AUX" SETTER OP TEM)
+   ;"Any time an atom is added to the list of LIVES, it must be declared
+     DEAD, unless it is also SET in the same instruction."
+   <COND (<NOT <EMPTY? .INST>>
+         <SET OP <1 .INST>>
+         <COND (<==? .OP `SET>
+                <SET SETTER <CHTYPE <2 .INST> ATOM>>
+                <COND (<NOT <REM-LIST? .SETTER .LIVES>>
+                       <SETG ANY-FLUSHED-INS T>
+                       <PUT .INST 2 <CHTYPE .SETTER DEAD-VAR>>)>
+                <COND (<TYPE? <3 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 2> .LIVES .SETTER>)>)
+               (<==? .OP `SETLR>
+                <SET SETTER <CHTYPE <2 .INST> ATOM>>
+                <COND (<NOT <REM-LIST? .SETTER .LIVES>>
+                       <SETG ANY-FLUSHED-INS T>
+                       <PUT .INST 2 <CHTYPE .SETTER DEAD-VAR>>)>
+                <COND (<TYPE? <3 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 2> .LIVES .SETTER>)>
+                <COND (<TYPE? <4 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 3> .LIVES .SETTER>)>)
+               (<==? .OP `SETRL>
+                <SET SETTER <CHTYPE <3 .INST> ATOM>>
+                <COND (<NOT <REM-LIST? .SETTER .LIVES>>
+                       <SETG ANY-FLUSHED-INS T>
+                       <PUT .INST 3 <CHTYPE .SETTER DEAD-VAR>>)>
+                <COND (<TYPE? <2 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 1> .LIVES .SETTER>)>
+                <COND (<TYPE? <4 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 3> .LIVES .SETTER>)>)
+               (<==? .OP `TEMP>
+                <MAPF %<>
+                      <FUNCTION (T)
+                         <COND (<TYPE? .T LIST>
+                                <REM-LIST <ATOM-PART .T> .LIVES>)>>
+                      <REST .INST>>)
+               (<==? .OP `MAKTUP>
+                <MAPF %<>
+                      <FUNCTION (T)
+                         <COND (<==? .T => <MAPLEAVE>)
+                               (<TYPE? .T LIST>
+                                <REM-LIST <ATOM-PART .T> .LIVES>)>>
+                      <REST .INST>>)
+               (<==? .OP `DISPATCH>
+                <COND (<TYPE? <2 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 1> .LIVES %<>>)>
+                <COND (<TYPE? <3 .INST> ATOM DEAD-VAR>
+                       <ADD-DEAD <REST .INST 2> .LIVES %<>>)>)
+               (<AND <N==? .OP `FCN>
+                     <N==? .OP `GFCN>
+                     <N==? .OP `OPT-DISPATCH>
+                     <N==? .OP `LOOP>
+                     <N==? .OP `END>
+                     <N==? .OP `ICALL>>
+                <SET TEM <MEMQ = <REST .INST>>>
+                <COND (.TEM 
+                       <SET SETTER <CHTYPE <2 .TEM> ATOM>>
+                       <COND (<N==? .SETTER `STACK>
+                              <COND (<AND <NOT <REM-LIST? .SETTER .LIVES>>
+                                          <N==? .OP `SCALL>
+                                          <N==? .OP `SYSOP>
+                                          <N==? .OP `SYSCALL>>
+                                     <SETG ANY-FLUSHED-INS T>
+                                     <PUT .TEM 2 <CHTYPE .SETTER DEAD-VAR>>)>)>)
+                      (ELSE <SET SETTER %<>>)>
+                <REPEAT ((RINST <REST .INST>) ONE)
+                   <COND (<EMPTY? .RINST> <RETURN>)>
+                   <SET ONE <1 .RINST>>
+                   <COND (<OR <==? .ONE =>
+                              <==? .ONE +>
+                              <==? .ONE ->>
+                          <SET RINST <REST .RINST 2>>)
+                         (<TYPE? .ONE ATOM DEAD-VAR>
+                          <ADD-DEAD .RINST .LIVES .SETTER>
+                          <SET RINST <REST .RINST>>)
+                         (<AND <==? .OP `CHTYPE>
+                               <TYPE? .ONE FORM>
+                               <NOT <LENGTH? .ONE 1>>
+                               <==? <1 .ONE> `TYPE>
+                               <TYPE? <2 .ONE> ATOM>>
+                          <ADD-DEAD <REST .ONE> .LIVES .SETTER>
+                          <SET RINST <REST .RINST>>)
+                         (ELSE
+                          <SET RINST <REST .RINST>>)>>)>)>
+   .LIVES>
+
+<DEFINE ADD-DEAD (RINST:<LIST <OR ATOM DEAD-VAR>> L:UVECTOR
+                 SETTER:<OR ATOM FALSE>
+                 "AUX" (ATM:ATOM <CHTYPE <1 .RINST> ATOM>))
+   <COND (<AND <ADD-LIST? .ATM .L> <N==? .ATM .SETTER>>
+         <1 .RINST <CHTYPE .ATM DEAD-VAR>>)>>
+
+<DEFINE INSERT-DEADS (CODE:LIST VCODE:VECTOR "AUX" (RCODE:LIST .CODE))
+   <MAPF %<>
+        <FUNCTION (INST "AUX" DEADS:LIST FALL-DEADS:LIST JUMP-DEADS:LIST OP
+                              TMPL:<OR FALSE LIST> BJL:<OR FALSE UVECTOR>)
+           <COND (<TYPE? .INST BRANCH>
+                  <SET DEADS <FIND-DEADS <B-INST .INST>>>
+                  <SET FALL-DEADS <UV-TO-L <B-FALL-DEADS .INST>>>
+                  <SET BJL <B-JUMP-DEADS .INST>>
+                  <COND (.BJL
+                         <SET JUMP-DEADS <UV-TO-L .BJL>>)
+                        (ELSE <SET JUMP-DEADS ()>)>
+                  <SET INST <B-INST .INST>:FORM>
+                  ;"BEGIN TEMPORARY HACK"
+                  ;<SET FALL-DEADS <INTERSECT-LISTS .FALL-DEADS .JUMP-DEADS>>
+                  ;<SET JUMP-DEADS ()>
+                  ;"END TEMOPRARY HACK"
+                  <COND (<NOT <EMPTY? .JUMP-DEADS>>
+                         <PUTREST <REST .INST <- <LENGTH .INST> 1>>
+                                  ((`DEAD-JUMP !.JUMP-DEADS))>)>
+                  <COND (<NOT <EMPTY? .FALL-DEADS>>
+                         <PUTREST <REST .INST <- <LENGTH .INST> 1>>
+                                  ((`DEAD-FALL !.FALL-DEADS))>)>
+                  <COND (<NOT <EMPTY? .DEADS>>
+                         <PUTREST .RCODE 
+                                  (<CHTYPE (`DEAD !.DEADS) FORM> 
+                                   !<REST .RCODE>)>
+                         <SET RCODE <REST .RCODE>>)>
+                  <SET RCODE <REST <SET CODE .RCODE>>>)
+                 (<TYPE? .INST FORM>
+                  <COND (<AND <NOT <EMPTY? .INST>>
+                              <OR <AND <==? <SET OP <1 .INST>> `SET>
+                                       <OR <==? <2 .INST> <3 .INST>>
+                                           <TYPE? <2 .INST> DEAD-VAR>>>
+                                  <AND <==? .OP `SETLR>
+                                       <TYPE? <2 .INST> DEAD-VAR>>
+                                  <AND <==? .OP `SETRL>
+                                       <TYPE? <3 .INST> DEAD-VAR>>
+                                  <AND <SET TMPL <MEMQ = .INST>>
+                                       <TYPE? <2 .TMPL> DEAD-VAR>>>
+                              <SETG ANY-FLUSHED-INS T>
+                              <COND (<OR <==? .OP `CALL> <==? .OP `ACALL>>
+                                     <PUTREST <REST .INST <- <LENGTH .INST>
+                                                             <LENGTH .TMPL>
+                                                             1>> ()>
+                                     <>)
+                                    (<OR <==? .OP `SCALL> <==? .OP `SYSOP>
+                                         <==? .OP `SYSCALL>>
+                                     <PUT .TMPL 2 <CHTYPE <2 .TMPL> ATOM>>
+                                     <>)
+                                    (<==? .OP `POP>
+                                     <PUT .RCODE 1 '<`ADJ -1>>
+                                     <SET RCODE <REST <SET CODE .RCODE>>>
+                                     T)
+                                    (ELSE
+                                     <PUTREST .CODE
+                                              <SET RCODE <REST .RCODE>>>
+                                     T)>>)
+                        (ELSE
+                         <SET DEADS <FIND-DEADS .INST>>
+                         <COND (<NOT <EMPTY? .DEADS>>
+                                <PUTREST .RCODE
+                                         (<FORM `DEAD !.DEADS>
+                                          !<REST .RCODE>)>
+                                <SET RCODE <REST .RCODE>>)>
+                         <SET RCODE <REST <SET CODE .RCODE>>>)>)
+                 (<NOT <AND <TYPE? .INST LABEL>
+                            <TYPE? <SET INST <L-INST .INST>> FORM>
+                            <NOT <EMPTY? .INST>>
+                            <==? <1 .INST> `ENDIF>>>
+                  <SET RCODE <REST <SET CODE .RCODE>>>)>>
+        .VCODE>>
+
+<DEFINE FIND-DEADS (INST:FORM "AUX" OP (PASSED=?:<OR FALSE <LIST ANY>> <>))
+   <COND (<NOT <EMPTY? .INST>>
+         <SET OP <1 .INST>>
+         <MAPR ,LIST
+               <FUNCTION (RINST "AUX" (ONE <1 .RINST>))
+                  <COND (<==? .ONE =>
+                         <SET PASSED=? .RINST>
+                         <MAPRET>)
+                        (<AND .PASSED=?
+                              <OR <==? .OP `CALL> <==? .OP `ACALL>>
+                              <TYPE? .ONE DEAD-VAR>>
+                         <PUTREST <REST .INST
+                                        <- <LENGTH .INST>
+                                           <LENGTH .PASSED=?>
+                                           1>>
+                                  ()>
+                         <MAPSTOP>)
+                        (<TYPE? .ONE DEAD-VAR>
+                         <SET ONE <CHTYPE .ONE ATOM>>
+                         <1 .RINST .ONE>
+                         <MAPRET .ONE>)
+                        (<AND <TYPE? .ONE FORM>
+                              <==? .OP `CHTYPE>
+                              <NOT <LENGTH? .ONE 1>>
+                              <==? <1 .ONE> `TYPE>
+                              <TYPE? <2 .ONE> DEAD-VAR>>
+                         <2 .ONE <CHTYPE <2 .ONE> ATOM>>
+                         <MAPRET <2 .ONE>>)
+                        (ELSE <MAPRET>)>>
+               <REST .INST>>)
+        (ELSE ())>>
+
+<DEFINE UV-TO-L (UV:UVECTOR "AUX" (L:LIST ()) (TEMP-OFFS:FIX 0))
+       <MAPF <>
+             <FUNCTION (WD)
+                  <COND (<N==? .WD 0>
+                         <REPEAT ((TNO:FIX <+ .TEMP-OFFS 1>)
+                                  (MSK:FIX 1))
+                                 <COND (<N==? <ANDB .MSK .WD> 0>
+                                        <SET L (<NTH ,NAME-UV .TNO> !.L)>
+                                        <SET WD <XORB .WD .MSK>>
+                                        <COND (<==? .WD 0> <RETURN>)>)>
+                                 <SET TNO <+ .TNO 1>>
+                                 <SET MSK <LSH .MSK 1>>>)>
+                  <SET TEMP-OFFS <+ .TEMP-OFFS 32>>>
+             .UV>
+       .L> 
+
+<ENDPACKAGE>