[project @ 2003-07-18 14:39:05 by simonmar]
[ghc-hetmet.git] / ghc / compiler / absCSyn / AbsCSyn.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 % $Id: AbsCSyn.lhs,v 1.54 2003/07/18 14:39:06 simonmar Exp $
5 %
6 \section[AbstractC]{Abstract C: the last stop before machine code}
7
8 This ``Abstract C'' data type describes the raw Spineless Tagless
9 machine model at a C-ish level; it is ``abstract'' in that it only
10 includes C-like structures that we happen to need.  The conversion of
11 programs from @StgSyntax@ (basically a functional language) to
12 @AbstractC@ (basically imperative C) is the heart of code generation.
13 From @AbstractC@, one may convert to real C (for portability) or to
14 raw assembler/machine code.
15
16 \begin{code}
17 module AbsCSyn where    -- export everything
18
19 #include "HsVersions.h"
20
21 import {-# SOURCE #-} ClosureInfo ( ClosureInfo )
22
23 import CLabel
24 import Constants        ( mAX_Vanilla_REG, mAX_Float_REG,
25                           mAX_Double_REG, spRelToInt )
26 import CostCentre       ( CostCentre, CostCentreStack )
27 import Literal          ( mkMachInt, Literal(..) )
28 import ForeignCall      ( CCallSpec )
29 import PrimRep          ( PrimRep(..) )
30 import MachOp           ( MachOp(..) )
31 import Unique           ( Unique )
32 import StgSyn           ( StgOp )
33 import TyCon            ( TyCon )
34 import Bitmap           ( Bitmap, mAX_SMALL_BITMAP_SIZE )
35 import SMRep            ( StgWord, StgHalfWord )
36 import FastTypes
37 import FastString
38 \end{code}
39
40 @AbstractC@ is a list of Abstract~C statements, but the data structure
41 is tree-ish, for easier and more efficient putting-together.
42 \begin{code}
43 absCNop = AbsCNop
44
45 data AbstractC
46   = AbsCNop
47   | AbsCStmts           AbstractC AbstractC
48
49   -- and the individual stmts...
50 \end{code}
51
52 A note on @CAssign@: In general, the type associated with an assignment
53 is the type of the lhs.  However, when the lhs is a pointer to mixed
54 types (e.g. SpB relative), the type of the assignment is the type of
55 the rhs for float types, or the generic StgWord for all other types.
56 (In particular, a CharRep on the rhs is promoted to IntRep when
57 stored in a mixed type location.)
58
59 \begin{code}
60   | CAssign
61         !CAddrMode      -- target
62         !CAddrMode      -- source
63
64   | CJump
65         CAddrMode       -- Put this in the program counter
66                         -- eg `CJump (CReg (VanillaReg PtrRep 1))' puts Ret1 in PC
67                         -- Enter can be done by:
68                         --        CJump (CVal NodeRel zeroOff)
69
70   | CFallThrough
71         CAddrMode       -- Fall through into this routine
72                         -- (for the benefit of the native code generators)
73                         -- Equivalent to CJump in C land
74
75   | CReturn             -- Perform a return
76         CAddrMode       -- Address of a RET_<blah> info table
77         ReturnInfo      -- Whether it's a direct or vectored return
78
79   | CSwitch !CAddrMode
80         [(Literal, AbstractC)]  -- alternatives
81         AbstractC               -- default; if there is no real Abstract C in here
82                                 -- (e.g., all comments; see function "nonemptyAbsC"),
83                                 -- then that means the default _cannot_ occur.
84                                 -- If there is only one alternative & no default code,
85                                 -- then there is no need to check the tag.
86                                 -- Therefore, e.g.:
87                                 --  CSwitch m [(tag,code)] AbsCNop == code
88
89   | CCodeBlock CLabel AbstractC
90                         -- A labelled block of code; this "statement" is not
91                         -- executed; rather, the labelled code will be hoisted
92                         -- out to the top level (out of line) & it can be
93                         -- jumped to.
94
95   | CInitHdr            -- to initialise the header of a closure (both fixed/var parts)
96         ClosureInfo
97         CAddrMode       -- address of the info ptr
98         !CAddrMode      -- cost centre to place in closure
99                         --   CReg CurCostCentre or CC_HDR(R1.p{-Node-})
100         Int             -- size of closure, for profiling
101
102   -- NEW CASES FOR EXPANDED PRIMOPS
103
104   | CMachOpStmt                 -- Machine-level operation
105         CAddrMode               -- result
106         MachOp
107         [CAddrMode]             -- Arguments
108         (Maybe [MagicId])       -- list of regs which need to be preserved
109         -- across the primop.  This is allowed to be Nothing only if
110         -- machOpIsDefinitelyInline returns True.  And that in turn may
111         -- only return True if we are absolutely sure that the mach op
112         -- can be done inline on all platforms.  
113
114   | CSequential         -- Do the nested AbstractCs sequentially.
115         [AbstractC]     -- In particular, as far as the AbsCUtils.doSimultaneously
116                         -- is concerned, these stmts are to be treated as atomic
117                         -- and are not to be reordered.
118
119   -- end of NEW CASES FOR EXPANDED PRIMOPS
120
121   | COpStmt
122         [CAddrMode]     -- Results
123         StgOp
124         [CAddrMode]     -- Arguments
125         [MagicId]       -- Potentially volatile/live registers
126                         -- (to save/restore around the call/op)
127
128         -- INVARIANT: When a PrimOp which can cause GC is used, the
129         -- only live data is tidily on the STG stacks or in the STG
130         -- registers (the code generator ensures this).
131         --
132         -- Why this?  Because if the arguments were arbitrary
133         -- addressing modes, they might be things like (Hp+6) which
134         -- will get utterly spongled by GC.
135
136   | CSimultaneous       -- Perform simultaneously all the statements
137         AbstractC       -- in the nested AbstractC.  They are only
138                         -- allowed to be CAssigns, COpStmts and AbsCNops, so the
139                         -- "simultaneous" part just concerns making
140                         -- sure that permutations work.
141                         -- For example { a := b, b := a }
142                         --      needs to go via (at least one) temporary
143
144   | CCheck              -- heap or stack checks, or both.  
145         CCheckMacro     -- These might include some code to fill in tags 
146         [CAddrMode]     -- on the stack, so we can't use CMacroStmt below.
147         AbstractC
148
149   | CRetDirect                  -- Direct return
150         !Unique                 -- for making labels
151         AbstractC               -- return code
152         C_SRT                   -- SRT info
153         Liveness                -- stack liveness at the return point
154
155   -- see the notes about these next few; they follow below...
156   | CMacroStmt          CStmtMacro      [CAddrMode]
157   | CCallProfCtrMacro   FastString      [CAddrMode]
158   | CCallProfCCMacro    FastString      [CAddrMode]
159
160     {- The presence of this constructor is a makeshift solution;
161        it being used to work around a gcc-related problem of
162        handling typedefs within statement blocks (or, rather,
163        the inability to do so.)
164        
165        The AbstractC flattener takes care of lifting out these
166        typedefs if needs be (i.e., when generating .hc code and
167        compiling 'foreign import dynamic's)
168     -}
169   | CCallTypedef Bool {- True => use "typedef"; False => use "extern"-}
170                  CCallSpec Unique [CAddrMode] [CAddrMode]
171
172   -- *** the next three [or so...] are DATA (those above are CODE) ***
173
174   | CStaticClosure
175         CLabel                  -- The closure's label
176         ClosureInfo             -- Todo: maybe info_lbl & closure_lbl instead?
177         CAddrMode               -- cost centre identifier to place in closure
178         [CAddrMode]             -- free vars; ptrs, then non-ptrs.
179
180   | CSRT CLabel [CLabel]        -- SRT declarations: basically an array of 
181                                 -- pointers to static closures.
182   
183   | CBitmap Liveness            -- A "large" bitmap to be emitted
184
185   | CSRTDesc                    -- A "large" SRT descriptor (one that doesn't
186                                 -- fit into the half-word bitmap in the itbl).
187         !CLabel                 -- Label for this SRT descriptor
188         !CLabel                 -- Pointer to the SRT
189         !Int                    -- Offset within the SRT
190         !Int                    -- Length
191         !Bitmap                 -- Bitmap
192
193   | CClosureInfoAndCode
194         ClosureInfo             -- Explains placement and layout of closure
195         AbstractC               -- Entry point code
196
197   | CRetVector                  -- A labelled block of static data
198         CLabel
199         [CAddrMode]
200         C_SRT                   -- SRT info
201         Liveness                -- stack liveness at the return point
202
203   | CClosureTbl                 -- table of constructors for enumerated types
204         TyCon                   -- which TyCon this table is for
205
206   | CModuleInitBlock            -- module initialisation block
207         CLabel                  -- "plain" label for init block
208         CLabel                  -- label for init block (with ver + way info)
209         AbstractC               -- initialisation code
210
211   | CCostCentreDecl             -- A cost centre *declaration*
212         Bool                    -- True  <=> local => full declaration
213                                 -- False <=> extern; just say so
214         CostCentre
215
216   | CCostCentreStackDecl        -- A cost centre stack *declaration*
217         CostCentreStack         -- this is the declaration for a
218                                 -- pre-defined singleton CCS (see 
219                                 -- CostCentre.lhs)
220
221   | CSplitMarker                -- Split into separate object modules here
222
223 -- C_SRT is what StgSyn.SRT gets translated to... 
224 -- we add a label for the table, and expect only the 'offset/length' form
225
226 data C_SRT = NoC_SRT
227            | C_SRT !CLabel !Int{-offset-} !StgHalfWord{-bitmap or escape-}
228
229 needsSRT :: C_SRT -> Bool
230 needsSRT NoC_SRT       = False
231 needsSRT (C_SRT _ _ _) = True
232 \end{code}
233
234 About @CMacroStmt@, etc.: notionally, they all just call some
235 arbitrary C~macro or routine, passing the @CAddrModes@ as arguments.
236 However, we distinguish between various flavours of these things,
237 mostly just to keep things somewhat less wild and wooly.
238
239 \begin{description}
240 \item[@CMacroStmt@:]
241 Some {\em essential} bits of the STG execution model are done with C
242 macros.  An example is @STK_CHK@, which checks for stack-space
243 overflow.  This enumeration type lists all such macros:
244 \begin{code}
245 data CStmtMacro
246   = UPD_CAF                             -- update CAF closure with indirection
247   | UPD_BH_UPDATABLE                    -- eager backholing
248   | UPD_BH_SINGLE_ENTRY                 -- more eager blackholing
249   | PUSH_UPD_FRAME                      -- push update frame
250   | SET_TAG                             -- set TagReg if it exists
251       -- dataToTag# primop -- *only* used in unregisterised builds.
252       -- (see AbsCUtils.dsCOpStmt)
253   | DATA_TO_TAGZH
254   | AWAKEN_BQ_CLOSURE                   -- possibly awaken a blocking quuee
255                                         -- (used for in-place updates)
256
257   | REGISTER_FOREIGN_EXPORT             -- register a foreign exported fun
258   | REGISTER_IMPORT                     -- register an imported module
259   | REGISTER_DIMPORT                    -- register an imported module from
260                                         -- another DLL
261
262   | GRAN_FETCH                  -- for GrAnSim only  -- HWL
263   | GRAN_RESCHEDULE             -- for GrAnSim only  -- HWL
264   | GRAN_FETCH_AND_RESCHEDULE   -- for GrAnSim only  -- HWL
265   | THREAD_CONTEXT_SWITCH       -- for GrAnSim only  -- HWL
266   | GRAN_YIELD                  -- for GrAnSim only  -- HWL 
267 \end{code}
268
269 Heap/Stack checks.  There are far too many of these.
270
271 \begin{code}
272 data CCheckMacro
273
274   = HP_CHK_NP                           -- heap/stack checks when
275   | STK_CHK_NP                          -- node points to the closure
276   | HP_STK_CHK_NP
277
278   | HP_CHK_FUN                          -- heap/stack checks when
279   | STK_CHK_FUN                         -- node doesn't point
280   | HP_STK_CHK_FUN
281                                         -- case alternative heap checks:
282
283   | HP_CHK_NOREGS                       --   no registers live
284   | HP_CHK_UNPT_R1                      --   R1 is boxed/unlifted
285   | HP_CHK_UNBX_R1                      --   R1 is unboxed
286   | HP_CHK_F1                           --   FloatReg1 (only) is live 
287   | HP_CHK_D1                           --   DblReg1   (only) is live
288   | HP_CHK_L1                           --   LngReg1   (only) is live
289
290   | HP_CHK_UNBX_TUPLE                   -- unboxed tuple heap check
291 \end{code}
292
293 \item[@CCallProfCtrMacro@:]
294 The @String@ names a macro that, if \tr{#define}d, will bump one/some
295 of the STG-event profiling counters.
296
297 \item[@CCallProfCCMacro@:]
298 The @String@ names a macro that, if \tr{#define}d, will perform some
299 cost-centre-profiling-related action.
300 \end{description}
301
302 %************************************************************************
303 %*                                                                      *
304 \subsection[CAddrMode]{C addressing modes}
305 %*                                                                      *
306 %************************************************************************
307
308 \begin{code}
309 data CAddrMode
310   = CVal  RegRelative PrimRep
311                         -- On RHS of assign: Contents of Magic[n]
312                         -- On LHS of assign: location Magic[n]
313                         -- (ie at addr Magic+n)
314
315   | CAddr RegRelative
316                         -- On RHS of assign: Address of Magic[n]; ie Magic+n
317                         --      n=0 gets the Magic location itself
318                         --      (NB: n=0 case superceded by CReg)
319                         -- On LHS of assign: only sensible if n=0,
320                         --      which gives the magic location itself
321                         --      (NB: superceded by CReg)
322
323              -- JRS 2002-02-05: CAddr is really scummy and should be fixed.
324              -- The effect is that the semantics of CAddr depend on what the
325              -- contained RegRelative is; it is decidely non-orthogonal.
326
327   | CReg MagicId        -- To replace (CAddr MagicId 0)
328
329   | CTemp !Unique !PrimRep      -- Temporary locations
330         -- ``Temporaries'' correspond to local variables in C, and registers in
331         -- native code.
332
333   | CLbl    CLabel      -- Labels in the runtime system, etc.
334             PrimRep     -- the kind is so we can generate accurate C decls
335
336   | CCharLike CAddrMode -- The address of a static char-like closure for
337                         -- the specified character.  It is guaranteed to be in
338                         -- the range mIN_CHARLIKE..mAX_CHARLIKE
339
340   | CIntLike CAddrMode  -- The address of a static int-like closure for the
341                         -- specified small integer.  It is guaranteed to be in
342                         -- the range mIN_INTLIKE..mAX_INTLIKE
343
344   | CLit    Literal
345
346   | CJoinPoint          -- This is used as the amode of a let-no-escape-bound
347                         -- variable.
348         VirtualSpOffset   -- Sp value after any volatile free vars
349                           -- of the rhs have been saved on stack.
350                           -- Just before the code for the thing is jumped to,
351                           -- Sp will be set to this value,
352                           -- and then any stack-passed args pushed,
353                           -- then the code for this thing will be entered
354   | CMacroExpr
355         !PrimRep        -- the kind of the result
356         CExprMacro      -- the macro to generate a value
357         [CAddrMode]     -- and its arguments
358 \end{code}
359
360 Various C macros for values which are dependent on the back-end layout.
361
362 \begin{code}
363
364 data CExprMacro
365   = ENTRY_CODE
366   | ARG_TAG                             -- stack argument tagging
367   | GET_TAG                             -- get current constructor tag
368   | UPD_FRAME_UPDATEE
369   | CCS_HDR
370   | BYTE_ARR_CTS                -- used when passing a ByteArray# to a ccall
371   | PTRS_ARR_CTS                -- similarly for an Array#
372   | ForeignObj_CLOSURE_DATA     -- and again for a ForeignObj#
373 \end{code}
374
375 Convenience functions:
376
377 \begin{code}
378 mkIntCLit :: Int -> CAddrMode
379 mkIntCLit i = CLit (mkMachInt (toInteger i))
380
381 mkWordCLit :: StgWord -> CAddrMode
382 mkWordCLit wd = CLit (MachWord (fromIntegral wd))
383
384 mkCString :: FastString -> CAddrMode
385 mkCString s = CLit (MachStr s)
386
387 mkCCostCentre :: CostCentre -> CAddrMode
388 mkCCostCentre cc = CLbl (mkCC_Label cc) DataPtrRep
389
390 mkCCostCentreStack :: CostCentreStack -> CAddrMode
391 mkCCostCentreStack ccs = CLbl (mkCCS_Label ccs) DataPtrRep
392 \end{code}
393
394 %************************************************************************
395 %*                                                                      *
396 \subsection[RegRelative]{@RegRelatives@: ???}
397 %*                                                                      *
398 %************************************************************************
399
400 \begin{code}
401 data RegRelative
402   = HpRel       FastInt -- }
403   | SpRel       FastInt -- }- offsets in StgWords
404   | NodeRel     FastInt -- }
405   | CIndex      CAddrMode CAddrMode PrimRep     -- pointer arithmetic :-)
406                                                 -- CIndex a b k === (k*)a[b]
407
408 data ReturnInfo
409   = DirectReturn                        -- Jump directly, if possible
410   | StaticVectoredReturn Int            -- Fixed tag, starting at zero
411   | DynamicVectoredReturn CAddrMode     -- Dynamic tag given by amode, starting at zero
412
413 hpRel :: VirtualHeapOffset      -- virtual offset of Hp
414       -> VirtualHeapOffset      -- virtual offset of The Thing
415       -> RegRelative            -- integer offset
416 hpRel hp off = HpRel (iUnbox (hp - off))
417
418 spRel :: VirtualSpOffset        -- virtual offset of Sp
419       -> VirtualSpOffset        -- virtual offset of The Thing
420       -> RegRelative            -- integer offset
421 spRel sp off = SpRel (iUnbox (spRelToInt sp off))
422
423 nodeRel :: VirtualHeapOffset
424         -> RegRelative
425 nodeRel off = NodeRel (iUnbox off)
426
427 \end{code}
428
429 %************************************************************************
430 %*                                                                      *
431 \subsection[Liveness]{Liveness Masks}
432 %*                                                                      *
433 %************************************************************************
434
435 We represent liveness bitmaps as a BitSet (whose internal
436 representation really is a bitmap).  These are pinned onto case return
437 vectors to indicate the state of the stack for the garbage collector.
438
439 In the compiled program, liveness bitmaps that fit inside a single
440 word (StgWord) are stored as a single word, while larger bitmaps are
441 stored as a pointer to an array of words. 
442
443 \begin{code}
444 data Liveness = Liveness CLabel !Int Bitmap
445
446 maybeLargeBitmap :: Liveness -> AbstractC
447 maybeLargeBitmap liveness@(Liveness _ size _)
448   | size <= mAX_SMALL_BITMAP_SIZE = AbsCNop
449   | otherwise                     = CBitmap liveness
450 \end{code}
451
452 %************************************************************************
453 %*                                                                      *
454 \subsection[HeapOffset]{@Heap Offsets@}
455 %*                                                                      *
456 %************************************************************************
457
458 This used to be a grotesquely complicated datatype in an attempt to
459 hide the details of header sizes from the compiler itself.  Now these
460 constants are imported from the RTS, and we deal in real Ints.
461
462 \begin{code}
463 type HeapOffset = Int                   -- ToDo: remove
464
465 type VirtualHeapOffset  = HeapOffset
466 type VirtualSpOffset    = Int
467
468 type HpRelOffset        = HeapOffset
469 type SpRelOffset        = Int
470 \end{code}
471
472 %************************************************************************
473 %*                                                                      *
474 \subsection[MagicId]{@MagicIds@: registers and such}
475 %*                                                                      *
476 %************************************************************************
477
478 \begin{code}
479 data MagicId
480   = BaseReg     -- mentioned only in nativeGen
481
482   -- Argument and return registers
483   | VanillaReg          -- pointers, unboxed ints and chars
484         PrimRep
485         FastInt -- its number (1 .. mAX_Vanilla_REG)
486
487   | FloatReg            -- single-precision floating-point registers
488         FastInt -- its number (1 .. mAX_Float_REG)
489
490   | DoubleReg           -- double-precision floating-point registers
491         FastInt -- its number (1 .. mAX_Double_REG)
492
493   -- STG registers
494   | Sp                  -- Stack ptr; points to last occupied stack location.
495   | SpLim               -- Stack limit
496   | Hp                  -- Heap ptr; points to last occupied heap location.
497   | HpLim               -- Heap limit register
498   | CurCostCentre       -- current cost centre register.
499   | VoidReg             -- see "VoidPrim" type; just a placeholder; 
500                         --   no actual register
501   | LongReg             -- long int registers (64-bit, really)
502         PrimRep         -- Int64Rep or Word64Rep
503         FastInt -- its number (1 .. mAX_Long_REG)
504
505   | CurrentTSO          -- pointer to current thread's TSO
506   | CurrentNursery      -- pointer to allocation area
507   | HpAlloc             -- allocation count for heap check failure
508
509
510 node    = VanillaReg PtrRep     (_ILIT 1) -- A convenient alias for Node
511 tagreg  = VanillaReg WordRep    (_ILIT 2) -- A convenient alias for TagReg
512
513 nodeReg = CReg node
514 \end{code}
515
516 We need magical @Eq@ because @VanillaReg@s come in multiple flavors.
517
518 \begin{code}
519 instance Eq MagicId where
520     reg1 == reg2 = tag reg1 ==# tag reg2
521      where
522         tag BaseReg          = (_ILIT(0) :: FastInt)
523         tag Sp               = _ILIT(1)
524         tag SpLim            = _ILIT(3)
525         tag Hp               = _ILIT(4)
526         tag HpLim            = _ILIT(5)
527         tag CurCostCentre    = _ILIT(6)
528         tag VoidReg          = _ILIT(7)
529
530         tag (VanillaReg _ i) = _ILIT(8) +# i
531
532         tag (FloatReg i)  = _ILIT(8) +# maxv +# i
533         tag (DoubleReg i) = _ILIT(8) +# maxv +# maxf +# i
534         tag (LongReg _ i) = _ILIT(8) +# maxv +# maxf +# maxd +# i
535
536         maxv = iUnbox mAX_Vanilla_REG
537         maxf = iUnbox mAX_Float_REG
538         maxd = iUnbox mAX_Double_REG
539 \end{code}
540
541 Returns True for any register that {\em potentially} dies across
542 C calls (or anything near equivalent).  We just say @True@ and
543 let the (machine-specific) registering macros sort things out...
544
545 \begin{code}
546 isVolatileReg :: MagicId -> Bool
547 isVolatileReg any = True
548 \end{code}