[project @ 2000-01-13 14:33:57 by hwloidl]
[ghc-hetmet.git] / ghc / compiler / absCSyn / Costs.lhs
index 7a2d9dc..7bbadff 100644 (file)
@@ -1,7 +1,9 @@
 %
-% (c) The GRASP/AQUA Project, Glasgow University, 1994-1995
-%     Hans Wolfgang Loidl
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
 %
+% $Id: Costs.lhs,v 1.20 2000/01/13 14:33:57 hwloidl Exp $
+%
+% Only needed in a GranSim setup -- HWL
 % ---------------------------------------------------------------------------
 
 \section[Costs]{Evaluating the costs of computing some abstract C code}
@@ -28,9 +30,11 @@ The meaning of the result tuple is:
    instructions.
 \end{itemize}
 
-This function is needed in GrAnSim for parallelism.
+This function is needed in GranSim for costing pieces of abstract C.
 
-These are first suggestions for scaling the costs. But, this scaling should be done in the RTS rather than the compiler (this really should be tunable!):
+These are first suggestions for scaling the costs. But, this scaling should
+be done in the RTS rather than the compiler (this really should be
+tunable!):
 
 \begin{pseudocode}
 
@@ -44,8 +48,6 @@ These are first suggestions for scaling the costs. But, this scaling should be d
 \end{pseudocode}
 
 \begin{code}
-#include "HsVersions.h"
-
 #define ACCUM_COSTS(i,b,l,s,f) (i+b+l+s+f)
 
 #define NUM_REGS               10 {- PprAbsCSyn.lhs -}       {- runtime/c-as-asm/CallWrap_C.lc -}
@@ -57,34 +59,13 @@ module Costs( costs,
              addrModeCosts, CostRes(Cost), nullCosts, Side(..)
     ) where
 
-import AbsCUtils
+#include "HsVersions.h"
+
 import AbsCSyn
-import PrelInfo
-import PrimOp
-import TyCon
-import Util
+import PrimOp          ( primOpNeedsWrapper, PrimOp(..) )
+import Panic           ( trace )
 
 -- --------------------------------------------------------------------------
-#ifndef GRAN
--- a module of "stubs" that don't do anything
-data CostRes = Cost (Int, Int, Int, Int, Int)
-data Side = Lhs | Rhs
-
-nullCosts    = Cost (0, 0, 0, 0, 0) :: CostRes
-
-costs :: AbstractC -> CostRes
-addrModeCosts :: CAddrMode -> Side -> CostRes
-costs _ = nullCosts
-addrModeCosts _ _ = nullCosts
-
-instance Eq CostRes; instance Text CostRes
-
-instance Num CostRes where
-    x + y = nullCosts
-
-#else {-GRAN-}
--- the real thing
-
 data CostRes = Cost (Int, Int, Int, Int, Int)
               deriving (Text)
 
@@ -105,6 +86,7 @@ instance Num CostRes where
  negate         = mapOp negate
  abs    = mapOp abs
  signum         = mapOp signum
+ fromInteger _ = error "fromInteger not defined"
 
 mapOp :: (Int -> Int) -> CostRes -> CostRes
 mapOp g ( Cost (i, b, l, s, f) )  = Cost (g i, g b, g l, g s, g f)
@@ -140,7 +122,7 @@ costs absC =
 
    CAssign (CReg _) (CTemp _ _) -> Cost (1,0,0,0,0)
 
-   CAssign (CReg _) (CAddr _)  -> Cost (1,0,0,0,0)  -- typ.: add %reg1,<adr>,%reg2
+   CAssign (CReg _) source_m   -> addrModeCosts source_m Rhs
 
    CAssign target_m source_m   -> addrModeCosts target_m Lhs +
                                   addrModeCosts source_m Rhs
@@ -191,7 +173,7 @@ costs absC =
 
    CCodeBlock _ absC         -> costs absC
 
-   CInitHdr cl_info reg_rel cost_centre inplace_upd -> initHdrCosts
+   CInitHdr cl_info reg_rel cost_centre -> initHdrCosts
 
                        {- This is more fancy but superflous: The addr modes
                           are fixed and so the costs are const!
@@ -206,7 +188,7 @@ costs absC =
                           For costing the args of this macro
                           see PprAbsC.lhs where args are inserted -}
 
-   COpStmt modes_res primOp modes_args _ _ ->
+   COpStmt modes_res primOp modes_args _ ->
        {-
           let
                n = length modes_res
@@ -225,6 +207,11 @@ costs absC =
 
    CSimultaneous absC       -> costs absC
 
+   CCheck _ amodes code             -> Cost (2, 1, 0, 0, 0) -- ToDo: refine this by 
+                                                     -- looking at the first arg 
+
+   CRetDirect _ _ _ _       -> nullCosts
+
    CMacroStmt  macro modes  -> stmtMacroCosts macro modes
 
    CCallProfCtrMacro   _ _   -> nullCosts
@@ -236,22 +223,28 @@ costs absC =
   -- *** the next three [or so...] are DATA (those above are CODE) ***
   -- as they are data rather than code they all have nullCosts        -- HWL
 
+   CCallTypedef _ _ _ _      -> nullCosts
+
    CStaticClosure _ _ _ _    -> nullCosts
 
-   CClosureInfoAndCode _ _ _ _ _ _ -> nullCosts
+   CSRT _ _                  -> nullCosts
+
+   CBitmap _ _               -> nullCosts
 
-   CRetVector _ _ _         -> nullCosts
+   CClosureInfoAndCode _ _ _ _ -> nullCosts
 
-   CRetUnVector _ _         -> nullCosts
+   CRetVector _ _ _ _        -> nullCosts
 
-   CFlatRetVector _ _       -> nullCosts
+   CClosureTbl _             -> nullCosts
 
    CCostCentreDecl _ _      -> nullCosts
 
-   CClosureUpdInfo _        -> nullCosts
+   CCostCentreStackDecl _    -> nullCosts
 
    CSplitMarker                     -> nullCosts
 
+   _ -> trace ("Costs.costs") nullCosts
+
 -- ---------------------------------------------------------------------------
 
 addrModeCosts :: CAddrMode -> Side -> CostRes
@@ -266,16 +259,13 @@ addrModeCosts addr_mode side =
     CVal _ _ -> if lhs then Cost (0, 0, 0, 1, 0)
                       else Cost (0, 0, 1, 0, 0)
 
-    CAddr _  -> if lhs then Cost (0, 0, 0, 1, 0)  -- ??unchecked
-                      else Cost (0, 0, 1, 0, 0)
+    CAddr (CIndex _ n _ ) -> Cost (1, 0, 1, 0, 0) -- does pointer arithmetic
 
-    CReg _   -> nullCosts       {- loading from, storing to reg is free ! -}
+    CAddr _ -> nullCosts
+
+    CReg _  -> nullCosts        {- loading from, storing to reg is free ! -}
                                 {- for costing CReg->Creg ops see special -}
                                 {- case in costs fct -}
-    CTableEntry base_mode offset_mode kind ->
-               addrModeCosts base_mode side +
-               addrModeCosts offset_mode side +
-               Cost (1,0,1,0,0)
 
     CTemp _ _  -> nullCosts    {- if lhs then Cost (0, 0, 0, 1, 0)
                                          else Cost (0, 0, 1, 0, 0)  -}
@@ -288,10 +278,6 @@ addrModeCosts addr_mode side =
                  -- Rhs: typically: sethi %hi(lbl),%tmp_reg
                  --                 or    %tmp_reg,%lo(lbl),%target_reg
 
-    CUnVecLbl _ _ -> if lhs then Cost (0, 0, 0, 1, 0)
-                           else Cost (2, 0, 0, 0, 0)
-                    -- same as CLbl
-
     -- Check the following 3 (checked form CLit on)
 
     CCharLike mode -> if lhs then Cost (0, 0, 0, 1, 0)
@@ -300,9 +286,6 @@ addrModeCosts addr_mode side =
     CIntLike mode  -> if lhs then Cost (0, 0, 0, 1, 0)
                             else Cost (0, 0, 1, 0, 0)
 
-    CString _     -> if lhs then Cost (0, 0, 0, 1, 0)
-                            else Cost (0, 0, 1, 0, 0)
-
     CLit    _     -> if lhs then nullCosts            -- should never occur
                             else Cost (1, 0, 0, 0, 0) -- typ.: mov lit,%reg
 
@@ -310,20 +293,12 @@ addrModeCosts addr_mode side =
                             else Cost (1, 0, 0, 0, 0)
                      -- same es CLit
 
-    COffset _     -> if lhs then nullCosts
-                            else Cost (1, 0, 0, 0, 0)
-                     -- same es CLit
-
-    CCode absC    -> costs absC
-
-    CLabelledCode _ absC  ->  costs absC
-
-    CJoinPoint _ _       -> if lhs then Cost (0, 0, 0, 1, 0)
+    CJoinPoint _         -> if lhs then Cost (0, 0, 0, 1, 0)
                                    else Cost (0, 0, 1, 0, 0)
 
     CMacroExpr _ macro mode_list -> exprMacroCosts side macro mode_list
 
-    CCostCentre _ _ -> nullCosts
+    _ -> trace ("Costs.addrModeCosts") nullCosts
 
 -- ---------------------------------------------------------------------------
 
@@ -336,14 +311,11 @@ exprMacroCosts side macro mode_list =
   in
   arg_costs +
   case macro of
-    INFO_PTR   -> if side == Lhs then Cost (0, 0, 0, 1, 0)
-                                else Cost (0, 0, 1, 0, 0)
-    ENTRY_CODE -> nullCosts
-    INFO_TAG   -> if side == Lhs then Cost (0, 0, 0, 1, 0)
-                                else Cost (0, 0, 1, 0, 0)
-    EVAL_TAG   -> if side == Lhs then Cost (1, 0, 0, 1, 0)
-                                else Cost (1, 0, 1, 0, 0)
-                 -- costs of INFO_TAG + (1,0,0,0,0)
+    ENTRY_CODE -> nullCosts -- nothing 
+    ARG_TAG -> nullCosts -- nothing
+    GET_TAG -> Cost (0, 0, 1, 0, 0)  -- indirect load
+    UPD_FRAME_UPDATEE -> Cost (0, 0, 1, 0, 0)  -- indirect load
+    _ -> trace ("Costs.exprMacroCosts") nullCosts
 
 -- ---------------------------------------------------------------------------
 
@@ -355,43 +327,22 @@ stmtMacroCosts macro modes =
                        [addrModeCosts mode Rhs | mode <- modes]
   in
   case macro of
-    ARGS_CHK_A_LOAD_NODE  ->  Cost (2, 1, 0, 0, 0)      {- StgMacros.lh  -}
+    ARGS_CHK_LOAD_NODE  ->  Cost (2, 1, 0, 0, 0)        {- StgMacros.lh  -}
                -- p=probability of PAP (instead of AP): + p*(3,1,0,0,0)
-    ARGS_CHK_A           ->  Cost (2, 1, 0, 0, 0)       {- StgMacros.lh  -}
-               -- p=probability of PAP (instead of AP): + p*(0,1,0,0,0)
-    ARGS_CHK_B_LOAD_NODE  ->  Cost (2, 1, 0, 0, 0)      {- StgMacros.lh  -}
-    ARGS_CHK_B           ->  Cost (2, 1, 0, 0, 0)       {- StgMacros.lh  -}
-    HEAP_CHK             ->  Cost (2, 1, 0, 0, 0)       {- StgMacros.lh  -}
-    -- STK_CHK              ->  (2, 1, 0, 0, 0)       {- StgMacros.lh  -}
-    STK_CHK              ->  Cost (0, 0, 0, 0, 0)       {- StgMacros.lh  -}
+    ARGS_CHK             ->  Cost (2, 1, 0, 0, 0)       {- StgMacros.lh  -}
     UPD_CAF              ->  Cost (7, 0, 1, 3, 0)       {- SMupdate.lh  -}
-    UPD_IND              ->  Cost (8, 2, 2, 0, 0)       {- SMupdate.lh
-                               updatee in old-gen: Cost (4, 1, 1, 0, 0)
-                               updatee in new-gen: Cost (4, 1, 1, 0, 0)
-                               NB: we include costs fo checking if there is
-                                   a BQ, but we omit costs for awakening BQ
-                                   (these probably differ between old-gen and
-                                   new gen) -}
-    UPD_INPLACE_NOPTRS   ->  Cost (13, 3, 3, 2, 0)       {- SMupdate.lh
-                               common for both:    Cost (4, 1, 1, 0, 0)
-                               updatee in old-gen: Cost (14, 3, 2, 4, 0)
-                               updatee in new-gen: Cost (4, 1, 1, 0, 0)   -}
-    UPD_INPLACE_PTRS     ->  Cost (13, 3, 3, 2, 0)       {- SMupdate.lh
-                               common for both:    Cost (4, 1, 1, 0, 0)
-                               updatee in old-gen: Cost (14, 3, 2, 4, 0)
-                               updatee in new-gen: Cost (4, 1, 1, 0, 0)   -}
-
     UPD_BH_UPDATABLE     ->  Cost (3, 0, 0, 1, 0)       {- SMupdate.lh  -}
     UPD_BH_SINGLE_ENTRY          ->  Cost (3, 0, 0, 1, 0)       {- SMupdate.lh  -}
-    PUSH_STD_UPD_FRAME   ->  Cost (3, 0, 0, 4, 0)       {- SMupdate.lh  -}
-    POP_STD_UPD_FRAME    ->  Cost (1, 0, 3, 0, 0)       {- SMupdate.lh  -}
-    SET_ARITY            ->  nullCosts             {- StgMacros.lh  -}
-    CHK_ARITY            ->  nullCosts             {- StgMacros.lh  -}
+    PUSH_UPD_FRAME       ->  Cost (3, 0, 0, 4, 0)       {- Updates.h    -}
+    PUSH_SEQ_FRAME       ->  Cost (2, 0, 0, 3, 0)       {- StgMacros.h  !-}
+    UPDATE_SU_FROM_UPD_FRAME -> Cost (1, 0, 1, 0, 0)     {- StgMacros.h         !-}
     SET_TAG              ->  nullCosts             {- COptRegs.lh -}
     GRAN_FETCH                 ->  nullCosts     {- GrAnSim bookkeeping -}
     GRAN_RESCHEDULE            ->  nullCosts     {- GrAnSim bookkeeping -}
     GRAN_FETCH_AND_RESCHEDULE  ->  nullCosts     {- GrAnSim bookkeeping -}
+    GRAN_YIELD                 ->  nullCosts     {- GrAnSim bookkeeping -- added SOF -}
     THREAD_CONTEXT_SWITCH      ->  nullCosts     {- GrAnSim bookkeeping -}
+    _ -> trace ("Costs.stmtMacroCosts") nullCosts
 
 -- ---------------------------------------------------------------------------
 
@@ -414,8 +365,8 @@ floatOps =
     , DoubleAsinOp  , DoubleAcosOp  , DoubleAtanOp
     , DoubleSinhOp  , DoubleCoshOp  , DoubleTanhOp
     , DoublePowerOp
-    , FloatEncodeOp  , FloatDecodeOp
-    , DoubleEncodeOp , DoubleDecodeOp
+    , FloatDecodeOp
+    , DoubleDecodeOp
   ]
 
 gmpOps :: [PrimOp]
