83d2b72747cc8135db62d8314effa2c9150b603e
[ghc-hetmet.git] / compiler / codeGen / CgMonad.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %
5 \section[CgMonad]{The code generation monad}
6
7 See the beginning of the top-level @CodeGen@ module, to see how this
8 monadic stuff fits into the Big Picture.
9
10 \begin{code}
11 module CgMonad (
12         Code,   -- type
13         FCode,  -- type
14
15         initC, thenC, thenFC, listCs, listFCs, mapCs, mapFCs,
16         returnFC, fixC, fixC_, checkedAbsC, 
17         stmtC, stmtsC, labelC, emitStmts, nopC, whenC, newLabelC,
18         newUnique, newUniqSupply, 
19
20         CgStmts, emitCgStmts, forkCgStmts, cgStmtsToBlocks,
21         getCgStmts', getCgStmts,
22         noCgStmts, oneCgStmt, consCgStmt,
23
24         getCmm,
25         emitData, emitProc, emitSimpleProc,
26
27         forkLabelledCode,
28         forkClosureBody, forkStatics, forkAlts, forkEval,
29         forkEvalHelp, forkProc, codeOnly,
30         SemiTaggingStuff, ConTagZ,
31
32         EndOfBlockInfo(..),
33         setEndOfBlockInfo, getEndOfBlockInfo,
34
35         setSRT, getSRT,
36         setSRTLabel, getSRTLabel, 
37         setTickyCtrLabel, getTickyCtrLabel,
38
39         StackUsage(..), HeapUsage(..),
40         VirtualSpOffset, VirtualHpOffset,
41         initStkUsage, initHpUsage,
42         getHpUsage,  setHpUsage,
43         heapHWM,
44
45         getModuleName,
46
47         Sequel(..), -- ToDo: unabstract?
48
49         -- ideally we wouldn't export these, but some other modules access internal state
50         getState, setState, getInfoDown, getDynFlags, getThisPackage, 
51
52         -- more localised access to monad state 
53         getStkUsage, setStkUsage,
54         getBinds, setBinds, getStaticBinds,
55
56         -- out of general friendliness, we also export ...
57         CgInfoDownwards(..), CgState(..)        -- non-abstract
58     ) where
59
60 #include "HsVersions.h"
61
62 import {-# SOURCE #-} CgBindery ( CgBindings, nukeVolatileBinds )
63
64 import DynFlags
65 import BlockId
66 import Cmm
67 import CmmUtils
68 import CLabel
69 import StgSyn (SRT)
70 import SMRep
71 import Module
72 import Id
73 import VarEnv
74 import OrdList
75 import Unique
76 import Util()
77 import UniqSupply
78 import FastString()
79 import Outputable
80
81 import Control.Monad
82 import Data.List
83
84 infixr 9 `thenC`        -- Right-associative!
85 infixr 9 `thenFC`
86 \end{code}
87
88 %************************************************************************
89 %*                                                                      *
90 \subsection[CgMonad-environment]{Stuff for manipulating environments}
91 %*                                                                      *
92 %************************************************************************
93
94 This monadery has some information that it only passes {\em
95 downwards}, as well as some ``state'' which is modified as we go
96 along.
97
98 \begin{code}
99 data CgInfoDownwards    -- information only passed *downwards* by the monad
100   = MkCgInfoDown {
101         cgd_dflags  :: DynFlags,
102         cgd_mod     :: Module,          -- Module being compiled
103         cgd_statics :: CgBindings,      -- [Id -> info] : static environment
104         cgd_srt_lbl :: CLabel,          -- label of the current SRT
105         cgd_srt     :: SRT,             -- the current SRT
106         cgd_ticky   :: CLabel,          -- current destination for ticky counts
107         cgd_eob     :: EndOfBlockInfo   -- Info for stuff to do at end of basic block:
108   }
109
110 initCgInfoDown :: DynFlags -> Module -> CgInfoDownwards
111 initCgInfoDown dflags mod
112   = MkCgInfoDown {      cgd_dflags  = dflags,
113                         cgd_mod     = mod,
114                         cgd_statics = emptyVarEnv,
115                         cgd_srt_lbl = error "initC: srt_lbl",
116                         cgd_srt     = error "initC: srt",
117                         cgd_ticky   = mkTopTickyCtrLabel,
118                         cgd_eob     = initEobInfo }
119
120 data CgState
121   = MkCgState {
122      cgs_stmts :: OrdList CgStmt,         -- Current proc
123      cgs_tops  :: OrdList CmmTop,
124         -- Other procedures and data blocks in this compilation unit
125         -- Both the latter two are ordered only so that we can 
126         -- reduce forward references, when it's easy to do so
127      
128      cgs_binds :: CgBindings,   -- [Id -> info] : *local* bindings environment
129                                 -- Bindings for top-level things are given in
130                                 -- the info-down part
131      
132      cgs_stk_usg :: StackUsage,
133      cgs_hp_usg  :: HeapUsage,
134      
135      cgs_uniqs :: UniqSupply }
136
137 initCgState :: UniqSupply -> CgState
138 initCgState uniqs
139   = MkCgState { cgs_stmts = nilOL, cgs_tops = nilOL,
140                 cgs_binds = emptyVarEnv, 
141                 cgs_stk_usg = initStkUsage, 
142                 cgs_hp_usg = initHpUsage,
143                 cgs_uniqs = uniqs }
144 \end{code}
145
146 @EndOfBlockInfo@ tells what to do at the end of this block of code or,
147 if the expression is a @case@, what to do at the end of each
148 alternative.
149
150 \begin{code}
151 data EndOfBlockInfo
152   = EndOfBlockInfo
153         VirtualSpOffset   -- Args Sp: trim the stack to this point at a
154                           -- return; push arguments starting just
155                           -- above this point on a tail call.
156                           
157                           -- This is therefore the stk ptr as seen
158                           -- by a case alternative.
159         Sequel
160
161 initEobInfo :: EndOfBlockInfo
162 initEobInfo = EndOfBlockInfo 0 OnStack
163 \end{code}
164
165 Any addressing modes inside @Sequel@ must be ``robust,'' in the sense
166 that it must survive stack pointer adjustments at the end of the
167 block.
168
169 \begin{code}
170 data Sequel
171   = OnStack             -- Continuation is on the stack
172   | UpdateCode          -- Continuation is update
173
174   | CaseAlts
175           CLabel     -- Jump to this; if the continuation is for a vectored
176                      -- case this might be the label of a return vector
177           SemiTaggingStuff
178           Id          -- The case binder, only used to see if it's dead
179
180 type SemiTaggingStuff
181   = Maybe                       -- Maybe[1] we don't have any semi-tagging stuff...
182      ([(ConTagZ, CmmLit)],      -- Alternatives
183       CmmLit)                   -- Default (will be a can't happen RTS label if can't happen)
184
185 type ConTagZ = Int      -- A *zero-indexed* contructor tag
186
187 -- The case branch is executed only from a successful semitagging
188 -- venture, when a case has looked at a variable, found that it's
189 -- evaluated, and wants to load up the contents and go to the join
190 -- point.
191 \end{code}
192
193 %************************************************************************
194 %*                                                                      *
195                 CgStmt type
196 %*                                                                      *
197 %************************************************************************
198
199 The CgStmts type is what the code generator outputs: it is a tree of
200 statements, including in-line labels.  The job of flattenCgStmts is to
201 turn this into a list of basic blocks, each of which ends in a jump
202 statement (either a local branch or a non-local jump).
203
204 \begin{code}
205 type CgStmts = OrdList CgStmt
206
207 data CgStmt
208   = CgStmt  CmmStmt
209   | CgLabel BlockId
210   | CgFork  BlockId CgStmts
211
212 flattenCgStmts :: BlockId -> CgStmts -> [CmmBasicBlock]
213 flattenCgStmts id stmts = 
214         case flatten (fromOL stmts) of
215           ([],blocks)    -> blocks
216           (block,blocks) -> BasicBlock id block : blocks
217  where
218   flatten [] = ([],[])
219
220   -- A label at the end of a function or fork: this label must not be reachable,
221   -- but it might be referred to from another BB that also isn't reachable.
222   -- Eliminating these has to be done with a dead-code analysis.  For now,
223   -- we just make it into a well-formed block by adding a recursive jump.
224   flatten [CgLabel id]
225     = ( [CmmBranch id], [BasicBlock id [CmmBranch id]] )
226
227   -- A jump/branch: throw away all the code up to the next label, because
228   -- it is unreachable.  Be careful to keep forks that we find on the way.
229   flatten (CgStmt stmt : stmts)
230     | isJump stmt
231     = case dropWhile isOrdinaryStmt stmts of
232         []                     -> ( [stmt], [] )
233         [CgLabel id]           -> ( [stmt], [BasicBlock id [CmmBranch id]])
234         (CgLabel id : stmts)   -> ( [stmt], BasicBlock id block : blocks )
235             where (block,blocks) = flatten stmts
236         (CgFork fork_id stmts : ss) -> 
237            flatten (CgFork fork_id stmts : CgStmt stmt : ss)
238         (CgStmt {} : _) -> panic "CgStmt not seen as ordinary"
239
240   flatten (s:ss) = 
241         case s of
242           CgStmt stmt -> (stmt:block,blocks)
243           CgLabel id  -> ([CmmBranch id],BasicBlock id block:blocks)
244           CgFork fork_id stmts -> 
245                 (block, BasicBlock fork_id fork_block : fork_blocks ++ blocks)
246                 where (fork_block, fork_blocks) = flatten (fromOL stmts)
247     where (block,blocks) = flatten ss
248
249 isJump :: CmmStmt -> Bool
250 isJump (CmmJump _ _) = True
251 isJump (CmmBranch _) = True
252 isJump (CmmSwitch _ _) = True
253 isJump (CmmReturn _) = True
254 isJump _ = False
255
256 isOrdinaryStmt :: CgStmt -> Bool
257 isOrdinaryStmt (CgStmt _) = True
258 isOrdinaryStmt _ = False
259 \end{code}
260
261 %************************************************************************
262 %*                                                                      *
263                 Stack and heap models
264 %*                                                                      *
265 %************************************************************************
266
267 \begin{code}
268 type VirtualHpOffset = WordOff  -- Both are in
269 type VirtualSpOffset = WordOff  -- units of words
270
271 data StackUsage 
272   = StackUsage {
273         virtSp :: VirtualSpOffset,
274                 -- Virtual offset of topmost allocated slot
275
276         frameSp :: VirtualSpOffset,
277                 -- Virtual offset of the return address of the enclosing frame.
278                 -- This RA describes the liveness/pointedness of
279                 -- all the stack from frameSp downwards
280                 -- INVARIANT: less than or equal to virtSp
281
282          freeStk :: [VirtualSpOffset], 
283                 -- List of free slots, in *increasing* order
284                 -- INVARIANT: all <= virtSp
285                 -- All slots <= virtSp are taken except these ones
286
287          realSp :: VirtualSpOffset,     
288                 -- Virtual offset of real stack pointer register
289
290          hwSp :: VirtualSpOffset
291   }                -- Highest value ever taken by virtSp
292
293 -- INVARIANT: The environment contains no Stable references to
294 --            stack slots below (lower offset) frameSp
295 --            It can contain volatile references to this area though.
296
297 data HeapUsage =
298   HeapUsage {
299         virtHp :: VirtualHpOffset,      -- Virtual offset of highest-allocated word
300         realHp :: VirtualHpOffset       -- realHp: Virtual offset of real heap ptr
301   }
302 \end{code}
303
304 The heap high water mark is the larger of virtHp and hwHp.  The latter is
305 only records the high water marks of forked-off branches, so to find the
306 heap high water mark you have to take the max of virtHp and hwHp.  Remember,
307 virtHp never retreats!
308
309 Note Jan 04: ok, so why do we only look at the virtual Hp??
310
311 \begin{code}
312 heapHWM :: HeapUsage -> VirtualHpOffset
313 heapHWM = virtHp
314 \end{code}
315
316 Initialisation.
317
318 \begin{code}
319 initStkUsage :: StackUsage
320 initStkUsage = StackUsage {
321                         virtSp = 0,
322                         frameSp = 0,
323                         freeStk = [],
324                         realSp = 0,
325                         hwSp = 0
326                }
327                 
328 initHpUsage :: HeapUsage 
329 initHpUsage = HeapUsage {
330                 virtHp = 0,
331                 realHp = 0
332               }
333 \end{code}
334
335 @stateIncUsage@$~e_1~e_2$ incorporates in $e_1$ the stack and heap high water
336 marks found in $e_2$.
337
338 \begin{code}
339 stateIncUsage :: CgState -> CgState -> CgState
340 stateIncUsage s1 s2@(MkCgState { cgs_stk_usg = stk_usg, cgs_hp_usg = hp_usg })
341      = s1 { cgs_hp_usg  = cgs_hp_usg  s1 `maxHpHw`  virtHp hp_usg,
342             cgs_stk_usg = cgs_stk_usg s1 `maxStkHw` hwSp   stk_usg }
343        `addCodeBlocksFrom` s2
344                 
345 stateIncUsageEval :: CgState -> CgState -> CgState
346 stateIncUsageEval s1 s2
347      = s1 { cgs_stk_usg = cgs_stk_usg s1 `maxStkHw` hwSp (cgs_stk_usg s2) }
348        `addCodeBlocksFrom` s2
349         -- We don't max the heap high-watermark because stateIncUsageEval is
350         -- used only in forkEval, which in turn is only used for blocks of code
351         -- which do their own heap-check.
352
353 addCodeBlocksFrom :: CgState -> CgState -> CgState
354 -- Add code blocks from the latter to the former
355 -- (The cgs_stmts will often be empty, but not always; see codeOnly)
356 s1 `addCodeBlocksFrom` s2
357   = s1 { cgs_stmts = cgs_stmts s1 `appOL` cgs_stmts s2,
358          cgs_tops  = cgs_tops  s1 `appOL` cgs_tops  s2 }
359
360 maxHpHw :: HeapUsage -> VirtualHpOffset -> HeapUsage
361 hp_usg `maxHpHw` hw = hp_usg { virtHp = virtHp hp_usg `max` hw }
362
363 maxStkHw :: StackUsage -> VirtualSpOffset -> StackUsage
364 stk_usg `maxStkHw` hw = stk_usg { hwSp = hwSp stk_usg `max` hw }
365 \end{code}
366
367 %************************************************************************
368 %*                                                                      *
369                 The FCode monad
370 %*                                                                      *
371 %************************************************************************
372
373 \begin{code}
374 newtype FCode a = FCode (CgInfoDownwards -> CgState -> (a, CgState))
375 type Code       = FCode ()
376
377 instance Monad FCode where
378         (>>=) = thenFC
379         return = returnFC
380
381 {-# INLINE thenC #-}
382 {-# INLINE thenFC #-}
383 {-# INLINE returnFC #-}
384 \end{code}
385 The Abstract~C is not in the environment so as to improve strictness.
386
387 \begin{code}
388 initC :: DynFlags -> Module -> FCode a -> IO a
389
390 initC dflags mod (FCode code)
391   = do  { uniqs <- mkSplitUniqSupply 'c'
392         ; case code (initCgInfoDown dflags mod) (initCgState uniqs) of
393               (res, _) -> return res
394         }
395
396 returnFC :: a -> FCode a
397 returnFC val = FCode (\_ state -> (val, state))
398 \end{code}
399
400 \begin{code}
401 thenC :: Code -> FCode a -> FCode a
402 thenC (FCode m) (FCode k) = 
403         FCode (\info_down state -> let (_,new_state) = m info_down state in 
404                 k info_down new_state)
405
406 listCs :: [Code] -> Code
407 listCs [] = return ()
408 listCs (fc:fcs) = do
409         fc
410         listCs fcs
411         
412 mapCs :: (a -> Code) -> [a] -> Code
413 mapCs = mapM_
414 \end{code}
415
416 \begin{code}
417 thenFC  :: FCode a -> (a -> FCode c) -> FCode c
418 thenFC (FCode m) k = FCode (
419         \info_down state ->
420                 let 
421                         (m_result, new_state) = m info_down state
422                         (FCode kcode) = k m_result
423                 in 
424                         kcode info_down new_state
425         )
426
427 listFCs :: [FCode a] -> FCode [a]
428 listFCs = sequence
429
430 mapFCs :: (a -> FCode b) -> [a] -> FCode [b]
431 mapFCs = mapM
432 \end{code}
433
434 And the knot-tying combinator:
435 \begin{code}
436 fixC :: (a -> FCode a) -> FCode a
437 fixC fcode = FCode (
438         \info_down state -> 
439                 let
440                         FCode fc = fcode v
441                         result@(v,_) = fc info_down state
442                         --          ^--------^
443                 in
444                         result
445         )
446
447 fixC_ :: (a -> FCode a) -> FCode ()
448 fixC_ fcode = fixC fcode >> return ()
449 \end{code}
450
451 %************************************************************************
452 %*                                                                      *
453         Operators for getting and setting the state and "info_down".
454
455 %*                                                                      *
456 %************************************************************************
457
458 \begin{code}
459 getState :: FCode CgState
460 getState = FCode $ \_ state -> (state,state)
461
462 setState :: CgState -> FCode ()
463 setState state = FCode $ \_ _ -> ((),state)
464
465 getStkUsage :: FCode StackUsage
466 getStkUsage = do
467         state <- getState
468         return $ cgs_stk_usg state
469
470 setStkUsage :: StackUsage -> Code
471 setStkUsage new_stk_usg = do
472         state <- getState
473         setState $ state {cgs_stk_usg = new_stk_usg}
474
475 getHpUsage :: FCode HeapUsage
476 getHpUsage = do
477         state <- getState
478         return $ cgs_hp_usg state
479         
480 setHpUsage :: HeapUsage -> Code
481 setHpUsage new_hp_usg = do
482         state <- getState
483         setState $ state {cgs_hp_usg = new_hp_usg}
484
485 getBinds :: FCode CgBindings
486 getBinds = do
487         state <- getState
488         return $ cgs_binds state
489         
490 setBinds :: CgBindings -> FCode ()
491 setBinds new_binds = do
492         state <- getState
493         setState $ state {cgs_binds = new_binds}
494
495 getStaticBinds :: FCode CgBindings
496 getStaticBinds = do
497         info  <- getInfoDown
498         return (cgd_statics info)
499
500 withState :: FCode a -> CgState -> FCode (a,CgState)
501 withState (FCode fcode) newstate = FCode $ \info_down state -> 
502         let (retval, state2) = fcode info_down newstate in ((retval,state2), state)
503
504 newUniqSupply :: FCode UniqSupply
505 newUniqSupply = do
506         state <- getState
507         let (us1, us2) = splitUniqSupply (cgs_uniqs state)
508         setState $ state { cgs_uniqs = us1 }
509         return us2
510
511 newUnique :: FCode Unique
512 newUnique = do
513         us <- newUniqSupply
514         return (uniqFromSupply us)
515
516 ------------------
517 getInfoDown :: FCode CgInfoDownwards
518 getInfoDown = FCode $ \info_down state -> (info_down,state)
519
520 getDynFlags :: FCode DynFlags
521 getDynFlags = liftM cgd_dflags getInfoDown
522
523 getThisPackage :: FCode PackageId
524 getThisPackage = liftM thisPackage getDynFlags
525
526 withInfoDown :: FCode a -> CgInfoDownwards -> FCode a
527 withInfoDown (FCode fcode) info_down = FCode $ \_ state -> fcode info_down state 
528
529 doFCode :: FCode a -> CgInfoDownwards -> CgState -> (a,CgState)
530 doFCode (FCode fcode) info_down state = fcode info_down state
531 \end{code}
532
533
534 %************************************************************************
535 %*                                                                      *
536                 Forking
537 %*                                                                      *
538 %************************************************************************
539
540 @forkClosureBody@ takes a code, $c$, and compiles it in a completely
541 fresh environment, except that:
542         - compilation info and statics are passed in unchanged.
543 The current environment is passed on completely unaltered, except that
544 abstract C from the fork is incorporated.
545
546 @forkProc@ takes a code and compiles it in the current environment,
547 returning the basic blocks thus constructed.  The current environment
548 is passed on completely unchanged.  It is pretty similar to
549 @getBlocks@, except that the latter does affect the environment.
550
551 @forkStatics@ $fc$ compiles $fc$ in an environment whose statics come
552 from the current bindings, but which is otherwise freshly initialised.
553 The Abstract~C returned is attached to the current state, but the
554 bindings and usage information is otherwise unchanged.
555
556 \begin{code}
557 forkClosureBody :: Code -> Code
558 forkClosureBody body_code
559   = do  { info <- getInfoDown
560         ; us   <- newUniqSupply
561         ; state <- getState
562         ; let   body_info_down = info { cgd_eob = initEobInfo }
563                 ((),fork_state) = doFCode body_code body_info_down 
564                                           (initCgState us)
565         ; ASSERT( isNilOL (cgs_stmts fork_state) )
566           setState $ state `addCodeBlocksFrom` fork_state }
567         
568 forkStatics :: FCode a -> FCode a
569 forkStatics body_code
570   = do  { info  <- getInfoDown
571         ; us    <- newUniqSupply
572         ; state <- getState
573         ; let   rhs_info_down = info { cgd_statics = cgs_binds state,
574                                        cgd_eob     = initEobInfo }
575                 (result, fork_state_out) = doFCode body_code rhs_info_down 
576                                                    (initCgState us)
577         ; ASSERT( isNilOL (cgs_stmts fork_state_out) )
578           setState (state `addCodeBlocksFrom` fork_state_out)
579         ; return result }
580
581 forkProc :: Code -> FCode CgStmts
582 forkProc body_code
583   = do  { info_down <- getInfoDown
584         ; us    <- newUniqSupply
585         ; state <- getState
586         ; let   fork_state_in = (initCgState us) 
587                                         { cgs_binds   = cgs_binds state,
588                                           cgs_stk_usg = cgs_stk_usg state,
589                                           cgs_hp_usg  = cgs_hp_usg state }
590                         -- ToDo: is the hp usage necesary?
591                 (code_blks, fork_state_out) = doFCode (getCgStmts body_code) 
592                                                       info_down fork_state_in
593         ; setState $ state `stateIncUsageEval` fork_state_out
594         ; return code_blks }
595
596 codeOnly :: Code -> Code
597 -- Emit any code from the inner thing into the outer thing
598 -- Do not affect anything else in the outer state
599 -- Used in almost-circular code to prevent false loop dependencies
600 codeOnly body_code
601   = do  { info_down <- getInfoDown
602         ; us   <- newUniqSupply
603         ; state <- getState
604         ; let   fork_state_in = (initCgState us) { cgs_binds   = cgs_binds state,
605                                                    cgs_stk_usg = cgs_stk_usg state,
606                                                    cgs_hp_usg  = cgs_hp_usg state }
607                 ((), fork_state_out) = doFCode body_code info_down fork_state_in
608         ; setState $ state `addCodeBlocksFrom` fork_state_out }
609 \end{code}
610
611 @forkAlts@ $bs~d$ takes fcodes $bs$ for the branches of a @case@, and
612 an fcode for the default case $d$, and compiles each in the current
613 environment.  The current environment is passed on unmodified, except
614 that
615         - the worst stack high-water mark is incorporated
616         - the virtual Hp is moved on to the worst virtual Hp for the branches
617
618 \begin{code}
619 forkAlts :: [FCode a] -> FCode [a]
620
621 forkAlts branch_fcodes
622   = do  { info_down <- getInfoDown
623         ; us <- newUniqSupply
624         ; state <- getState
625         ; let compile us branch 
626                 = (us2, doFCode branch info_down branch_state)
627                 where
628                   (us1,us2) = splitUniqSupply us
629                   branch_state = (initCgState us1) {
630                                         cgs_binds   = cgs_binds state,
631                                         cgs_stk_usg = cgs_stk_usg state,
632                                         cgs_hp_usg  = cgs_hp_usg state }
633
634               (_us, results) = mapAccumL compile us branch_fcodes
635               (branch_results, branch_out_states) = unzip results
636         ; setState $ foldl stateIncUsage state branch_out_states
637                 -- NB foldl.  state is the *left* argument to stateIncUsage
638         ; return branch_results }
639 \end{code}
640
641 @forkEval@ takes two blocks of code.
642
643    -  The first meddles with the environment to set it up as expected by
644       the alternatives of a @case@ which does an eval (or gc-possible primop).
645    -  The second block is the code for the alternatives.
646       (plus info for semi-tagging purposes)
647
648 @forkEval@ picks up the virtual stack pointer and returns a suitable
649 @EndOfBlockInfo@ for the caller to use, together with whatever value
650 is returned by the second block.
651
652 It uses @initEnvForAlternatives@ to initialise the environment, and
653 @stateIncUsageAlt@ to incorporate usage; the latter ignores the heap
654 usage.
655
656 \begin{code}
657 forkEval :: EndOfBlockInfo              -- For the body
658          -> Code                        -- Code to set environment
659          -> FCode Sequel                -- Semi-tagging info to store
660          -> FCode EndOfBlockInfo        -- The new end of block info
661
662 forkEval body_eob_info env_code body_code
663   = do  { (v, sequel) <- forkEvalHelp body_eob_info env_code body_code
664         ; returnFC (EndOfBlockInfo v sequel) }
665
666 forkEvalHelp :: EndOfBlockInfo  -- For the body
667              -> Code            -- Code to set environment
668              -> FCode a         -- The code to do after the eval
669              -> FCode (VirtualSpOffset, -- Sp
670                        a)               -- Result of the FCode
671         -- A disturbingly complicated function
672 forkEvalHelp body_eob_info env_code body_code
673   = do  { info_down <- getInfoDown
674         ; us   <- newUniqSupply
675         ; state <- getState
676         ; let { info_down_for_body = info_down {cgd_eob = body_eob_info}
677               ; (_, env_state) = doFCode env_code info_down_for_body 
678                                          (state {cgs_uniqs = us})
679               ; state_for_body = (initCgState (cgs_uniqs env_state)) 
680                                         { cgs_binds   = binds_for_body,
681                                           cgs_stk_usg = stk_usg_for_body }
682               ; binds_for_body   = nukeVolatileBinds (cgs_binds env_state)
683               ; stk_usg_from_env = cgs_stk_usg env_state
684               ; virtSp_from_env  = virtSp stk_usg_from_env
685               ; stk_usg_for_body = stk_usg_from_env {realSp = virtSp_from_env,
686                                                      hwSp   = virtSp_from_env}
687               ; (value_returned, state_at_end_return)
688                         = doFCode body_code info_down_for_body state_for_body           
689           } 
690         ; ASSERT( isNilOL (cgs_stmts state_at_end_return) )
691                  -- The code coming back should consist only of nested declarations,
692                  -- notably of the return vector!
693           setState $ state `stateIncUsageEval` state_at_end_return
694         ; return (virtSp_from_env, value_returned) }
695
696
697 -- ----------------------------------------------------------------------------
698 -- Combinators for emitting code
699
700 nopC :: Code
701 nopC = return ()
702
703 whenC :: Bool -> Code -> Code
704 whenC True  code = code
705 whenC False _    = nopC
706
707 stmtC :: CmmStmt -> Code
708 stmtC stmt = emitCgStmt (CgStmt stmt)
709
710 labelC :: BlockId -> Code
711 labelC id = emitCgStmt (CgLabel id)
712
713 newLabelC :: FCode BlockId
714 newLabelC = do { u <- newUnique
715                ; return $ BlockId u }
716
717 checkedAbsC :: CmmStmt -> Code
718 -- Emit code, eliminating no-ops
719 checkedAbsC stmt = emitStmts (if isNopStmt stmt then nilOL
720                               else unitOL stmt)
721
722 stmtsC :: [CmmStmt] -> Code
723 stmtsC stmts = emitStmts (toOL stmts)
724
725 -- Emit code; no no-op checking
726 emitStmts :: CmmStmts -> Code
727 emitStmts stmts = emitCgStmts (fmap CgStmt stmts)
728
729 -- forkLabelledCode is for emitting a chunk of code with a label, outside
730 -- of the current instruction stream.
731 forkLabelledCode :: Code -> FCode BlockId
732 forkLabelledCode code = getCgStmts code >>= forkCgStmts
733
734 emitCgStmt :: CgStmt -> Code
735 emitCgStmt stmt
736   = do  { state <- getState
737         ; setState $ state { cgs_stmts = cgs_stmts state `snocOL` stmt }
738         }
739
740 emitData :: Section -> [CmmStatic] -> Code
741 emitData sect lits
742   = do  { state <- getState
743         ; setState $ state { cgs_tops = cgs_tops state `snocOL` data_block } }
744   where
745     data_block = CmmData sect lits
746
747 emitProc :: CmmInfo -> CLabel -> CmmFormals -> [CmmBasicBlock] -> Code
748 emitProc info lbl args blocks
749   = do  { let proc_block = CmmProc info lbl args (ListGraph blocks)
750         ; state <- getState
751         ; setState $ state { cgs_tops = cgs_tops state `snocOL` proc_block } }
752
753 emitSimpleProc :: CLabel -> Code -> Code
754 -- Emit a procedure whose body is the specified code; no info table
755 emitSimpleProc lbl code
756   = do  { stmts <- getCgStmts code
757         ; blks <- cgStmtsToBlocks stmts
758         ; emitProc (CmmInfo Nothing Nothing CmmNonInfoTable) lbl [] blks }
759
760 getCmm :: Code -> FCode Cmm
761 -- Get all the CmmTops (there should be no stmts)
762 -- Return a single Cmm which may be split from other Cmms by
763 -- object splitting (at a later stage)
764 getCmm code 
765   = do  { state1 <- getState
766         ; ((), state2) <- withState code (state1 { cgs_tops  = nilOL })
767         ; setState $ state2 { cgs_tops = cgs_tops state1 } 
768         ; return (Cmm (fromOL (cgs_tops state2))) 
769         }
770
771 -- ----------------------------------------------------------------------------
772 -- CgStmts
773
774 -- These functions deal in terms of CgStmts, which is an abstract type
775 -- representing the code in the current proc.
776
777
778 -- emit CgStmts into the current instruction stream
779 emitCgStmts :: CgStmts -> Code
780 emitCgStmts stmts
781   = do  { state <- getState
782         ; setState $ state { cgs_stmts = cgs_stmts state `appOL` stmts } }
783
784 -- emit CgStmts outside the current instruction stream, and return a label
785 forkCgStmts :: CgStmts -> FCode BlockId
786 forkCgStmts stmts
787   = do  { id <- newLabelC
788         ; emitCgStmt (CgFork id stmts)
789         ; return id
790         }
791
792 -- turn CgStmts into [CmmBasicBlock], for making a new proc.
793 cgStmtsToBlocks :: CgStmts -> FCode [CmmBasicBlock]
794 cgStmtsToBlocks stmts
795   = do  { id <- newLabelC
796         ; return (flattenCgStmts id stmts)
797         }       
798
799 -- collect the code emitted by an FCode computation
800 getCgStmts' :: FCode a -> FCode (a, CgStmts)
801 getCgStmts' fcode
802   = do  { state1 <- getState
803         ; (a, state2) <- withState fcode (state1 { cgs_stmts = nilOL })
804         ; setState $ state2 { cgs_stmts = cgs_stmts state1  }
805         ; return (a, cgs_stmts state2) }
806
807 getCgStmts :: FCode a -> FCode CgStmts
808 getCgStmts fcode = do { (_,stmts) <- getCgStmts' fcode; return stmts }
809
810 -- Simple ways to construct CgStmts:
811 noCgStmts :: CgStmts
812 noCgStmts = nilOL
813
814 oneCgStmt :: CmmStmt -> CgStmts
815 oneCgStmt stmt = unitOL (CgStmt stmt)
816
817 consCgStmt :: CmmStmt -> CgStmts -> CgStmts
818 consCgStmt stmt stmts = CgStmt stmt `consOL` stmts
819
820 -- ----------------------------------------------------------------------------
821 -- Get the current module name
822
823 getModuleName :: FCode Module
824 getModuleName = do { info <- getInfoDown; return (cgd_mod info) }
825
826 -- ----------------------------------------------------------------------------
827 -- Get/set the end-of-block info
828
829 setEndOfBlockInfo :: EndOfBlockInfo -> Code -> Code
830 setEndOfBlockInfo eob_info code = do
831         info  <- getInfoDown
832         withInfoDown code (info {cgd_eob = eob_info})
833
834 getEndOfBlockInfo :: FCode EndOfBlockInfo
835 getEndOfBlockInfo = do
836         info <- getInfoDown
837         return (cgd_eob info)
838
839 -- ----------------------------------------------------------------------------
840 -- Get/set the current SRT label
841
842 -- There is just one SRT for each top level binding; all the nested
843 -- bindings use sub-sections of this SRT.  The label is passed down to
844 -- the nested bindings via the monad.
845
846 getSRTLabel :: FCode CLabel     -- Used only by cgPanic
847 getSRTLabel = do info  <- getInfoDown
848                  return (cgd_srt_lbl info)
849
850 setSRTLabel :: CLabel -> FCode a -> FCode a
851 setSRTLabel srt_lbl code
852   = do  info <- getInfoDown
853         withInfoDown code (info { cgd_srt_lbl = srt_lbl})
854
855 getSRT :: FCode SRT
856 getSRT = do info <- getInfoDown
857             return (cgd_srt info)
858
859 setSRT :: SRT -> FCode a -> FCode a
860 setSRT srt code
861   = do info <- getInfoDown
862        withInfoDown code (info { cgd_srt = srt})
863
864 -- ----------------------------------------------------------------------------
865 -- Get/set the current ticky counter label
866
867 getTickyCtrLabel :: FCode CLabel
868 getTickyCtrLabel = do
869         info <- getInfoDown
870         return (cgd_ticky info)
871
872 setTickyCtrLabel :: CLabel -> Code -> Code
873 setTickyCtrLabel ticky code = do
874         info <- getInfoDown
875         withInfoDown code (info {cgd_ticky = ticky})
876 \end{code}