Add PrimCall to the STG layer and update Core -> STG translation
[ghc-hetmet.git] / compiler / codeGen / CgExpr.lhs
index 43f6990..71087ca 100644 (file)
@@ -12,6 +12,7 @@ import Constants
 import StgSyn
 import CgMonad
 
+import CostCentre
 import SMRep
 import CoreSyn
 import CgProf
@@ -21,7 +22,6 @@ import CgCase
 import CgClosure
 import CgCon
 import CgLetNoEscape
-import CgCallConv
 import CgTailCall
 import CgInfoTbls
 import CgForeignCall
@@ -30,7 +30,7 @@ import CgHpc
 import CgUtils
 import ClosureInfo
 import Cmm
-import MachOp
+import CmmUtils
 import VarSet
 import Literal
 import PrimOp
@@ -121,18 +121,15 @@ cgExpr (StgOpApp (StgFCallOp fcall _) stg_args res_ty) = do
                    | (stg_arg, (rep,expr)) <- stg_args `zip` reps_n_amodes, 
                      nonVoidArg rep]
 
-    arg_tmps <- sequence [
-                 if isFollowableArg (typeCgRep (stgArgType stg_arg))
-                 then assignPtrTemp arg
-                 else assignNonPtrTemp arg
-                     | (arg, stg_arg) <- arg_exprs]
-    let        arg_hints = zip arg_tmps (map (typeHint.stgArgType) stg_args)
+    arg_tmps <- sequence [ assignTemp arg
+                         | (arg, _) <- arg_exprs]
+    let        arg_hints = zipWith CmmHinted arg_tmps (map (typeForeignHint.stgArgType) stg_args)
     {-
        Now, allocate some result regs.
     -}
     (res_reps,res_regs,res_hints)  <- newUnboxedTupleRegs res_ty
     ccallReturnUnboxedTuple (zip res_reps (map (CmmReg . CmmLocal) res_regs)) $
-       emitForeignCall (zip res_regs res_hints) fcall 
+       emitForeignCall (zipWith CmmHinted res_regs res_hints) fcall 
           arg_hints emptyVarSet{-no live vars-}
       
 -- tagToEnum# is special: we need to pull the constructor out of the table,
@@ -140,14 +137,10 @@ cgExpr (StgOpApp (StgFCallOp fcall _) stg_args res_ty) = do
 
 cgExpr (StgOpApp (StgPrimOp TagToEnumOp) [arg] res_ty) 
   = ASSERT(isEnumerationTyCon tycon)