@@ -428,10 +379,7 @@ gmpOps     =
   ]
 
 
--- Haven't found the .umul .div .rem macros yet
--- If they are not Haskell cde, they are not costed, yet
-
-abs_costs = nullCosts  -- NB:  This is normal STG code with costs already
+abs_costs = nullCosts   -- NB:  This is normal STG code with costs already 
                        --      included; no need to add costs again.
 
 umul_costs = Cost (21,4,0,0,0)    -- due to spy counts
@@ -442,8 +390,10 @@ primOpCosts :: PrimOp -> CostRes
 
 -- Special cases
 
-primOpCosts (CCallOp _ _ _ _ _) = SAVE_COSTS + CCALL_COSTS_GUESS +
-                                 RESTORE_COSTS         -- GUESS; check it
+primOpCosts (CCallOp _ _ _ _) = SAVE_COSTS + RESTORE_COSTS     
+                                 -- don't guess costs of ccall proper
+                                  -- for exact costing use a GRAN_EXEC
+                                  -- in the C code
 
 -- Usually 3 mov instructions are needed to get args and res in right place.
 
@@ -451,7 +401,6 @@ primOpCosts IntMulOp  = Cost (3, 1, 0, 0, 0)  + umul_costs
 primOpCosts IntQuotOp = Cost (3, 1, 0, 0, 0)  + div_costs
 primOpCosts IntRemOp  = Cost (3, 1, 0, 0, 0)  + rem_costs
 primOpCosts IntNegOp  = Cost (1, 1, 0, 0, 0) -- translates into 1 sub
