[project @ 2001-09-26 15:11:50 by simonpj]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgCase.lhs
index 9eb6b22..43147e5 100644 (file)
@@ -1,7 +1,7 @@
 %
 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
-% $Id: CgCase.lhs,v 1.32 1999/06/22 07:59:59 simonpj Exp $
+% $Id: CgCase.lhs,v 1.53 2001/09/26 15:11:50 simonpj Exp $
 %
 %********************************************************
 %*                                                     *
@@ -25,15 +25,14 @@ import AbsCUtils    ( mkAbstractCs, mkAbsCStmts, mkAlgAltsCSwitch,
                          getAmodeRep, nonemptyAbsC
                        )
 import CgUpdate                ( reserveSeqFrame )
-import CgBindery       ( getVolatileRegs, getArgAmodes, getArgAmode,
+import CgBindery       ( getVolatileRegs, getArgAmodes,
                          bindNewToReg, bindNewToTemp,
-                         bindNewPrimToAmode,
-                         rebindToStack, getCAddrMode,
-                         getCAddrModeAndInfo, getCAddrModeIfVolatile,
+                         bindNewPrimToAmode, getCAddrModeAndInfo,
+                         rebindToStack, getCAddrMode, getCAddrModeIfVolatile,
                          buildContLivenessMask, nukeDeadBindings,
                        )
 import CgCon           ( bindConArgs, bindUnboxedTupleComponents )
-import CgHeapery       ( altHeapCheck, yield )
+import CgHeapery       ( altHeapCheck )
 import CgRetConv       ( dataReturnConvPrim, ctrlReturnConvAlg,
                          CtrlReturnConvention(..)
                        )
@@ -41,31 +40,23 @@ import CgStackery   ( allocPrimStack, allocStackTop,
                          deAllocStackTop, freeStackSlots, dataStackSlots
                        )
 import CgTailCall      ( tailCallFun )
-import CgUsages                ( getSpRelOffset, getRealSp )
-import CLabel          ( CLabel, mkVecTblLabel, mkReturnPtLabel, 
-                         mkDefaultLabel, mkAltLabel, mkReturnInfoLabel,
-                         mkErrorStdEntryLabel, mkClosureTblLabel
+import CgUsages                ( getSpRelOffset )
+import CLabel          ( mkVecTblLabel, mkClosureTblLabel,
+                         mkDefaultLabel, mkAltLabel, mkReturnInfoLabel
                        )
 import ClosureInfo     ( mkLFArgument )
-import CmdLineOpts     ( opt_SccProfilingOn, opt_GranMacros )
-import CostCentre      ( CostCentre )
-import CoreSyn         ( isDeadBinder )
-import Id              ( Id, idPrimRep )
-import DataCon         ( DataCon, dataConTag, fIRST_TAG, ConTag,
-                         isUnboxedTupleCon, dataConType )
+import CmdLineOpts     ( opt_SccProfilingOn )
+import Id              ( Id, idPrimRep, isDeadBinder )
+import DataCon         ( DataCon, dataConTag, fIRST_TAG, ConTag )
 import VarSet          ( varSetElems )
-import Const           ( Con(..), Literal )
+import Literal         ( Literal )
 import PrimOp          ( primOpOutOfLine, PrimOp(..) )
 import PrimRep         ( getPrimRepSize, retPrimRepSize, PrimRep(..)
                        )
-import TyCon           ( TyCon, isEnumerationTyCon, isUnboxedTupleTyCon,
-                         isNewTyCon, isAlgTyCon, isFunTyCon, isPrimTyCon,
-                         tyConDataCons, tyConFamilySize )
-import Type            ( Type, typePrimRep, splitAlgTyConApp, 
-                         splitTyConApp_maybe, splitRepTyConApp_maybe )
-import Unique           ( Unique, Uniquable(..), mkBuiltinUnique )
+import TyCon           ( isEnumerationTyCon, isUnboxedTupleTyCon, tyConPrimRep )
+import Unique           ( Unique, Uniquable(..), newTagUnique )
 import Maybes          ( maybeToBool )
-import Util
+import Util            ( only )
 import Outputable
 \end{code}
 
@@ -144,31 +135,40 @@ which generates no code for the primop, unless x is used in the
 alternatives (in which case we lookup the tag in the relevant closure
 table to get the closure).
 
+Being a bit short of uniques for temporary variables here, we use
+newTagUnique to generate a new unique from the case binder.  The case
+binder's unique will presumably have the 'c' tag (generated by
+CoreToStg), so we just change its tag to 'C' (for 'case') to ensure it
+doesn't clash with anything else.
+
 \begin{code}
-cgCase (StgCon (PrimOp op) args res_ty)
-         live_in_whole_case live_in_alts bndr srt (StgAlgAlts ty alts deflt)
+cgCase (StgOpApp op args _)
+       live_in_whole_case live_in_alts bndr srt (StgAlgAlts (Just tycon) alts deflt)
   | isEnumerationTyCon tycon
   = getArgAmodes args `thenFC` \ arg_amodes ->
 
-    let tag_amode = case op of 
-                       TagToEnumOp -> only arg_amodes
-                       _ -> CTemp (mkBuiltinUnique 1) IntRep
-
-       closure = CTableEntry (CLbl (mkClosureTblLabel tycon) PtrRep) tag_amode PtrRep
-    in
-
     case op of {
-       TagToEnumOp -> nopC;  -- no code!
+       StgPrimOp TagToEnumOp   -- No code!
+          -> returnFC (only arg_amodes) ;
+
+       _  ->           -- Perform the operation
+             let
+               tag_amode = CTemp (newTagUnique (getUnique bndr) 'C') IntRep
+             in
+             getVolatileRegs live_in_alts                      `thenFC` \ vol_regs ->
+             absC (COpStmt [tag_amode] op arg_amodes vol_regs) `thenC`
+                               -- NB: no liveness arg
+             returnFC tag_amode
+    }                                          `thenFC` \ tag_amode ->
 
-       _ ->    -- Perform the operation
-              getVolatileRegs live_in_alts     `thenFC` \ vol_regs ->
-
-              absC (COpStmt [tag_amode] op
-                arg_amodes -- note: no liveness arg
-                vol_regs)
-    }                                          `thenC`
+    let
+       closure = CVal (CIndex (CLbl (mkClosureTblLabel tycon) PtrRep) 
+                              tag_amode PtrRep) 
+                      PtrRep
+    in
 
