[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / compiler / absCSyn / AbsCSyn.lhs
diff --git a/ghc/compiler/absCSyn/AbsCSyn.lhs b/ghc/compiler/absCSyn/AbsCSyn.lhs
deleted file mode 100644 (file)
index 3c8a470..0000000
+++ /dev/null
@@ -1,540 +0,0 @@
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
-%
-% $Id: AbsCSyn.lhs,v 1.56 2003/11/17 14:47:53 simonmar Exp $
-%
-\section[AbstractC]{Abstract C: the last stop before machine code}
-
-This ``Abstract C'' data type describes the raw Spineless Tagless
-machine model at a C-ish level; it is ``abstract'' in that it only
-includes C-like structures that we happen to need.  The conversion of
-programs from @StgSyntax@ (basically a functional language) to
-@AbstractC@ (basically imperative C) is the heart of code generation.
-From @AbstractC@, one may convert to real C (for portability) or to
-raw assembler/machine code.
-
-\begin{code}
-module AbsCSyn where   -- export everything
-
-#include "HsVersions.h"
-
-import {-# SOURCE #-} ClosureInfo ( ClosureInfo )
-
-import CLabel
-import Constants       ( mAX_Vanilla_REG, mAX_Float_REG,
-                         mAX_Double_REG, spRelToInt )
-import CostCentre       ( CostCentre, CostCentreStack )
-import Literal         ( mkMachInt, Literal(..) )
-import ForeignCall     ( CCallSpec )
-import PrimRep         ( PrimRep(..) )
-import MachOp          ( MachOp(..) )
-import Unique           ( Unique )
-import StgSyn          ( StgOp )
-import TyCon           ( TyCon )
-import Bitmap          ( Bitmap, mAX_SMALL_BITMAP_SIZE )
-import SMRep           ( StgWord, StgHalfWord )
-import FastTypes
-import FastString
-\end{code}
-
-@AbstractC@ is a list of Abstract~C statements, but the data structure
-is tree-ish, for easier and more efficient putting-together.
-\begin{code}
-data AbstractC
-  = AbsCNop
-  | AbsCStmts          AbstractC AbstractC
-
-  -- and the individual stmts...
-\end{code}
-
-A note on @CAssign@: In general, the type associated with an assignment
-is the type of the lhs.  However, when the lhs is a pointer to mixed
-types (e.g. SpB relative), the type of the assignment is the type of
-the rhs for float types, or the generic StgWord for all other types.
-(In particular, a CharRep on the rhs is promoted to IntRep when
-stored in a mixed type location.)
-
-\begin{code}
-  | CAssign
-       !CAddrMode      -- target
-       !CAddrMode      -- source
-
-  | CJump
-       CAddrMode       -- Put this in the program counter
-                       -- eg `CJump (CReg (VanillaReg PtrRep 1))' puts Ret1 in PC
-                       -- Enter can be done by:
-                       --        CJump (CVal NodeRel zeroOff)
-
-  | CFallThrough
-       CAddrMode       -- Fall through into this routine
-                       -- (for the benefit of the native code generators)
-                       -- Equivalent to CJump in C land
-
-  | CReturn            -- Perform a return
-       CAddrMode       -- Address of a RET_<blah> info table
-       ReturnInfo      -- Whether it's a direct or vectored return
-
-  | CSwitch !CAddrMode
-       [(Literal, AbstractC)]  -- alternatives
-       AbstractC               -- default; if there is no real Abstract C in here
-                               -- (e.g., all comments; see function "nonemptyAbsC"),
-                               -- then that means the default _cannot_ occur.
-                               -- If there is only one alternative & no default code,
-                               -- then there is no need to check the tag.
-                               -- Therefore, e.g.:
-                               --  CSwitch m [(tag,code)] AbsCNop == code
-
-  | CCodeBlock CLabel AbstractC
-                       -- A labelled block of code; this "statement" is not
-                       -- executed; rather, the labelled code will be hoisted
-                       -- out to the top level (out of line) & it can be
-                       -- jumped to.
-
-  | CInitHdr           -- to initialise the header of a closure (both fixed/var parts)
-       ClosureInfo
-       CAddrMode       -- address of the info ptr
-       !CAddrMode      -- cost centre to place in closure
-                       --   CReg CurCostCentre or CC_HDR(R1.p{-Node-})
-       Int             -- size of closure, for profiling
-
-  -- NEW CASES FOR EXPANDED PRIMOPS
-
-  | CMachOpStmt                        -- Machine-level operation
-       CAddrMode               -- result
-       MachOp
-       [CAddrMode]             -- Arguments
-        (Maybe [MagicId])      -- list of regs which need to be preserved
-       -- across the primop.  This is allowed to be Nothing only if
-       -- machOpIsDefinitelyInline returns True.  And that in turn may
-       -- only return True if we are absolutely sure that the mach op
-       -- can be done inline on all platforms.  
-
-  | CSequential                -- Do the nested AbstractCs sequentially.
-       [AbstractC]     -- In particular, as far as the AbsCUtils.doSimultaneously
-                       -- is concerned, these stmts are to be treated as atomic
-                       -- and are not to be reordered.
-
-  -- end of NEW CASES FOR EXPANDED PRIMOPS
-
-  | COpStmt
-       [CAddrMode]     -- Results
-       StgOp
-       [CAddrMode]     -- Arguments
-       [MagicId]       -- Potentially volatile/live registers
-                       -- (to save/restore around the call/op)
-
-       -- INVARIANT: When a PrimOp which can cause GC is used, the
-       -- only live data is tidily on the STG stacks or in the STG
-       -- registers (the code generator ensures this).
-       --
-       -- Why this?  Because if the arguments were arbitrary
-       -- addressing modes, they might be things like (Hp+6) which
-       -- will get utterly spongled by GC.
-
-  | CSimultaneous      -- Perform simultaneously all the statements
-       AbstractC       -- in the nested AbstractC.  They are only
-                       -- allowed to be CAssigns, COpStmts and AbsCNops, so the
-                       -- "simultaneous" part just concerns making
-                       -- sure that permutations work.
-                       -- For example { a := b, b := a }
-                       --      needs to go via (at least one) temporary
-
-  | CCheck             -- heap or stack checks, or both.  
-       CCheckMacro     -- These might include some code to fill in tags 
-       [CAddrMode]     -- on the stack, so we can't use CMacroStmt below.
-       AbstractC
-
-  | CRetDirect                 -- Direct return
-        !Unique                        -- for making labels
-       AbstractC               -- return code
-       C_SRT                   -- SRT info
-       Liveness                -- stack liveness at the return point
-
-  -- see the notes about these next few; they follow below...
-  | CMacroStmt         CStmtMacro      [CAddrMode]
-  | CCallProfCtrMacro  FastString      [CAddrMode]
-  | CCallProfCCMacro   FastString      [CAddrMode]
-
-    {- The presence of this constructor is a makeshift solution;
-       it being used to work around a gcc-related problem of
-       handling typedefs within statement blocks (or, rather,
-       the inability to do so.)
-       
-       The AbstractC flattener takes care of lifting out these
-       typedefs if needs be (i.e., when generating .hc code and
-       compiling 'foreign import dynamic's)
-    -}
-  | CCallTypedef Bool {- True => use "typedef"; False => use "extern"-}
-                CCallSpec Unique [CAddrMode] [CAddrMode]
-
-  -- *** the next three [or so...] are DATA (those above are CODE) ***
-
-  | CStaticClosure
-       CLabel                  -- The closure's label
-       ClosureInfo             -- Todo: maybe info_lbl & closure_lbl instead?
-       CAddrMode               -- cost centre identifier to place in closure
-       [CAddrMode]             -- free vars; ptrs, then non-ptrs.
-
-  | CSRT CLabel [CLabel]       -- SRT declarations: basically an array of 
-                               -- pointers to static closures.
-  
-  | CBitmap Liveness           -- A "large" bitmap to be emitted
-
-  | CSRTDesc                   -- A "large" SRT descriptor (one that doesn't
-                               -- fit into the half-word bitmap in the itbl).
-       !CLabel                 -- Label for this SRT descriptor
-       !CLabel                 -- Pointer to the SRT
-       !Int                    -- Offset within the SRT
-       !Int                    -- Length
-       !Bitmap                 -- Bitmap
-
-  | CClosureInfoAndCode
-       ClosureInfo             -- Explains placement and layout of closure
-       AbstractC               -- Entry point code
-
-  | CRetVector                 -- A labelled block of static data
-       CLabel
-       [CAddrMode]
-       C_SRT                   -- SRT info
-       Liveness                -- stack liveness at the return point
-
-  | CClosureTbl                -- table of constructors for enumerated types
-       TyCon                   -- which TyCon this table is for
-
-  | CModuleInitBlock           -- module initialisation block
-       CLabel                  -- "plain" label for init block
-       CLabel                  -- label for init block (with ver + way info)
-       AbstractC               -- initialisation code
-
-  | CCostCentreDecl            -- A cost centre *declaration*
-       Bool                    -- True  <=> local => full declaration
-                               -- False <=> extern; just say so
-       CostCentre
-
-  | CCostCentreStackDecl       -- A cost centre stack *declaration*
-       CostCentreStack         -- this is the declaration for a
-                               -- pre-defined singleton CCS (see 
-                               -- CostCentre.lhs)
-
-  | CSplitMarker               -- Split into separate object modules here
-
--- C_SRT is what StgSyn.SRT gets translated to... 
--- we add a label for the table, and expect only the 'offset/length' form
-
-data C_SRT = NoC_SRT
-          | C_SRT !CLabel !Int{-offset-} !StgHalfWord{-bitmap or escape-}
-
-needsSRT :: C_SRT -> Bool
-needsSRT NoC_SRT       = False
-needsSRT (C_SRT _ _ _) = True
-\end{code}
-
-About @CMacroStmt@, etc.: notionally, they all just call some
-arbitrary C~macro or routine, passing the @CAddrModes@ as arguments.
-However, we distinguish between various flavours of these things,
-mostly just to keep things somewhat less wild and wooly.
-
-\begin{description}
-\item[@CMacroStmt@:]
-Some {\em essential} bits of the STG execution model are done with C
-macros.  An example is @STK_CHK@, which checks for stack-space
-overflow.  This enumeration type lists all such macros:
-\begin{code}
-data CStmtMacro
-  = UPD_CAF                            -- update CAF closure with indirection
-  | UPD_BH_UPDATABLE                   -- eager backholing
-  | UPD_BH_SINGLE_ENTRY                        -- more eager blackholing
-  | PUSH_UPD_FRAME                     -- push update frame
-  | SET_TAG                            -- set TagReg if it exists
-      -- dataToTag# primop -- *only* used in unregisterised builds.
-      -- (see AbsCUtils.dsCOpStmt)
-  | DATA_TO_TAGZH
-
-  | REGISTER_FOREIGN_EXPORT            -- register a foreign exported fun
-  | REGISTER_IMPORT                    -- register an imported module
-  | REGISTER_DIMPORT                    -- register an imported module from
-                                        -- another DLL
-
-  | GRAN_FETCH                 -- for GrAnSim only  -- HWL
-  | GRAN_RESCHEDULE            -- for GrAnSim only  -- HWL
-  | GRAN_FETCH_AND_RESCHEDULE  -- for GrAnSim only  -- HWL
-  | THREAD_CONTEXT_SWITCH      -- for GrAnSim only  -- HWL
-  | GRAN_YIELD                 -- for GrAnSim only  -- HWL 
-\end{code}
-
-Heap/Stack checks.  There are far too many of these.
-
-\begin{code}
-data CCheckMacro
-
-  = HP_CHK_NP                          -- heap/stack checks when
-  | STK_CHK_NP                         -- node points to the closure
-  | HP_STK_CHK_NP
-
-  | HP_CHK_FUN                         -- heap/stack checks when
-  | STK_CHK_FUN                                -- node doesn't point
-  | HP_STK_CHK_FUN
-                                       -- case alternative heap checks:
-
-  | HP_CHK_NOREGS                      --   no registers live
-  | HP_CHK_UNPT_R1                     --   R1 is boxed/unlifted
-  | HP_CHK_UNBX_R1                     --   R1 is unboxed
-  | HP_CHK_F1                          --   FloatReg1 (only) is live 
-  | HP_CHK_D1                          --   DblReg1   (only) is live
-  | HP_CHK_L1                          --   LngReg1   (only) is live
-
-  | HP_CHK_UNBX_TUPLE                  -- unboxed tuple heap check
-\end{code}
-
-\item[@CCallProfCtrMacro@:]
-The @String@ names a macro that, if \tr{#define}d, will bump one/some
-of the STG-event profiling counters.
-
-\item[@CCallProfCCMacro@:]
-The @String@ names a macro that, if \tr{#define}d, will perform some
-cost-centre-profiling-related action.
-\end{description}
-
-%************************************************************************
-%*                                                                     *
-\subsection[CAddrMode]{C addressing modes}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-data CAddrMode
-  = CVal  RegRelative PrimRep
-                       -- On RHS of assign: Contents of Magic[n]
-                       -- On LHS of assign: location Magic[n]
-                       -- (ie at addr Magic+n)
-
-  | CAddr RegRelative
-                       -- On RHS of assign: Address of Magic[n]; ie Magic+n
-                       --      n=0 gets the Magic location itself
-                       --      (NB: n=0 case superceded by CReg)
-                       -- On LHS of assign: only sensible if n=0,
-                       --      which gives the magic location itself
-                       --      (NB: superceded by CReg)
-
-             -- JRS 2002-02-05: CAddr is really scummy and should be fixed.
-             -- The effect is that the semantics of CAddr depend on what the
-             -- contained RegRelative is; it is decidely non-orthogonal.
-
-  | CReg MagicId       -- To replace (CAddr MagicId 0)
-
-  | CTemp !Unique !PrimRep     -- Temporary locations
-       -- ``Temporaries'' correspond to local variables in C, and registers in
-       -- native code.
-
-  | CLbl    CLabel     -- Labels in the runtime system, etc.
-           PrimRep     -- the kind is so we can generate accurate C decls
-
-  | CCharLike CAddrMode        -- The address of a static char-like closure for
-                       -- the specified character.  It is guaranteed to be in
-                       -- the range mIN_CHARLIKE..mAX_CHARLIKE
-
-  | CIntLike CAddrMode -- The address of a static int-like closure for the
-                       -- specified small integer.  It is guaranteed to be in
-                       -- the range mIN_INTLIKE..mAX_INTLIKE
-
-  | CLit    Literal
-
-  | CJoinPoint         -- This is used as the amode of a let-no-escape-bound
-                       -- variable.
-       VirtualSpOffset   -- Sp value after any volatile free vars
-                         -- of the rhs have been saved on stack.
-                         -- Just before the code for the thing is jumped to,
-                         -- Sp will be set to this value,
-                         -- and then any stack-passed args pushed,
-                         -- then the code for this thing will be entered
-  | CMacroExpr
-       !PrimRep        -- the kind of the result
-       CExprMacro      -- the macro to generate a value
-       [CAddrMode]     -- and its arguments
-\end{code}
-
-Various C macros for values which are dependent on the back-end layout.
-
-\begin{code}
-
-data CExprMacro
-  = ENTRY_CODE
-  | ARG_TAG                            -- stack argument tagging
-  | GET_TAG                            -- get current constructor tag
-  | CCS_HDR
-  | BYTE_ARR_CTS               -- used when passing a ByteArray# to a ccall
-  | PTRS_ARR_CTS               -- similarly for an Array#
-  | ForeignObj_CLOSURE_DATA    -- and again for a ForeignObj#
-\end{code}
-
-Convenience functions:
-
-\begin{code}
-mkIntCLit :: Int -> CAddrMode
-mkIntCLit i = CLit (mkMachInt (toInteger i))
-
-mkWordCLit :: StgWord -> CAddrMode
-mkWordCLit wd = CLit (MachWord (fromIntegral wd))
-
-mkCString :: FastString -> CAddrMode
-mkCString s = CLit (MachStr s)
-
-mkCCostCentre :: CostCentre -> CAddrMode
-mkCCostCentre cc = CLbl (mkCC_Label cc) DataPtrRep
-
-mkCCostCentreStack :: CostCentreStack -> CAddrMode
-mkCCostCentreStack ccs = CLbl (mkCCS_Label ccs) DataPtrRep
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[RegRelative]{@RegRelatives@: ???}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-data RegRelative
-  = HpRel      FastInt -- }
-  | SpRel      FastInt -- }- offsets in StgWords
-  | NodeRel    FastInt -- }
-  | CIndex     CAddrMode CAddrMode PrimRep     -- pointer arithmetic :-)
-                                               -- CIndex a b k === (k*)a[b]
-
-data ReturnInfo
-  = DirectReturn                       -- Jump directly, if possible
-  | StaticVectoredReturn Int           -- Fixed tag, starting at zero
-  | DynamicVectoredReturn CAddrMode    -- Dynamic tag given by amode, starting at zero
-
-hpRel :: VirtualHeapOffset     -- virtual offset of Hp
-      -> VirtualHeapOffset     -- virtual offset of The Thing
-      -> RegRelative           -- integer offset
-hpRel hp off = HpRel (iUnbox (hp - off))
-
-spRel :: VirtualSpOffset       -- virtual offset of Sp
-      -> VirtualSpOffset       -- virtual offset of The Thing
-      -> RegRelative           -- integer offset
-spRel sp off = SpRel (iUnbox (spRelToInt sp off))
-
-nodeRel :: VirtualHeapOffset
-        -> RegRelative
-nodeRel off = NodeRel (iUnbox off)
-
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[Liveness]{Liveness Masks}
-%*                                                                     *
-%************************************************************************
-
-We represent liveness bitmaps as a BitSet (whose internal
-representation really is a bitmap).  These are pinned onto case return
-vectors to indicate the state of the stack for the garbage collector.
-
-In the compiled program, liveness bitmaps that fit inside a single
-word (StgWord) are stored as a single word, while larger bitmaps are
-stored as a pointer to an array of words. 
-
-\begin{code}
-data Liveness = Liveness CLabel !Int Bitmap
-
-maybeLargeBitmap :: Liveness -> AbstractC
-maybeLargeBitmap liveness@(Liveness _ size _)
-  | size <= mAX_SMALL_BITMAP_SIZE = AbsCNop
-  | otherwise                     = CBitmap liveness
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[HeapOffset]{@Heap Offsets@}
-%*                                                                     *
-%************************************************************************
-
-This used to be a grotesquely complicated datatype in an attempt to
-hide the details of header sizes from the compiler itself.  Now these
-constants are imported from the RTS, and we deal in real Ints.
-
-\begin{code}
-type HeapOffset = Int                  -- ToDo: remove
-
-type VirtualHeapOffset = HeapOffset
-type VirtualSpOffset   = Int
-\end{code}
-
-%************************************************************************
-%*                                                                     *
-\subsection[MagicId]{@MagicIds@: registers and such}
-%*                                                                     *
-%************************************************************************
-
-\begin{code}
-data MagicId
-  = BaseReg    -- mentioned only in nativeGen
-
-  -- Argument and return registers
-  | VanillaReg         -- pointers, unboxed ints and chars
-       PrimRep
-       FastInt -- its number (1 .. mAX_Vanilla_REG)
-
-  | FloatReg           -- single-precision floating-point registers
-       FastInt -- its number (1 .. mAX_Float_REG)
-
-  | DoubleReg          -- double-precision floating-point registers
-       FastInt -- its number (1 .. mAX_Double_REG)
-
-  -- STG registers
-  | Sp                 -- Stack ptr; points to last occupied stack location.
-  | SpLim              -- Stack limit
-  | Hp                 -- Heap ptr; points to last occupied heap location.
-  | HpLim              -- Heap limit register
-  | CurCostCentre      -- current cost centre register.
-  | VoidReg            -- see "VoidPrim" type; just a placeholder; 
-                       --   no actual register
-  | LongReg            -- long int registers (64-bit, really)
-       PrimRep         -- Int64Rep or Word64Rep
-       FastInt -- its number (1 .. mAX_Long_REG)
-
-  | CurrentTSO         -- pointer to current thread's TSO
-  | CurrentNursery     -- pointer to allocation area
-  | HpAlloc            -- allocation count for heap check failure
-
-
-node   = VanillaReg PtrRep     (_ILIT 1) -- A convenient alias for Node
-tagreg  = VanillaReg WordRep    (_ILIT 2) -- A convenient alias for TagReg
-
-nodeReg = CReg node
-\end{code}
-
-We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
-
-\begin{code}
-instance Eq MagicId where
-    reg1 == reg2 = tag reg1 ==# tag reg2
-     where
-       tag BaseReg          = (_ILIT(0) :: FastInt)
-       tag Sp               = _ILIT(1)
-       tag SpLim            = _ILIT(3)
-       tag Hp               = _ILIT(4)
-       tag HpLim            = _ILIT(5)
-       tag CurCostCentre    = _ILIT(6)
-       tag VoidReg          = _ILIT(7)
-
-       tag (VanillaReg _ i) = _ILIT(8) +# i
-
-       tag (FloatReg i)  = _ILIT(8) +# maxv +# i
-       tag (DoubleReg i) = _ILIT(8) +# maxv +# maxf +# i
-       tag (LongReg _ i) = _ILIT(8) +# maxv +# maxf +# maxd +# i
-
-        maxv = iUnbox mAX_Vanilla_REG
-        maxf = iUnbox mAX_Float_REG
-        maxd = iUnbox mAX_Double_REG
-\end{code}
-
-Returns True for any register that {\em potentially} dies across
-C calls (or anything near equivalent).  We just say @True@ and
-let the (machine-specific) registering macros sort things out...
-
-\begin{code}
-isVolatileReg :: MagicId -> Bool
-isVolatileReg any = True
-\end{code}