Commit 493c12ff authored by Simon Peyton Jones's avatar Simon Peyton Jones Committed by Simon Marlow

More refactoring (CgRep)

* Move CgRep (private to old codgen) from SMRep to ClosureInfo
* Avoid using CgRep in new codegen
* Move SMRep and Bitmap from codeGen/ to cmm/
parent 5b167f5e
......@@ -13,7 +13,6 @@ import Prelude hiding (last, unzip, succ, zip)
import BlockId
import CLabel
import Cmm
import CmmExpr
import CmmUtils
import CmmContFlowOpt
import CmmInfo
......
{-# LANGUAGE GADTs #-}
{-# OPTIONS_GHC -w #-}
-- Warnings from deprecated blockToNodeList
-----------------------------------------------------------------------------
--
-- Cmm utilities.
......
......@@ -15,18 +15,6 @@ module SMRep (
hALF_WORD_SIZE, hALF_WORD_SIZE_IN_BITS,
WordOff, ByteOff,
-- Argument/return representations
CgRep(..), nonVoidArg,
argMachRep, primRepToCgRep,
-- Temp primRepHint, typeHint,
isFollowableArg, isVoidArg,
isFloatingArg, is64BitArg,
separateByPtrFollowness,
cgRepSizeW, cgRepSizeB,
retAddrSizeW,
typeCgRep, idCgRep, tyConCgRep,
-- Closure repesentation
SMRep(..), -- CmmInfo sees the rep; no one else does
IsStatic,
......@@ -49,10 +37,6 @@ module SMRep (
#include "../HsVersions.h"
#include "../includes/MachDeps.h"
import CmmType
import Id
import Type
import TyCon
import StaticFlags
import Constants
import Outputable
......@@ -96,148 +80,6 @@ hALF_WORD_SIZE_IN_BITS = 32
#endif
\end{code}
%************************************************************************
%* *
CgRep
%* *
%************************************************************************
An CgRep is an abstraction of a Type which tells the code generator
all it needs to know about the calling convention for arguments (and
results) of that type. In particular, the ArgReps of a function's
arguments are used to decide which of the RTS's generic apply
functions to call when applying an unknown function.
It contains more information than the back-end data type MachRep,
so one can easily convert from CgRep -> MachRep. (Except that
there's no MachRep for a VoidRep.)
It distinguishes
pointers from non-pointers (we sort the pointers together
when building closures)
void from other types: a void argument is different from no argument
All 64-bit types map to the same CgRep, because they're passed in the
same register, but a PtrArg is still different from an NonPtrArg
because the function's entry convention has to take into account the
pointer-hood of arguments for the purposes of describing the stack on
entry to the garbage collector.
\begin{code}
data CgRep
= VoidArg -- Void
| PtrArg -- Word-sized heap pointer, followed
-- by the garbage collector
| NonPtrArg -- Word-sized non-pointer
-- (including addresses not followed by GC)
| LongArg -- 64-bit non-pointer
| FloatArg -- 32-bit float
| DoubleArg -- 64-bit float
deriving Eq
instance Outputable CgRep where
ppr VoidArg = ptext (sLit "V_")
ppr PtrArg = ptext (sLit "P_")
ppr NonPtrArg = ptext (sLit "I_")
ppr LongArg = ptext (sLit "L_")
ppr FloatArg = ptext (sLit "F_")
ppr DoubleArg = ptext (sLit "D_")
argMachRep :: CgRep -> CmmType
argMachRep PtrArg = gcWord
argMachRep NonPtrArg = bWord
argMachRep LongArg = b64
argMachRep FloatArg = f32
argMachRep DoubleArg = f64
argMachRep VoidArg = panic "argMachRep:VoidRep"
primRepToCgRep :: PrimRep -> CgRep
primRepToCgRep VoidRep = VoidArg
primRepToCgRep PtrRep = PtrArg
primRepToCgRep IntRep = NonPtrArg
primRepToCgRep WordRep = NonPtrArg
primRepToCgRep Int64Rep = LongArg
primRepToCgRep Word64Rep = LongArg
primRepToCgRep AddrRep = NonPtrArg
primRepToCgRep FloatRep = FloatArg
primRepToCgRep DoubleRep = DoubleArg
idCgRep :: Id -> CgRep
idCgRep x = typeCgRep . idType $ x
tyConCgRep :: TyCon -> CgRep
tyConCgRep = primRepToCgRep . tyConPrimRep
typeCgRep :: Type -> CgRep
typeCgRep = primRepToCgRep . typePrimRep
\end{code}
Whether or not the thing is a pointer that the garbage-collector
should follow. Or, to put it another (less confusing) way, whether
the object in question is a heap object.
Depending on the outcome, this predicate determines what stack
the pointer/object possibly will have to be saved onto, and the
computation of GC liveness info.
\begin{code}
isFollowableArg :: CgRep -> Bool -- True <=> points to a heap object
isFollowableArg PtrArg = True
isFollowableArg _ = False
isVoidArg :: CgRep -> Bool
isVoidArg VoidArg = True
isVoidArg _ = False
nonVoidArg :: CgRep -> Bool
nonVoidArg VoidArg = False
nonVoidArg _ = True
-- isFloatingArg is used to distinguish @Double@ and @Float@ which
-- cause inadvertent numeric conversions if you aren't jolly careful.
-- See codeGen/CgCon:cgTopRhsCon.
isFloatingArg :: CgRep -> Bool
isFloatingArg DoubleArg = True
isFloatingArg FloatArg = True
isFloatingArg _ = False
is64BitArg :: CgRep -> Bool
is64BitArg LongArg = True
is64BitArg _ = False
\end{code}
\begin{code}
separateByPtrFollowness :: [(CgRep,a)] -> ([(CgRep,a)], [(CgRep,a)])
-- Returns (ptrs, non-ptrs)
separateByPtrFollowness things
= sep_things things [] []
-- accumulating params for follow-able and don't-follow things...
where
sep_things [] bs us = (reverse bs, reverse us)
sep_things ((PtrArg,a):ts) bs us = sep_things ts ((PtrArg,a):bs) us
sep_things (t :ts) bs us = sep_things ts bs (t:us)
\end{code}
\begin{code}
cgRepSizeB :: CgRep -> ByteOff
cgRepSizeB DoubleArg = dOUBLE_SIZE
cgRepSizeB LongArg = wORD64_SIZE
cgRepSizeB VoidArg = 0
cgRepSizeB _ = wORD_SIZE
cgRepSizeW :: CgRep -> ByteOff
cgRepSizeW DoubleArg = dOUBLE_SIZE `quot` wORD_SIZE
cgRepSizeW LongArg = wORD64_SIZE `quot` wORD_SIZE
cgRepSizeW VoidArg = 0
cgRepSizeW _ = 1
retAddrSizeW :: WordOff
retAddrSizeW = 1 -- One word
\end{code}
%************************************************************************
%* *
\subsubsection[SMRep-datatype]{@SMRep@---storage manager representation}
......
......@@ -35,6 +35,7 @@ import CLabel
import Constants
import CgStackery
import ClosureInfo( CgRep(..), nonVoidArg, idCgRep, cgRepSizeW, isFollowableArg )
import OldCmmUtils
import Maybes
import Id
......
......@@ -26,7 +26,6 @@ import CgProf
import CgInfoTbls
import ClosureInfo
import SMRep
import OldCmmUtils
import OldCmm
......
......@@ -24,6 +24,7 @@ import CgMonad
import CgUtils
import Type
import TysPrim
import ClosureInfo( nonVoidArg )
import CLabel
import OldCmm
import OldCmmUtils
......
......@@ -30,7 +30,6 @@ import CLabel
import ClosureInfo
import CostCentre
import Id
import SMRep
import BasicTypes
\end{code}
......
......@@ -25,6 +25,7 @@ module CgStackery (
import CgMonad
import CgUtils
import CgProf
import ClosureInfo( CgRep(..), cgRepSizeW )
import SMRep
import OldCmm
import OldCmmUtils
......
......@@ -27,7 +27,6 @@ import CgHeapery
import CgUtils
import CgTicky
import ClosureInfo
import SMRep
import OldCmm
import OldCmmUtils
import CLabel
......
......@@ -42,7 +42,6 @@ module CgTicky (
import ClosureInfo
import CgUtils
import CgMonad
import SMRep
import OldCmm
import OldCmmUtils
......
......@@ -52,6 +52,17 @@ module ClosureInfo (
cafBlackHoleClosureInfo,
staticClosureNeedsLink,
-- CgRep and its functions
CgRep(..), nonVoidArg,
argMachRep, primRepToCgRep,
isFollowableArg, isVoidArg,
isFloatingArg, is64BitArg,
separateByPtrFollowness,
cgRepSizeW, cgRepSizeB,
retAddrSizeW,
typeCgRep, idCgRep, tyConCgRep,
) where
#include "../includes/MachDeps.h"
......@@ -75,6 +86,7 @@ import TcType
import TyCon
import BasicTypes
import Outputable
import FastString
import Constants
import DynFlags
\end{code}
......@@ -195,6 +207,148 @@ data StandardFormInfo
Int -- Arity, n
\end{code}
%************************************************************************
%* *
CgRep
%* *
%************************************************************************
An CgRep is an abstraction of a Type which tells the code generator
all it needs to know about the calling convention for arguments (and
results) of that type. In particular, the ArgReps of a function's
arguments are used to decide which of the RTS's generic apply
functions to call when applying an unknown function.
It contains more information than the back-end data type MachRep,
so one can easily convert from CgRep -> MachRep. (Except that
there's no MachRep for a VoidRep.)
It distinguishes
pointers from non-pointers (we sort the pointers together
when building closures)
void from other types: a void argument is different from no argument
All 64-bit types map to the same CgRep, because they're passed in the
same register, but a PtrArg is still different from an NonPtrArg
because the function's entry convention has to take into account the
pointer-hood of arguments for the purposes of describing the stack on
entry to the garbage collector.
\begin{code}
data CgRep
= VoidArg -- Void
| PtrArg -- Word-sized heap pointer, followed
-- by the garbage collector
| NonPtrArg -- Word-sized non-pointer
-- (including addresses not followed by GC)
| LongArg -- 64-bit non-pointer
| FloatArg -- 32-bit float
| DoubleArg -- 64-bit float
deriving Eq
instance Outputable CgRep where
ppr VoidArg = ptext (sLit "V_")
ppr PtrArg = ptext (sLit "P_")
ppr NonPtrArg = ptext (sLit "I_")
ppr LongArg = ptext (sLit "L_")
ppr FloatArg = ptext (sLit "F_")
ppr DoubleArg = ptext (sLit "D_")
argMachRep :: CgRep -> CmmType
argMachRep PtrArg = gcWord
argMachRep NonPtrArg = bWord
argMachRep LongArg = b64
argMachRep FloatArg = f32
argMachRep DoubleArg = f64
argMachRep VoidArg = panic "argMachRep:VoidRep"
primRepToCgRep :: PrimRep -> CgRep
primRepToCgRep VoidRep = VoidArg
primRepToCgRep PtrRep = PtrArg
primRepToCgRep IntRep = NonPtrArg
primRepToCgRep WordRep = NonPtrArg
primRepToCgRep Int64Rep = LongArg
primRepToCgRep Word64Rep = LongArg
primRepToCgRep AddrRep = NonPtrArg
primRepToCgRep FloatRep = FloatArg
primRepToCgRep DoubleRep = DoubleArg
idCgRep :: Id -> CgRep
idCgRep x = typeCgRep . idType $ x
tyConCgRep :: TyCon -> CgRep
tyConCgRep = primRepToCgRep . tyConPrimRep
typeCgRep :: Type -> CgRep
typeCgRep = primRepToCgRep . typePrimRep
\end{code}
Whether or not the thing is a pointer that the garbage-collector
should follow. Or, to put it another (less confusing) way, whether
the object in question is a heap object.
Depending on the outcome, this predicate determines what stack
the pointer/object possibly will have to be saved onto, and the
computation of GC liveness info.
\begin{code}
isFollowableArg :: CgRep -> Bool -- True <=> points to a heap object
isFollowableArg PtrArg = True
isFollowableArg _ = False
isVoidArg :: CgRep -> Bool
isVoidArg VoidArg = True
isVoidArg _ = False
nonVoidArg :: CgRep -> Bool
nonVoidArg VoidArg = False
nonVoidArg _ = True
-- isFloatingArg is used to distinguish @Double@ and @Float@ which
-- cause inadvertent numeric conversions if you aren't jolly careful.
-- See codeGen/CgCon:cgTopRhsCon.
isFloatingArg :: CgRep -> Bool
isFloatingArg DoubleArg = True
isFloatingArg FloatArg = True
isFloatingArg _ = False
is64BitArg :: CgRep -> Bool
is64BitArg LongArg = True
is64BitArg _ = False
\end{code}
\begin{code}
separateByPtrFollowness :: [(CgRep,a)] -> ([(CgRep,a)], [(CgRep,a)])
-- Returns (ptrs, non-ptrs)
separateByPtrFollowness things
= sep_things things [] []
-- accumulating params for follow-able and don't-follow things...
where
sep_things [] bs us = (reverse bs, reverse us)
sep_things ((PtrArg,a):ts) bs us = sep_things ts ((PtrArg,a):bs) us
sep_things (t :ts) bs us = sep_things ts bs (t:us)
\end{code}
\begin{code}
cgRepSizeB :: CgRep -> ByteOff
cgRepSizeB DoubleArg = dOUBLE_SIZE
cgRepSizeB LongArg = wORD64_SIZE
cgRepSizeB VoidArg = 0
cgRepSizeB _ = wORD_SIZE
cgRepSizeW :: CgRep -> ByteOff
cgRepSizeW DoubleArg = dOUBLE_SIZE `quot` wORD_SIZE
cgRepSizeW LongArg = wORD64_SIZE `quot` wORD_SIZE
cgRepSizeW VoidArg = 0
cgRepSizeW _ = 1
retAddrSizeW :: WordOff
retAddrSizeW = 1 -- One word
\end{code}
%************************************************************************
%* *
\subsection[ClosureInfo-construction]{Functions which build LFInfos}
......
......@@ -241,7 +241,7 @@ mkRhsClosure bndr cc bi
body@(StgApp fun_id args)
| args `lengthIs` (arity-1)
&& all isFollowableArg (map (idCgRep . stripNV) fvs)
&& all (isGcPtrRep . idPrimRep . stripNV) fvs
&& isUpdatable upd_flag
&& arity <= mAX_SPEC_AP_SIZE
......
......@@ -358,17 +358,6 @@ isLFReEntrant _ = False
-- Choosing SM reps
-----------------------------------------------------------------------------
chooseSMRep
:: Bool -- True <=> static closure
-> LambdaFormInfo
-> WordOff -> WordOff -- Tot wds, ptr wds
-> SMRep
chooseSMRep is_static lf_info tot_wds ptr_wds
= mkHeapRep is_static ptr_wds nonptr_wds (lfClosureType lf_info)
where
nonptr_wds = tot_wds - ptr_wds
lfClosureType :: LambdaFormInfo -> ClosureTypeInfo
lfClosureType (LFReEntrant _ arity _ argd) = Fun (fromIntegral arity) argd
lfClosureType (LFCon con) = Constr (fromIntegral (dataConTagZ con))
......
......@@ -35,7 +35,6 @@ import DataCon
import ForeignCall
import Id
import PrimOp
import SMRep
import TyCon
import Type
import CostCentre ( CostCentreStack, currentCCS )
......@@ -317,7 +316,7 @@ cgCase (StgApp v []) bndr _ alt_type@(PrimAlt _) alts
; _ <- bindArgsToRegs [NonVoid bndr]
; cgAlts NoGcInAlts (NonVoid bndr) alt_type alts }
where
reps_compatible = idCgRep v == idCgRep bndr
reps_compatible = idPrimRep v == idPrimRep bndr
cgCase scrut@(StgApp v []) _ _ (PrimAlt _) _
= -- fail at run-time, not compile-time
......
......@@ -38,7 +38,6 @@ import StgCmmUtils
import MkGraph
import SMRep
import Cmm
import CmmUtils
import CLabel
import StgSyn
import Id
......@@ -240,6 +239,9 @@ lRepSizeW L = wORD64_SIZE `quot` wORD_SIZE
lRepSizeW D = dOUBLE_SIZE `quot` wORD_SIZE
lRepSizeW V = 0
idLRep :: Id -> LRep
idLRep = toLRep . idPrimRep
-------------------------------------------------------------------------
---- Laying out objects on the heap and stack
-------------------------------------------------------------------------
......@@ -314,7 +316,7 @@ mkArgDescr _nm args
Nothing -> return (ArgGen arg_bits)
where
arg_bits = argBits arg_reps
arg_reps = filter isNonV (map (toLRep . idPrimRep) args)
arg_reps = filter isNonV (map idLRep args)
-- Getting rid of voids eases matching of standard patterns
argBits :: [LRep] -> [Bool] -- True for non-ptr, False for ptr
......
......@@ -247,6 +247,7 @@ tickySlowCallPat _args = return ()
(str, True) -> bumpTickyCounter' (mkRtsSlowTickyCtrLabel pat)
(str, False) -> bumpTickyCounter (sLit "TICK_SLOW_CALL_OTHER")
-- Don't use CgRep; put this function in StgCmmLayout
callPattern :: [CgRep] -> (String,Bool)
callPattern reps
| match == length reps = (chars, True)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment