[project @ 1999-06-08 15:56:44 by simonmar]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgMonad.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 % $Id: CgMonad.lhs,v 1.21 1999/06/08 15:56:47 simonmar Exp $
5 %
6 \section[CgMonad]{The code generation monad}
7
8 See the beginning of the top-level @CodeGen@ module, to see how this
9 monadic stuff fits into the Big Picture.
10
11 \begin{code}
12 module CgMonad (
13         Code,   -- type
14         FCode,  -- type
15
16         initC, thenC, thenFC, listCs, listFCs, mapCs, mapFCs,
17         returnFC, fixC, absC, nopC, getAbsC,
18
19         forkClosureBody, forkStatics, forkAlts, forkEval,
20         forkEvalHelp, forkAbsC,
21         SemiTaggingStuff,
22
23         addBindC, addBindsC, modifyBindC, lookupBindC,
24
25         EndOfBlockInfo(..),
26         setEndOfBlockInfo, getEndOfBlockInfo,
27
28         setSRTLabel, getSRTLabel,
29
30         StackUsage, Slot(..), HeapUsage,
31
32         profCtrC, cgPanic,
33
34         costCentresC, moduleName,
35
36         Sequel(..), -- ToDo: unabstract?
37         sequelToAmode,
38
39         -- out of general friendliness, we also export ...
40         CgInfoDownwards(..), CgState(..),       -- non-abstract
41         CompilationInfo(..)
42     ) where
43
44 #include "HsVersions.h"
45
46 import {-# SOURCE #-} CgBindery ( CgIdInfo(..), CgBindings, maybeStkLoc, nukeVolatileBinds )
47 import {-# SOURCE #-} CgUsages  ( getSpRelOffset )
48
49 import AbsCSyn
50 import AbsCUtils        ( mkAbsCStmts )
51 import CmdLineOpts      ( opt_SccProfilingOn, opt_DoTickyProfiling )
52 import CLabel           ( CLabel, mkUpdInfoLabel, pprCLabel )
53 import Module           ( Module )
54 import DataCon          ( ConTag )
55 import Id               ( Id )
56 import VarEnv
57 import PrimRep          ( PrimRep(..) )
58 import StgSyn           ( StgLiveVars )
59 import Outputable
60
61 infixr 9 `thenC`        -- Right-associative!
62 infixr 9 `thenFC`
63 \end{code}
64
65 %************************************************************************
66 %*                                                                      *
67 \subsection[CgMonad-environment]{Stuff for manipulating environments}
68 %*                                                                      *
69 %************************************************************************
70
71 This monadery has some information that it only passes {\em
72 downwards}, as well as some ``state'' which is modified as we go
73 along.
74
75 \begin{code}
76 data CgInfoDownwards    -- information only passed *downwards* by the monad
77   = MkCgInfoDown
78      CompilationInfo    -- COMPLETELY STATIC info about this compilation
79                         --  (e.g., what flags were passed to the compiler)
80
81      CgBindings         -- [Id -> info] : static environment
82
83      CLabel             -- label of the current SRT
84
85      EndOfBlockInfo     -- Info for stuff to do at end of basic block:
86
87
88 data CompilationInfo
89   = MkCompInfo
90         Module          -- the module name
91
92 data CgState
93   = MkCgState
94         AbstractC       -- code accumulated so far
95         CgBindings      -- [Id -> info] : *local* bindings environment
96                         -- Bindings for top-level things are given in the info-down part
97         CgStksAndHeapUsage
98 \end{code}
99
100 @EndOfBlockInfo@ tells what to do at the end of this block of code or,
101 if the expression is a @case@, what to do at the end of each
102 alternative.
103
104 \begin{code}
105 data EndOfBlockInfo
106   = EndOfBlockInfo
107         VirtualSpOffset   -- Args Sp: trim the stack to this point at a
108                           -- return; push arguments starting just
109                           -- above this point on a tail call.
110                           
111                           -- This is therefore the stk ptr as seen
112                           -- by a case alternative.
113         Sequel
114
115 initEobInfo = EndOfBlockInfo 0 (OnStack 0)
116 \end{code}
117
118 Any addressing modes inside @Sequel@ must be ``robust,'' in the sense
119 that it must survive stack pointer adjustments at the end of the
120 block.
121
122 \begin{code}
123 data Sequel
124   = OnStack 
125         VirtualSpOffset   -- Continuation is on the stack, at the
126                           -- specified location
127
128   | UpdateCode
129
130   | CaseAlts
131           CAddrMode   -- Jump to this; if the continuation is for a vectored
132                       -- case this might be the label of a return
133                       -- vector Guaranteed to be a non-volatile
134                       -- addressing mode (I think)
135           SemiTaggingStuff
136
137   | SeqFrame                    -- like CaseAlts but push a seq frame too.
138           CAddrMode
139           SemiTaggingStuff
140
141 type SemiTaggingStuff
142   = Maybe                           -- Maybe[1] we don't have any semi-tagging stuff...
143      ([(ConTag, JoinDetails)],      -- Alternatives
144       Maybe (Maybe Id, JoinDetails) -- Default (but Maybe[2] we don't have one)
145                                     -- Maybe[3] the default is a
146                                     -- bind-default (Just b); that is,
147                                     -- it expects a ptr to the thing
148                                     -- in Node, bound to b
149      )
150
151 type JoinDetails
152   = (AbstractC, CLabel)         -- Code to load regs from heap object + profiling macros,
153                                 -- and join point label
154
155 -- The abstract C is executed only from a successful semitagging
156 -- venture, when a case has looked at a variable, found that it's
157 -- evaluated, and wants to load up the contents and go to the join
158 -- point.
159
160 -- DIRE WARNING.
161 -- The OnStack case of sequelToAmode delivers an Amode which is only
162 -- valid just before the final control transfer, because it assumes
163 -- that Sp is pointing to the top word of the return address.  This
164 -- seems unclean but there you go.
165
166 -- sequelToAmode returns an amode which refers to an info table.  The info
167 -- table will always be of the RET(_VEC)?_(BIG|SMALL) kind.  We're careful
168 -- not to handle real code pointers, just in case we're compiling for 
169 -- an unregisterised/untailcallish architecture, where info pointers and
170 -- code pointers aren't the same.
171
172 sequelToAmode :: Sequel -> FCode CAddrMode
173
174 sequelToAmode (OnStack virt_sp_offset)
175   = getSpRelOffset virt_sp_offset `thenFC` \ sp_rel ->
176     returnFC (CVal sp_rel RetRep)
177
178 sequelToAmode UpdateCode = returnFC (CLbl mkUpdInfoLabel RetRep)
179 sequelToAmode (CaseAlts amode _) = returnFC amode
180 sequelToAmode (SeqFrame _ _) = cgPanic (text "sequelToAmode: SeqFrame")
181
182 type CgStksAndHeapUsage         -- stacks and heap usage information
183   = (StackUsage, HeapUsage)
184
185 data Slot = Free | NonPointer deriving (Eq,Show)
186
187 type StackUsage =
188         (Int,              -- virtSp: Virtual offset of topmost allocated slot
189          [(Int,Slot)],     -- free:   List of free slots, in increasing order
190          Int,              -- realSp: Virtual offset of real stack pointer
191          Int)              -- hwSp:   Highest value ever taken by virtSp
192
193 type HeapUsage =
194         (HeapOffset,    -- virtHp: Virtual offset of highest-allocated word
195          HeapOffset)    -- realHp: Virtual offset of real heap ptr
196 \end{code}
197
198 NB: absolutely every one of the above Ints is really
199 a VirtualOffset of some description (the code generator
200 works entirely in terms of VirtualOffsets).
201
202 Initialisation.
203
204 \begin{code}
205 initialStateC = MkCgState AbsCNop emptyVarEnv initUsage
206
207 initUsage :: CgStksAndHeapUsage
208 initUsage  = ((0,[],0,0), (0,0))
209 \end{code}
210
211 "envInitForAlternatives" initialises the environment for a case alternative,
212 assuming that the alternative is entered after an evaluation.
213 This involves:
214
215    - zapping any volatile bindings, which aren't valid.
216    
217    - zapping the heap usage. It should be restored by a heap check.
218    
219    - setting the virtual AND real stack pointer fields to the given
220    virtual stack offsets.  this doesn't represent any {\em code}; it is a
221    prediction of where the real stack pointer will be when we come back
222    from the case analysis.
223    
224    - BUT LEAVING the rest of the stack-usage info because it is all
225    valid.  In particular, we leave the tail stack pointers unchanged,
226    becuase the alternative has to de-allocate the original @case@
227    expression's stack.  \end{itemize}
228
229 @stateIncUsage@$~e_1~e_2$ incorporates in $e_1$ the stack and heap high water
230 marks found in $e_2$.
231
232 \begin{code}
233 stateIncUsage :: CgState -> CgState -> CgState
234
235 stateIncUsage (MkCgState abs_c bs ((v,f,r,h1),(vH1,rH1)))
236               (MkCgState _     _  ((_,_,_,h2),(vH2, _)))
237      = MkCgState abs_c
238                  bs
239                  ((v,f,r,h1 `max` h2),
240                   (vH1 `max` vH2, rH1))
241 \end{code}
242
243 %************************************************************************
244 %*                                                                      *
245 \subsection[CgMonad-basics]{Basic code-generation monad magic}
246 %*                                                                      *
247 %************************************************************************
248
249 \begin{code}
250 type FCode a = CgInfoDownwards -> CgState -> (a, CgState)
251 type Code    = CgInfoDownwards -> CgState -> CgState
252
253 {-# INLINE thenC #-}
254 {-# INLINE thenFC #-}
255 {-# INLINE returnFC #-}
256 \end{code}
257 The Abstract~C is not in the environment so as to improve strictness.
258
259 \begin{code}
260 initC :: CompilationInfo -> Code -> AbstractC
261
262 initC cg_info code
263   = case (code (MkCgInfoDown 
264                         cg_info 
265                         (error "initC: statics")
266                         (error "initC: srt")
267                         initEobInfo)
268                initialStateC) of
269       MkCgState abc _ _ -> abc
270
271 returnFC :: a -> FCode a
272
273 returnFC val info_down state = (val, state)
274 \end{code}
275
276 \begin{code}
277 thenC :: Code
278       -> (CgInfoDownwards -> CgState -> a)
279       -> CgInfoDownwards -> CgState -> a
280
281 -- thenC has both of the following types:
282 -- thenC :: Code -> Code    -> Code
283 -- thenC :: Code -> FCode a -> FCode a
284
285 thenC m k info_down state
286   = k info_down new_state
287   where
288     new_state  = m info_down state
289
290 listCs :: [Code] -> Code
291
292 listCs []     info_down state = state
293 listCs (c:cs) info_down state = stateN
294   where
295     state1 = c         info_down state
296     stateN = listCs cs info_down state1
297
298 mapCs :: (a -> Code) -> [a] -> Code
299
300 mapCs f []     info_down state = state
301 mapCs f (c:cs) info_down state = stateN
302   where
303     state1 = (f c)      info_down state
304     stateN = mapCs f cs info_down state1
305 \end{code}
306
307 \begin{code}
308 thenFC  :: FCode a
309         -> (a -> CgInfoDownwards -> CgState -> c)
310         -> CgInfoDownwards -> CgState -> c
311
312 -- thenFC :: FCode a -> (a -> FCode b) -> FCode b
313 -- thenFC :: FCode a -> (a -> Code)    -> Code
314
315 thenFC m k info_down state
316   = k m_result info_down new_state
317   where
318     (m_result, new_state) = m info_down state
319
320 listFCs :: [FCode a] -> FCode [a]
321
322 listFCs []       info_down state = ([],             state)
323 listFCs (fc:fcs) info_down state = (thing : things, stateN)
324   where
325     (thing,  state1) = fc          info_down state
326     (things, stateN) = listFCs fcs info_down state1
327
328 mapFCs :: (a -> FCode b) -> [a] -> FCode [b]
329
330 mapFCs f []       info_down state = ([],             state)
331 mapFCs f (fc:fcs) info_down state = (thing : things, stateN)
332   where
333     (thing,  state1) = (f fc)       info_down state
334     (things, stateN) = mapFCs f fcs info_down state1
335 \end{code}
336
337 And the knot-tying combinator:
338 \begin{code}
339 fixC :: (a -> FCode a) -> FCode a
340 fixC fcode info_down state = result
341   where
342     result@(v, _) = fcode v info_down state
343     --      ^-------------^
344 \end{code}
345
346 @forkClosureBody@ takes a code, $c$, and compiles it in a completely
347 fresh environment, except that:
348         - compilation info and statics are passed in unchanged.
349 The current environment is passed on completely unaltered, except that
350 abstract C from the fork is incorporated.
351
352 @forkAbsC@ takes a code and compiles it in the current environment,
353 returning the abstract C thus constructed.  The current environment
354 is passed on completely unchanged.  It is pretty similar to @getAbsC@,
355 except that the latter does affect the environment. ToDo: combine?
356
357 @forkStatics@ $fc$ compiles $fc$ in an environment whose statics come
358 from the current bindings, but which is otherwise freshly initialised.
359 The Abstract~C returned is attached to the current state, but the
360 bindings and usage information is otherwise unchanged.
361
362 \begin{code}
363 forkClosureBody :: Code -> Code
364
365 forkClosureBody code
366         (MkCgInfoDown cg_info statics srt _)
367         (MkCgState absC_in binds un_usage)
368   = MkCgState (AbsCStmts absC_in absC_fork) binds un_usage
369   where
370     fork_state              = code body_info_down initialStateC
371     MkCgState absC_fork _ _ = fork_state
372     body_info_down = MkCgInfoDown cg_info statics srt initEobInfo
373
374 forkStatics :: FCode a -> FCode a
375
376 forkStatics fcode (MkCgInfoDown cg_info _ srt _)
377                   (MkCgState absC_in statics un_usage)
378   = (result, MkCgState (AbsCStmts absC_in absC_fork) statics un_usage)
379   where
380   (result, state) = fcode rhs_info_down initialStateC
381   MkCgState absC_fork _ _ = state       -- Don't merge these this line with the one
382                                         -- above or it becomes too strict!
383   rhs_info_down = MkCgInfoDown cg_info statics srt initEobInfo
384
385 forkAbsC :: Code -> FCode AbstractC
386 forkAbsC code info_down (MkCgState absC1 bs usage)
387   = (absC2, new_state)
388   where
389     MkCgState absC2 _ ((_, _, _,h2), _) =
390         code info_down (MkCgState AbsCNop bs usage)
391     ((v, f, r, h1), heap_usage) = usage
392
393     new_usage = ((v, f, r, h1 `max` h2), heap_usage)
394     new_state = MkCgState absC1 bs new_usage
395 \end{code}
396
397 @forkAlts@ $bs~d$ takes fcodes $bs$ for the branches of a @case@, and
398 an fcode for the default case $d$, and compiles each in the current
399 environment.  The current environment is passed on unmodified, except
400 that
401         - the worst stack high-water mark is incorporated
402         - the virtual Hp is moved on to the worst virtual Hp for the branches
403
404 \begin{code}
405 forkAlts :: [FCode a] -> FCode b -> FCode ([a],b)
406
407 forkAlts branch_fcodes deflt_fcode info_down in_state
408  = ((branch_results , deflt_result), out_state)
409   where
410     compile fc = fc info_down in_state
411
412     (branch_results, branch_out_states) = unzip (map compile branch_fcodes)
413
414     (deflt_result, deflt_out_state) = deflt_fcode info_down in_state
415
416     out_state = foldl stateIncUsage in_state (deflt_out_state:branch_out_states)
417                 -- NB foldl.  in_state is the *left* argument to stateIncUsage
418 \end{code}
419
420 @forkEval@ takes two blocks of code.
421
422    -  The first meddles with the environment to set it up as expected by
423       the alternatives of a @case@ which does an eval (or gc-possible primop).
424    -  The second block is the code for the alternatives.
425       (plus info for semi-tagging purposes)
426
427 @forkEval@ picks up the virtual stack pointer and returns a suitable
428 @EndOfBlockInfo@ for the caller to use, together with whatever value
429 is returned by the second block.
430
431 It uses @initEnvForAlternatives@ to initialise the environment, and
432 @stateIncUsageAlt@ to incorporate usage; the latter ignores the heap
433 usage.
434
435 \begin{code}
436 forkEval :: EndOfBlockInfo              -- For the body
437          -> Code                        -- Code to set environment
438          -> FCode Sequel                -- Semi-tagging info to store
439          -> FCode EndOfBlockInfo        -- The new end of block info
440
441 forkEval body_eob_info env_code body_code
442   = forkEvalHelp body_eob_info env_code body_code `thenFC` \ (v, sequel) ->
443     returnFC (EndOfBlockInfo v sequel)
444
445 forkEvalHelp :: EndOfBlockInfo  -- For the body
446              -> Code            -- Code to set environment
447              -> FCode a         -- The code to do after the eval
448              -> FCode (Int,     -- Sp
449                        a)       -- Result of the FCode
450
451 forkEvalHelp body_eob_info env_code body_code
452          info_down@(MkCgInfoDown cg_info statics srt _) state
453   = ((v,value_returned), state `stateIncUsageEval` state_at_end_return)
454   where
455     info_down_for_body = MkCgInfoDown cg_info statics srt body_eob_info
456
457     (MkCgState _ binds ((v,f,_,_), _)) = env_code info_down_for_body state
458         -- These v and f things are now set up as the body code expects them
459
460     (value_returned, state_at_end_return) 
461         = body_code info_down_for_body state_for_body
462
463     state_for_body = MkCgState AbsCNop
464                              (nukeVolatileBinds binds)
465                              ((v,f,v,v), (0,0))
466
467
468 stateIncUsageEval :: CgState -> CgState -> CgState
469 stateIncUsageEval (MkCgState absC1 bs ((v,f,r,h1),heap_usage))
470                   (MkCgState absC2 _  ((_,_,_,h2),         _))
471      = MkCgState (absC1 `AbsCStmts` absC2)
472                  -- The AbsC coming back should consist only of nested declarations,
473                  -- notably of the return vector!
474                  bs
475                  ((v,f,r,h1 `max` h2), heap_usage)
476         -- We don't max the heap high-watermark because stateIncUsageEval is
477         -- used only in forkEval, which in turn is only used for blocks of code
478         -- which do their own heap-check.
479 \end{code}
480
481 %************************************************************************
482 %*                                                                      *
483 \subsection[CgMonad-spitting-AbstractC]{Spitting out @AbstractC@}
484 %*                                                                      *
485 %************************************************************************
486
487 @nopC@ is the no-op for the @Code@ monad; it adds no Abstract~C to the
488 environment; @absC@ glues @ab_C@ onto the Abstract~C collected so far.
489 \begin{code}
490 nopC :: Code
491 nopC info_down state = state
492
493 absC :: AbstractC -> Code
494 absC more_absC info_down state@(MkCgState absC binds usage)
495   = MkCgState (mkAbsCStmts absC more_absC) binds usage
496 \end{code}
497
498 These two are just like @absC@, except they examine the compilation
499 info (whether SCC profiling or profiling-ctrs going) and possibly emit
500 nothing.
501
502 \begin{code}
503 costCentresC :: FAST_STRING -> [CAddrMode] -> Code
504
505 costCentresC macro args _ state@(MkCgState absC binds usage)
506   = if opt_SccProfilingOn
507     then MkCgState (mkAbsCStmts absC (CCallProfCCMacro macro args)) binds usage
508     else state
509
510 profCtrC :: FAST_STRING -> [CAddrMode] -> Code
511
512 profCtrC macro args _ state@(MkCgState absC binds usage)
513   = if not opt_DoTickyProfiling
514     then state
515     else MkCgState (mkAbsCStmts absC (CCallProfCtrMacro macro args)) binds usage
516
517 {- Try to avoid adding too many special compilation strategies here.
518    It's better to modify the header files as necessary for particular
519    targets, so that we can get away with as few variants of .hc files
520    as possible.
521 -}
522 \end{code}
523
524 @getAbsC@ compiles the code in the current environment, and returns
525 the abstract C thus constructed (leaving the abstract C being carried
526 around in the state untouched).  @getAbsC@ does not generate any
527 in-line Abstract~C itself, but the environment it returns is that
528 obtained from the compilation.
529
530 \begin{code}
531 getAbsC :: Code -> FCode AbstractC
532
533 getAbsC code info_down (MkCgState absC binds usage)
534   = (absC2, MkCgState absC binds2 usage2)
535   where
536     (MkCgState absC2 binds2 usage2) 
537         = code info_down (MkCgState AbsCNop binds usage)
538 \end{code}
539
540 \begin{code}
541
542 moduleName :: FCode Module
543 moduleName (MkCgInfoDown (MkCompInfo mod_name) _ _ _) state
544   = (mod_name, state)
545
546 \end{code}
547
548 \begin{code}
549 setEndOfBlockInfo :: EndOfBlockInfo -> Code -> Code
550 setEndOfBlockInfo eob_info code (MkCgInfoDown c_info statics srt _) state
551   = code (MkCgInfoDown c_info statics srt eob_info) state
552
553 getEndOfBlockInfo :: FCode EndOfBlockInfo
554 getEndOfBlockInfo (MkCgInfoDown c_info statics _ eob_info) state
555   = (eob_info, state)
556 \end{code}
557
558 \begin{code}
559 getSRTLabel :: FCode CLabel
560 getSRTLabel (MkCgInfoDown _ _ srt _) state
561   = (srt, state)
562
563 setSRTLabel :: CLabel -> Code -> Code
564 setSRTLabel srt code (MkCgInfoDown c_info statics _ eob_info) state
565   = code (MkCgInfoDown c_info statics srt eob_info) state
566 \end{code}
567
568 %************************************************************************
569 %*                                                                      *
570 \subsection[CgMonad-bindery]{Monad things for fiddling with @CgBindings@}
571 %*                                                                      *
572 %************************************************************************
573
574 There are three basic routines, for adding (@addBindC@), modifying
575 (@modifyBindC@) and looking up (@lookupBindC@) bindings.
576
577 A @Id@ is bound to a @(VolatileLoc, StableLoc)@ triple.
578 The name should not already be bound. (nice ASSERT, eh?)
579
580 \begin{code}
581 addBindC :: Id -> CgIdInfo -> Code
582 addBindC name stuff_to_bind info_down (MkCgState absC binds usage)
583   = MkCgState absC (extendVarEnv binds name stuff_to_bind) usage
584
585 addBindsC :: [(Id, CgIdInfo)] -> Code
586 addBindsC new_bindings info_down (MkCgState absC binds usage)
587   = MkCgState absC new_binds usage
588   where
589     new_binds = foldl (\ binds (name,info) -> extendVarEnv binds name info)
590                       binds
591                       new_bindings
592
593 modifyBindC :: Id -> (CgIdInfo -> CgIdInfo) -> Code
594 modifyBindC name mangle_fn info_down (MkCgState absC binds usage)
595   = MkCgState absC (modifyVarEnv mangle_fn binds name) usage
596
597 lookupBindC :: Id -> FCode CgIdInfo
598 lookupBindC name info_down@(MkCgInfoDown _ static_binds srt _)
599                  state@(MkCgState absC local_binds usage)
600   = (val, state)
601   where
602     val = case (lookupVarEnv local_binds name) of
603             Nothing     -> try_static
604             Just this   -> this
605
606     try_static = 
607       case (lookupVarEnv static_binds name) of
608         Just this -> this
609         Nothing
610           -> cgPanic (text "lookupBindC: no info for" <+> ppr name) info_down state
611
612 cgPanic :: SDoc -> CgInfoDownwards -> CgState -> a
613 cgPanic doc info_down@(MkCgInfoDown _ static_binds srt _)
614             state@(MkCgState absC local_binds usage)
615   = pprPanic "cgPanic"
616              (vcat [doc,
617                 ptext SLIT("static binds for:"),
618                 vcat [ ppr i | (MkCgIdInfo i _ _ _) <- rngVarEnv static_binds ],
619                 ptext SLIT("local binds for:"),
620                 vcat [ ppr i | (MkCgIdInfo i _ _ _) <- rngVarEnv local_binds ],
621                 ptext SLIT("SRT label") <+> pprCLabel srt
622               ])
623 \end{code}