%
-% (c) The GRASP/AQUA Project, Glasgow University, 1994-1995
+% (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
% Hans Wolfgang Loidl
%
% ---------------------------------------------------------------------------
\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 -}
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)
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!
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
CSimultaneous absC -> costs absC
+ CCheck _ amodes code -> Cost (2, 1, 0, 0, 0)
+
CMacroStmt macro modes -> stmtMacroCosts macro modes
CCallProfCtrMacro _ _ -> nullCosts
CStaticClosure _ _ _ _ -> nullCosts
- CClosureInfoAndCode _ _ _ _ _ _ -> nullCosts
+ CClosureInfoAndCode _ _ _ _ -> nullCosts
- CRetVector _ _ _ -> nullCosts
+ CRetDirect _ _ _ _ -> nullCosts
- CRetUnVector _ _ -> nullCosts
-
- CFlatRetVector _ _ -> nullCosts
+ CRetVector _ _ _ _ -> nullCosts
CCostCentreDecl _ _ -> nullCosts
-
- CClosureUpdInfo _ -> nullCosts
+ CCostCentreStackDecl _ -> nullCosts
CSplitMarker -> nullCosts
-- 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)
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
-
-- ---------------------------------------------------------------------------
exprMacroCosts :: Side -> CExprMacro -> [CAddrMode] -> CostRes
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)
+ ARG_TAG -> nullCosts -- XXX
+ GET_TAG -> nullCosts -- XXX
+
-- ---------------------------------------------------------------------------
[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) {- SMupdate.lh -}
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: "++show macro) nullCosts
-- ---------------------------------------------------------------------------
, DoubleAsinOp , DoubleAcosOp , DoubleAtanOp
, DoubleSinhOp , DoubleCoshOp , DoubleTanhOp
, DoublePowerOp
- , FloatEncodeOp , FloatDecodeOp
- , DoubleEncodeOp , DoubleDecodeOp
+ , FloatDecodeOp
+ , DoubleDecodeOp
]
gmpOps :: [PrimOp]
]
--- 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
-- 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.
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)
-- ---------------------------------------------------------------------------
costsByKind DoubleRep _ = nullCosts
-}
-- ---------------------------------------------------------------------------
-
-#endif {-GRAN-}
\end{code}
This is the data structure of {\tt PrimOp} copied from prelude/PrimOp.lhs.
-- 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:
| 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
\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