-primOpCosts IntAbsOp  = Cost (0, 1, 0, 0, 0) -- abs closure already costed
 
 primOpCosts FloatGtOp  = Cost (2, 0, 0, 0, 2) -- expensive f-comp
 primOpCosts FloatGeOp  = Cost (2, 0, 0, 0, 2) -- expensive f-comp
@@ -487,7 +436,7 @@ primOpCosts FloatPowerOp  = Cost (2, 1, 4, 4, 3)
 
 primOpCosts primOp
   | primOp `elem` floatOps = Cost (0, 0, 0, 0, 1)  :: CostRes
-  | primOp `elem` gmpOps   = Cost (50, 5, 10, 10, 0) :: CostRes         -- GUESS; check it
+  | primOp `elem` gmpOps   = Cost (30, 5, 10, 10, 0) :: CostRes  -- GUESS; check it
   | otherwise             = Cost (1, 0, 0, 0, 0)
 
 -- ---------------------------------------------------------------------------
@@ -505,8 +454,6 @@ costsByKind FloatRep        _ = nullCosts
 costsByKind DoubleRep  _ = nullCosts
 -}
 -- ---------------------------------------------------------------------------
-
-#endif {-GRAN-}
 \end{code}
 
 This is the data structure of {\tt PrimOp} copied from prelude/PrimOp.lhs.