-    do { (rep,amode) <- getArgAmode arg
-       ; amode' <- if isFollowableArg rep
-                    then assignPtrTemp amode
-                   else assignNonPtrTemp amode
-                                       -- We're going to use it twice,
+    do { (_rep,amode) <- getArgAmode arg
+       ; amode' <- assignTemp amode    -- We're going to use it twice,
                                        -- so save in a temp if non-trivial
-       ; this_pkg <- getThisPackage
-       ; stmtC (CmmAssign nodeReg (tagToClosure this_pkg tycon amode'))
+       ; stmtC (CmmAssign nodeReg (tagToClosure tycon amode'))
        ; performReturn emitReturnInstr }
    where
          -- If you're reading this code in the attempt to figure
@@ -158,7 +151,7 @@ cgExpr (StgOpApp (StgPrimOp TagToEnumOp) [arg] res_ty)
        tycon = tyConAppTyCon res_ty
 
 
-cgExpr x@(StgOpApp op@(StgPrimOp primop) args res_ty)
+cgExpr (StgOpApp (StgPrimOp primop) args res_ty)
   | primOpOutOfLine primop
        = tailCallPrimOp primop args
 
@@ -167,9 +160,7 @@ cgExpr x@(StgOpApp op@(StgPrimOp primop) args res_ty)
             performReturn emitReturnInstr
 
   | ReturnsPrim rep <- result_info
-       = do res <- if isFollowableArg (typeCgRep res_ty)
-                        then newPtrTemp (argMachRep (typeCgRep res_ty))
-                        else newNonPtrTemp (argMachRep (typeCgRep res_ty))
+       = do res <- newTemp (typeCmmType res_ty)
              cgPrimOp [res] primop args emptyVarSet
             performPrimReturn (primRepToCgRep rep) (CmmReg (CmmLocal res))
 
@@ -180,17 +171,17 @@ cgExpr x@(StgOpApp op@(StgPrimOp primop) args res_ty)
 
   | ReturnsAlg tycon <- result_info, isEnumerationTyCon tycon
        -- c.f. cgExpr (...TagToEnumOp...)
-       = do tag_reg <- if isFollowableArg (typeCgRep res_ty)
-                        then newPtrTemp wordRep
-                        else newNonPtrTemp wordRep
-            this_pkg <- getThisPackage
+       = do tag_reg <- newTemp bWord   -- The tag is a word
             cgPrimOp [tag_reg] primop args emptyVarSet
             stmtC (CmmAssign nodeReg
-                    (tagToClosure this_pkg tycon
+                    (tagToClosure tycon
                      (CmmReg (CmmLocal tag_reg))))
             performReturn emitReturnInstr
   where
        result_info = getPrimOpResultInfo primop
+
+cgExpr (StgOpApp (StgPrimCallOp primcall) args _res_ty)
+  = tailCallPrimCall primcall args
 \end{code}
 
 %********************************************************
@@ -203,7 +194,7 @@ module, @CgCase@.
 \begin{code}
 
 cgExpr (StgCase expr live_vars save_vars bndr srt alt_type alts)
-  = cgCase expr live_vars save_vars bndr srt alt_type alts
+  = setSRT srt $ cgCase expr live_vars save_vars bndr alt_type alts
 \end{code}
 
 
@@ -273,6 +264,16 @@ cgExpr (StgTick m n expr) = do cgTickBox m n; cgExpr expr
 \end{code}
 
 %********************************************************
+%*                                                     *
+%*             Anything else                           *
+%*                                                     *
+%********************************************************
+
+\begin{code}
+cgExpr _ = panic "cgExpr"
+\end{code}
+
+%********************************************************
 %*                                                     *
 %*             Non-top-level bindings                  *
 %*                                                     *
@@ -292,8 +293,7 @@ cgRhs name (StgRhsCon maybe_cc con args)
        ; returnFC (name, idinfo) }
 
 cgRhs name (StgRhsClosure cc bi fvs upd_flag srt args body)
-  = do this_pkg <- getThisPackage
-       mkRhsClosure this_pkg name cc bi srt fvs upd_flag args body
+  = setSRT srt $ mkRhsClosure name cc bi fvs upd_flag args body
 \end{code}
 
 mkRhsClosure looks for two special forms of the right-hand side:
@@ -316,14 +316,17 @@ form:
 
 
 \begin{code}
-mkRhsClosure   this_pkg bndr cc bi srt
+mkRhsClosure :: Id -> CostCentreStack -> StgBinderInfo
+             -> [Id] -> UpdateFlag -> [Id] -> GenStgExpr Id Id
+             -> FCode (Id, CgIdInfo)
+mkRhsClosure   bndr cc bi
                [the_fv]                -- Just one free var
                upd_flag                -- Updatable thunk
                []                      -- A thunk
                body@(StgCase (StgApp scrutinee [{-no args-}])
-                     _ _ _ _   -- ignore uniq, etc.
-                     (AlgAlt tycon)
-                     [(DataAlt con, params, use_mask,
+                     _ _ _ srt   -- ignore uniq, etc.
+                     (AlgAlt _)
+                     [(DataAlt con, params, _use_mask,
                            (StgApp selectee [{-no args-}]))])
   |  the_fv == scrutinee               -- Scrutinee is the only free variable
   && maybeToBool maybe_offset          -- Selectee is a component of the tuple
@@ -334,11 +337,11 @@ mkRhsClosure      this_pkg bndr cc bi srt
     -- other constructors in the datatype.  It's still ok to make a selector
     -- thunk in this case, because we *know* which constructor the scrutinee
     -- will evaluate to.
-    cgStdRhsClosure bndr cc bi [the_fv] [] body lf_info [StgVarArg the_fv]
+    setSRT srt $ cgStdRhsClosure bndr cc bi [the_fv] [] body lf_info [StgVarArg the_fv]
   where
     lf_info              = mkSelectorLFInfo bndr offset_into_int
                                 (isUpdatable upd_flag)
-    (_, params_w_offsets) = layOutDynConstr this_pkg con (addIdReps params)
+    (_, params_w_offsets) = layOutDynConstr con (addIdReps params)
                        -- Just want the layout
     maybe_offset         = assocMaybe params_w_offsets selectee
     Just the_offset      = maybe_offset
@@ -362,7 +365,7 @@ We only generate an Ap thunk if all the free variables are pointers,
 for semi-obvious reasons.
 
 \begin{code}
-mkRhsClosure   this_pkg bndr cc bi srt
+mkRhsClosure    bndr cc bi
                fvs
                upd_flag
                []                      -- No args; a thunk
@@ -387,8 +390,8 @@ mkRhsClosure        this_pkg bndr cc bi srt
 The default case
 ~~~~~~~~~~~~~~~~
 \begin{code}
-mkRhsClosure this_pkg bndr cc bi srt fvs upd_flag args body
-  = cgRhsClosure bndr cc bi srt fvs upd_flag args body
+mkRhsClosure bndr cc bi fvs upd_flag args body
+  = cgRhsClosure bndr cc bi fvs upd_flag args body
 \end{code}
 
 
@@ -398,6 +401,9 @@ mkRhsClosure this_pkg bndr cc bi srt fvs upd_flag args body
 %*                                                     *
 %********************************************************
 \begin{code}
+cgLetNoEscapeBindings :: StgLiveVars -> EndOfBlockInfo
+                      -> Maybe VirtualSpOffset -> GenStgBinding Id Id
+                      -> Code
 cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot 
        (StgNonRec binder rhs)
   = do { (binder,info) <- cgLetNoEscapeRhs live_in_rhss rhs_eob_info 
@@ -416,7 +422,7 @@ cgLetNoEscapeBindings live_in_rhss rhs_eob_info maybe_cc_slot (StgRec pairs)
   where
     -- We add the binders to the live-in-rhss set so that we don't
     -- delete the bindings for the binder from the environment!
-    full_live_in_rhss = live_in_rhss `unionVarSet` (mkVarSet [b | (b,r) <- pairs])
+    full_live_in_rhss = live_in_rhss `unionVarSet` (mkVarSet [b | (b,_) <- pairs])
 
 cgLetNoEscapeRhs
     :: StgLiveVars     -- Live in rhss
@@ -428,13 +434,13 @@ cgLetNoEscapeRhs
     -> FCode (Id, CgIdInfo)
 
 cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
-                (StgRhsClosure cc bi _ upd_flag srt args body)
+                (StgRhsClosure cc bi _ _upd_flag srt args body)
   = -- We could check the update flag, but currently we don't switch it off
     -- for let-no-escaped things, so we omit the check too!
     -- case upd_flag of
     --     Updatable -> panic "cgLetNoEscapeRhs"       -- Nothing to update!
     --     other     -> cgLetNoEscapeClosure binder cc bi live_in_whole_let live_in_rhss args body
-    cgLetNoEscapeClosure binder cc bi srt full_live_in_rhss rhs_eob_info
+    setSRT srt $ cgLetNoEscapeClosure binder cc bi full_live_in_rhss rhs_eob_info
        maybe_cc_slot rec args body
 
 -- For a constructor RHS we want to generate a single chunk of code which
@@ -442,7 +448,7 @@ cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
 -- It's easy; just behave as if it was an StgRhsClosure with a ConApp inside!
 cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
                 (StgRhsCon cc con args)
-  = cgLetNoEscapeClosure binder cc noBinderInfo{-safe-} NoSRT
+  = setSRT NoSRT $ cgLetNoEscapeClosure binder cc noBinderInfo{-safe-}
                         full_live_in_rhss rhs_eob_info maybe_cc_slot rec
        []      --No args; the binder is data structure, not a function
        (StgConApp con args)
@@ -451,16 +457,14 @@ cgLetNoEscapeRhs full_live_in_rhss rhs_eob_info maybe_cc_slot rec binder
 Little helper for primitives that return unboxed tuples.
 
 \begin{code}
-newUnboxedTupleRegs :: Type -> FCode ([CgRep], [LocalReg], [MachHint])
+newUnboxedTupleRegs :: Type -> FCode ([CgRep], [LocalReg], [ForeignHint])
 newUnboxedTupleRegs res_ty =
    let
        ty_args = tyConAppArgs (repType res_ty)
-       (reps,hints) = unzip [ (rep, typeHint ty) | ty <- ty_args,
+       (reps,hints) = unzip [ (rep, typeForeignHint ty) | ty <- ty_args,
                                                    let rep = typeCgRep ty,
                                                    nonVoidArg rep ]
-       make_new_temp rep = if isFollowableArg rep
-                            then newPtrTemp (argMachRep rep)
-                            else newNonPtrTemp (argMachRep rep)
+       make_new_temp rep = newTemp (argMachRep rep)
    in do
    regs <- mapM make_new_temp reps
    return (reps,regs,hints)