-       -- bind the default binder if necessary
+       -- Bind the default binder if necessary
+       -- The deadness info is set by StgVarInfo
     (if (isDeadBinder bndr)
        then nopC
        else bindNewToTemp bndr                 `thenFC` \ bndr_amode ->
@@ -176,39 +176,44 @@ cgCase (StgCon (PrimOp op) args res_ty)
                                                `thenC`
 
        -- compile the alts
-    cgAlgAlts NoGC uniq Nothing{-cc_slot-} False{-no semi-tagging-}
+    cgAlgAlts NoGC (getUnique bndr) Nothing{-cc_slot-} False{-no semi-tagging-}
                False{-not poly case-} alts deflt
                 False{-don't emit yield-}      `thenFC` \ (tagged_alts, deflt_c) ->
 
        -- Do the switch
     absC (mkAlgAltsCSwitch tag_amode tagged_alts deflt_c)
-
-   where
-       (Just (tycon,_)) = splitTyConApp_maybe res_ty
-       uniq = getUnique bndr
 \end{code}
 
 Special case #2: inline PrimOps.
 
 \begin{code}
-cgCase (StgCon (PrimOp op) args res_ty) 
-       live_in_whole_case live_in_alts bndr srt alts
-  | not (primOpOutOfLine op)
+cgCase (StgOpApp op@(StgPrimOp primop) args _) 
+       live_in_whole_case live_in_alts bndr srt alts
+  | not (primOpOutOfLine primop)
   =
        -- Get amodes for the arguments and results
     getArgAmodes args                  `thenFC` \ arg_amodes ->
-    let
-       result_amodes = getPrimAppResultAmodes (getUnique bndr) alts
-    in
-       -- Perform the operation
     getVolatileRegs live_in_alts        `thenFC` \ vol_regs ->
 
-    absC (COpStmt result_amodes op
-                arg_amodes -- note: no liveness arg
-                vol_regs)              `thenC`
-
-       -- Scrutinise the result
-    cgInlineAlts bndr alts
+    case alts of 
+      StgPrimAlts tycon alts deflt     -- PRIMITIVE ALTS
+       -> absC (COpStmt [CTemp (getUnique bndr) (tyConPrimRep tycon)]
+                        op
+                        arg_amodes     -- note: no liveness arg
+                        vol_regs)              `thenC`
+          cgPrimInlineAlts bndr tycon alts deflt
+
+      StgAlgAlts (Just tycon) [(_, args, _, rhs)] StgNoDefault 
+       |  isUnboxedTupleTyCon tycon    -- UNBOXED TUPLE ALTS
+       ->      -- no heap check, no yield, just get in there and do it.
+          absC (COpStmt [ CTemp (getUnique arg) (idPrimRep arg) | arg <- args ]
+                        op
+                        arg_amodes      -- note: no liveness arg
+                        vol_regs)              `thenC`
+          mapFCs bindNewToTemp args `thenFC` \ _ ->
+          cgExpr rhs
+
+      other -> pprPanic "cgCase: case of primop has strange alts" (pprStgAlts alts)
 \end{code}
 
 TODO: Case-of-case of primop can probably be done inline too (but
@@ -225,7 +230,7 @@ eliminate a heap check altogether.
 
 \begin{code}
 cgCase (StgApp v []) live_in_whole_case live_in_alts bndr srt
-                       (StgPrimAlts ty alts deflt)
+                       (StgPrimAlts tycon alts deflt)
 
   = 
     getCAddrMode v             `thenFC` \amode ->
@@ -248,12 +253,11 @@ we can reuse/trim the stack slot holding the variable (if it is in one).
 
 \begin{code}
 cgCase (StgApp fun args)
-       live_in_whole_case live_in_alts bndr srt alts@(StgAlgAlts ty _ _)
-  =
-    getCAddrModeAndInfo fun            `thenFC` \ (fun_amode, lf_info) ->
-    getArgAmodes args                  `thenFC` \ arg_amodes ->
+       live_in_whole_case live_in_alts bndr srt alts
+  = getCAddrModeAndInfo fun                    `thenFC` \ (fun', fun_amode, lf_info) ->
+    getArgAmodes args                          `thenFC` \ arg_amodes ->
 
-       -- Squish the environment
+       -- Squish the environment
     nukeDeadBindings live_in_alts      `thenC`
     saveVolatileVarsAndRegs live_in_alts
                        `thenFC` \ (save_assts, alts_eob_info, maybe_cc_slot) ->
@@ -261,24 +265,12 @@ cgCase (StgApp fun args)
     allocStackTop retPrimRepSize       `thenFC` \_ ->
 
     forkEval alts_eob_info nopC (
-               deAllocStackTop retPrimRepSize `thenFC` \_ ->
-               cgEvalAlts maybe_cc_slot bndr srt alts) 
+            deAllocStackTop retPrimRepSize `thenFC` \_ ->
+            cgEvalAlts maybe_cc_slot bndr srt alts) 
                                         `thenFC` \ scrut_eob_info ->
 
-    let real_scrut_eob_info =
-               if not_con_ty
-                       then reserveSeqFrame scrut_eob_info
-                       else scrut_eob_info
-    in
-
-    setEndOfBlockInfo real_scrut_eob_info (
-      tailCallFun fun fun_amode lf_info arg_amodes save_assts
-      )
-
-  where
-     not_con_ty = case (getScrutineeTyCon ty) of
-                       Just _ -> False
-                       other  -> True
+    setEndOfBlockInfo (maybeReserveSeqFrame alts scrut_eob_info)       $
+    tailCallFun fun' fun_amode lf_info arg_amodes save_assts
 \end{code}
 
 Note about return addresses: we *always* push a return address, even
@@ -307,26 +299,15 @@ cgCase expr live_in_whole_case live_in_alts bndr srt alts
 
     -- generate code for the alts
     forkEval alts_eob_info
-       (
-        nukeDeadBindings live_in_alts `thenC` 
+       (nukeDeadBindings live_in_alts `thenC` 
         allocStackTop retPrimRepSize   -- space for retn address 
         `thenFC` \_ -> nopC
         )
        (deAllocStackTop retPrimRepSize `thenFC` \_ ->
         cgEvalAlts maybe_cc_slot bndr srt alts) `thenFC` \ scrut_eob_info ->
 
-    let real_scrut_eob_info =
-               if not_con_ty
-                       then reserveSeqFrame scrut_eob_info
-                       else scrut_eob_info
-    in
-
-    setEndOfBlockInfo real_scrut_eob_info (cgExpr expr)
-
-  where
-     not_con_ty = case (getScrutineeTyCon (alts_ty alts)) of
-                       Just _ -> False
-                       other  -> True
+    setEndOfBlockInfo (maybeReserveSeqFrame alts scrut_eob_info) $
+    cgExpr expr
 \end{code}
 
 There's a lot of machinery going on behind the scenes to manage the
@@ -364,52 +345,11 @@ don't follow the layout of closures when we're profiling.  The CCS
 could be anywhere within the record).
 
 \begin{code}
-alts_ty (StgAlgAlts ty _ _) = ty
-alts_ty (StgPrimAlts ty _ _) = ty
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[CgCase-primops]{Primitive applications}
-%*                                                                     *
-%************************************************************************
-
-Get result amodes for a primitive operation, in the case wher GC can't happen.
-The  amodes are returned in canonical order, ready for the prim-op!
-
-       Alg case: temporaries named as in the alternatives,
-                 plus (CTemp u) for the tag (if needed)
-       Prim case: (CTemp u)
-
-This is all disgusting, because these amodes must be consistent with those
-invented by CgAlgAlts.
-
-\begin{code}
-getPrimAppResultAmodes
-       :: Unique
-       -> StgCaseAlts
-       -> [CAddrMode]
-
-getPrimAppResultAmodes uniq (StgAlgAlts ty alts some_default)
-
-  | isUnboxedTupleTyCon tycon = 
-       case alts of 
-           [(con, args, use_mask, rhs)] -> 
-               [ CTemp (getUnique arg) (idPrimRep arg) | arg <- args ]
-           _ -> panic "getPrimAppResultAmodes: case of unboxed tuple has multiple branches"
-
-  | otherwise = panic ("getPrimAppResultAmodes: case of primop has strange type: " ++ showSDoc (ppr ty))
-
-  where (tycon, _, _) = splitAlgTyConApp ty
-
--- The situation is simpler for primitive results, because there is only
--- one!
-
-getPrimAppResultAmodes uniq (StgPrimAlts ty _ _)
-  = [CTemp uniq (typePrimRep ty)]
+-- We need to reserve a seq frame for a polymorphic case
+maybeReserveSeqFrame (StgAlgAlts Nothing _ _) scrut_eob_info = reserveSeqFrame scrut_eob_info
+maybeReserveSeqFrame other                   scrut_eob_info = scrut_eob_info
 \end{code}
 
-
 %************************************************************************
 %*                                                                     *
 \subsection[CgCase-alts]{Alternatives}
@@ -438,7 +378,7 @@ cgEvalAlts cc_slot bndr srt alts
     case alts of
 
       -- algebraic alts ...
-      (StgAlgAlts ty alts deflt) ->
+      StgAlgAlts maybe_tycon alts deflt ->
 
           -- bind the default binder (it covers all the alternatives)
        bindNewToReg bndr node mkLFArgument      `thenC`
@@ -452,9 +392,8 @@ cgEvalAlts cc_slot bndr srt alts
        --
        -- which is worse than having the alt code in the switch statement
 
-       let     tycon_info      = getScrutineeTyCon ty
-               is_alg          = maybeToBool tycon_info
-               Just spec_tycon = tycon_info
+       let     is_alg          = maybeToBool maybe_tycon
+               Just spec_tycon = maybe_tycon
        in
 
        -- deal with the unboxed tuple case
@@ -463,8 +402,8 @@ cgEvalAlts cc_slot bndr srt alts
                [alt] -> let lbl = mkReturnInfoLabel uniq in
                         cgUnboxedTupleAlt uniq cc_slot True alt
                                `thenFC` \ abs_c ->
-                        getSRTLabel `thenFC` \srt_label -> 
-                        absC (CRetDirect uniq abs_c (srt_label, srt) 
+                        getSRTInfo srt          `thenFC` \ srt_info -> 
+                        absC (CRetDirect uniq abs_c srt_info
                                        liveness_mask) `thenC`
                        returnFC (CaseAlts (CLbl lbl RetRep) Nothing)
                _ -> panic "cgEvalAlts: dodgy case of unboxed tuple type"
@@ -494,56 +433,30 @@ cgEvalAlts cc_slot bndr srt alts
        returnFC (CaseAlts return_vec semi_tagged_stuff)
 
       -- primitive alts...
-      (StgPrimAlts ty alts deflt) ->
+      StgPrimAlts tycon alts deflt ->
 
        -- Restore the cost centre
-       restoreCurrentCostCentre cc_slot        `thenFC` \ cc_restore ->
+       restoreCurrentCostCentre cc_slot                `thenFC` \ cc_restore ->
 
        -- Generate the switch
-       getAbsC (cgPrimEvalAlts bndr ty alts deflt)     `thenFC` \ abs_c ->
+       getAbsC (cgPrimEvalAlts bndr tycon alts deflt)  `thenFC` \ abs_c ->
 
        -- Generate the labelled block, starting with restore-cost-centre
-       getSRTLabel                                     `thenFC` \srt_label ->
+       getSRTInfo srt                                  `thenFC` \srt_info ->
        absC (CRetDirect uniq (cc_restore `mkAbsCStmts` abs_c) 
-                       (srt_label,srt) liveness_mask)  `thenC`
+                        srt_info liveness_mask)        `thenC`
 
        -- Return an amode for the block
        returnFC (CaseAlts (CLbl (mkReturnInfoLabel uniq) RetRep) Nothing)
 \end{code}
 
 
-\begin{code}
-cgInlineAlts :: Id
-            -> StgCaseAlts
-            -> Code
-\end{code}
-
 HWL comment on {\em GrAnSim\/}  (adding GRAN_YIELDs for context switch): If
 we  do  an inlining of the  case  no separate  functions  for returning are
 created, so we don't have to generate a GRAN_YIELD in that case.  This info
 must be  propagated  to cgAlgAltRhs (where the  GRAN_YIELD  macro might  be
 emitted). Hence, the new Bool arg to cgAlgAltRhs.
 
-First case: primitive op returns an unboxed tuple.
-
-\begin{code}
-cgInlineAlts bndr (StgAlgAlts ty [alt@(con,args,use_mask,rhs)] StgNoDefault)
-  | isUnboxedTupleCon con
-  = -- no heap check, no yield, just get in there and do it.
-    mapFCs bindNewToTemp args `thenFC` \ _ ->
-    cgExpr rhs
-
-  | otherwise
-  = panic "cgInlineAlts: single alternative, not an unboxed tuple"
-\end{code}
-
-Third (real) case: primitive result type.
-
-\begin{code}
-cgInlineAlts bndr (StgPrimAlts ty alts deflt)
-  = cgPrimInlineAlts bndr ty alts deflt
-\end{code}
-
 %************************************************************************
 %*                                                                     *
 \subsection[CgCase-alg-alts]{Algebraic alternatives}
@@ -596,9 +509,10 @@ cgAlgDefault gc_flag is_fun uniq cc_slot must_label_branch
   =    -- We have arranged that Node points to the thing
     restoreCurrentCostCentre cc_slot `thenFC` \restore_cc ->
     getAbsC (absC restore_cc `thenC`
-             (if opt_GranMacros && emit_yield
-                then yield [node] False
-                else absC AbsCNop)                            `thenC`     
+             -- HWL: maybe need yield here
+             --(if emit_yield
+             --   then yield [node] True
+             --   else absC AbsCNop)                            `thenC`     
             possibleHeapCheck gc_flag is_fun [node] [] Nothing (cgExpr rhs)
        -- Node is live, but doesn't need to point at the thing itself;
        -- it's ok for Node to point to an indirection or FETCH_ME
@@ -627,9 +541,10 @@ cgAlgAlt gc_flag uniq cc_slot must_label_branch
   = 
     restoreCurrentCostCentre cc_slot `thenFC` \restore_cc ->
     getAbsC (absC restore_cc `thenC`
-            (if opt_GranMacros && emit_yield
-               then yield [node] True          -- XXX live regs wrong
-               else absC AbsCNop)                               `thenC`     
+             -- HWL: maybe need yield here
+            -- (if emit_yield
+            --    then yield [node] True               -- XXX live regs wrong
+            --    else absC AbsCNop)                               `thenC`    
             (case gc_flag of
                NoGC        -> mapFCs bindNewToTemp args `thenFC` \_ -> nopC
                GCMayHappen -> bindConArgs con args
@@ -661,9 +576,10 @@ cgUnboxedTupleAlt lbl cc_slot emit_yield (con,args,use_mask,rhs)
         restoreCurrentCostCentre cc_slot `thenFC` \restore_cc ->
        absC restore_cc `thenC`
 
-       (if opt_GranMacros && emit_yield
-           then yield live_regs True           -- XXX live regs wrong?
-           else absC AbsCNop)                         `thenC`     
+        -- HWL: maybe need yield here
+       -- (if emit_yield
+       --    then yield live_regs True         -- XXX live regs wrong?
+       --    else absC AbsCNop)                         `thenC`     
        let 
              -- ToDo: could maybe use Nothing here if stack_res is False
              -- since the heap-check can just return to the top of the 
@@ -736,18 +652,19 @@ the maximum stack depth encountered down any branch.
 As usual, no binders in the alternatives are yet bound.
 
 \begin{code}
-cgPrimInlineAlts bndr ty alts deflt
+cgPrimInlineAlts bndr tycon alts deflt
   = cgPrimAltsWithDefault bndr NoGC (CTemp uniq kind) alts deflt []
   where
        uniq = getUnique bndr
-       kind = typePrimRep ty
+       kind = tyConPrimRep tycon
 
-cgPrimEvalAlts bndr ty alts deflt
+cgPrimEvalAlts bndr tycon alts deflt
   = cgPrimAltsWithDefault bndr GCMayHappen (CReg reg) alts deflt [reg]
   where
-       reg  = WARN( case kind of { PtrRep -> True; other -> False }, text "cgPrimEE" <+> ppr bndr <+> ppr ty  )
+       reg  = WARN( case kind of { PtrRep -> True; other -> False }, 
+                    text "cgPrimEE" <+> ppr bndr <+> ppr tycon  )
               dataReturnConvPrim kind
-       kind = typePrimRep ty
+       kind = tyConPrimRep tycon
 
 cgPrimAltsWithDefault bndr gc_flag scrutinee alts deflt regs
   =    -- first bind the default if necessary
@@ -867,7 +784,7 @@ restoreCurrentCostCentre (Just slot)
    freeStackSlots [slot]                        `thenC`
    returnFC (CCallProfCCMacro SLIT("RESTORE_CCCS") [CVal sp_rel CostCentreRep])
     -- we use the RESTORE_CCCS macro, rather than just
-    -- assigning into CurCostCentre, in case RESTORE_CCC
+    -- assigning into CurCostCentre, in case RESTORE_CCCS
     -- has some sanity-checking in it.
 \end{code}
 
@@ -890,17 +807,15 @@ mkReturnVector :: Unique
               -> FCode CAddrMode
 
 mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness ret_conv
-  = getSRTLabel `thenFC` \srt_label ->
+  = getSRTInfo srt             `thenFC` \ srt_info ->
     let
-     srt_info = (srt_label, srt)
-
      (return_vec_amode, vtbl_body) = case ret_conv of {
 
        -- might be a polymorphic case...
       UnvectoredReturn 0 ->
        ASSERT(null tagged_alt_absCs)
        (CLbl ret_label RetRep,
-        absC (CRetDirect uniq deflt_absC (srt_label, srt) liveness));
+        absC (CRetDirect uniq deflt_absC srt_info liveness));
 
       UnvectoredReturn n ->
         -- find the tag explicitly rather than using tag_reg for now.
@@ -912,7 +827,7 @@ mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness ret_conv
        (CLbl ret_label RetRep,
         absC (CRetDirect uniq 
                            (mkAlgAltsCSwitch tag tagged_alt_absCs deflt_absC)
-                           (srt_label, srt)
+                           srt_info
                            liveness));
 
       VectoredReturn table_size ->
@@ -920,9 +835,7 @@ mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness ret_conv
          (vector_table, alts_absC) = 
            unzip (map mk_vector_entry [fIRST_TAG .. (table_size+fIRST_TAG-1)])
 
-         ret_vector = CRetVector vtbl_label
-                         vector_table
-                         (srt_label, srt) liveness
+         ret_vector = CRetVector vtbl_label vector_table srt_info liveness
        in
        (CLbl vtbl_label DataPtrRep, 
         -- alts come first, because we don't want to declare all the symbols
@@ -941,7 +854,7 @@ mkReturnVector uniq tagged_alt_absCs deflt_absC srt liveness ret_conv
     deflt_lbl = 
        case nonemptyAbsC deflt_absC of
                 -- the simplifier might have eliminated a case
-          Nothing -> CLbl mkErrorStdEntryLabel CodePtrRep 
+          Nothing -> mkIntCLit 0 -- CLbl mkErrorStdEntryLabel CodePtrRep 
           Just absC@(CCodeBlock lbl _) -> CLbl lbl CodePtrRep
 
     mk_vector_entry :: ConTag -> (CAddrMode, AbstractC)
@@ -977,15 +890,3 @@ possibleHeapCheck GCMayHappen is_alg regs tags lbl code
 possibleHeapCheck NoGC _ _ tags lbl code 
   = code
 \end{code}
-
-\begin{code}
-getScrutineeTyCon :: Type -> Maybe TyCon
-getScrutineeTyCon ty =
-   case splitRepTyConApp_maybe ty of
-       Nothing -> Nothing
-       Just (tc,_) -> 
-               if isFunTyCon tc  then Nothing else     -- not interested in funs
-               if isPrimTyCon tc then Just tc else     -- return primitive tycons
-                       -- otherwise (algebraic tycons) check the no. of constructors
-               Just tc
-\end{code}