@@ -538,12 +485,12 @@ data PrimOp
     -- but these take more than that; see special cases in primOpCosts
     -- I counted the generated ass. instructions for these -> checked
     | IntMulOp | IntQuotOp
-    | IntRemOp | IntNegOp | IntAbsOp
+    | IntRemOp | IntNegOp
 
     -- Rest is unchecked so far -- HWL
 
     -- Word#-related ops:
-    | AndOp   | OrOp  | NotOp | ShiftLOp | ShiftROp
+    | AndOp   | OrOp  | NotOp | XorOp | ShiftLOp | ShiftROp
     | Int2WordOp | Word2IntOp -- casts
 
     -- Addr#-related ops:
@@ -604,8 +551,8 @@ data PrimOp
     | IndexOffAddrOp   PrimRep
        -- PrimRep can be one of {Char,Int,Addr,Float,Double}Kind.
        -- This is just a cheesy encoding of a bunch of ops.
-       -- Note that MallocPtrRep is not included -- the only way of
-       -- creating a MallocPtr is with a ccall or casm.
+       -- Note that ForeignObjRep is not included -- the only way of
+       -- creating a ForeignObj is with a ccall or casm.
 
     | UnsafeFreezeArrayOp | UnsafeFreezeByteArrayOp
 
@@ -613,7 +560,11 @@ data PrimOp
 \end{pseudocode}
 
 A special ``trap-door'' to use in making calls direct to C functions:
-Note: From GrAn point of view, CCall is probably very expensive -- HWL
+Note: From GrAn point of view, CCall is probably very expensive 
+      The programmer can specify the costs of the Ccall by inserting
+      a GRAN_EXEC(a,b,l,s,f) at the end of the C- code, specifing the
+      number or arithm., branch, load, store and floating point instructions
+      -- HWL
 
 \begin{pseudocode}
     | CCallOp  String  -- An "unboxed" ccall# to this named function