[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgBindery.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[CgBindery]{Utility functions related to doing @CgBindings@}
5
6 \begin{code}
7 module CgBindery (
8         CgBindings, CgIdInfo(..){-dubiously concrete-},
9         StableLoc, VolatileLoc,
10
11         maybeStkLoc,
12
13         stableAmodeIdInfo, heapIdInfo, newTempAmodeAndIdInfo,
14         letNoEscapeIdInfo, idInfoToAmode,
15
16         nukeVolatileBinds,
17         nukeDeadBindings,
18
19         bindNewToStack,  rebindToStack,
20         bindNewToNode, bindNewToReg, bindArgsToRegs,
21         bindNewToTemp, bindNewPrimToAmode,
22         getArgAmode, getArgAmodes,
23         getCAddrModeAndInfo, getCAddrMode,
24         getCAddrModeIfVolatile, getVolatileRegs,
25
26         buildLivenessMask, buildContLivenessMask
27     ) where
28
29 #include "HsVersions.h"
30
31 import AbsCSyn
32 import CgMonad
33
34 import CgUsages         ( getHpRelOffset, getSpRelOffset, getRealSp )
35 import CgStackery       ( freeStackSlots, addFreeSlots )
36 import CLabel           ( mkStaticClosureLabel, mkClosureLabel,
37                           mkBitmapLabel )
38 import ClosureInfo      ( mkLFImported, mkLFArgument, LambdaFormInfo )
39 import BitSet           ( mkBS, emptyBS )
40 import PrimRep          ( isFollowableRep, getPrimRepSize )
41 import DataCon          ( DataCon, dataConName )
42 import Id               ( Id, idPrimRep, idType )
43 import Type             ( typePrimRep )
44 import VarEnv
45 import VarSet           ( varSetElems )
46 import Const            ( Con(..), Literal )
47 import Maybes           ( catMaybes, maybeToBool )
48 import Name             ( isLocallyDefined, isWiredInName, NamedThing(..) )
49 #ifdef DEBUG
50 import PprAbsC          ( pprAmode )
51 #endif
52 import PrimRep          ( PrimRep(..) )
53 import StgSyn           ( StgArg, StgLiveVars, GenStgArg(..) )
54 import Unique           ( Unique, Uniquable(..) )
55 import UniqSet          ( elementOfUniqSet )
56 import Util             ( zipWithEqual, panic, sortLt )
57 import Outputable
58 \end{code}
59
60
61 %************************************************************************
62 %*                                                                      *
63 \subsection[Bindery-datatypes]{Data types}
64 %*                                                                      *
65 %************************************************************************
66
67 @(CgBinding a b)@ is a type of finite maps from a to b.
68
69 The assumption used to be that @lookupCgBind@ must get exactly one
70 match.  This is {\em completely wrong} in the case of compiling
71 letrecs (where knot-tying is used).  An initial binding is fed in (and
72 never evaluated); eventually, a correct binding is put into the
73 environment.  So there can be two bindings for a given name.
74
75 \begin{code}
76 type CgBindings = IdEnv CgIdInfo
77
78 data CgIdInfo
79   = MkCgIdInfo  Id      -- Id that this is the info for
80                 VolatileLoc
81                 StableLoc
82                 LambdaFormInfo
83
84 data VolatileLoc
85   = NoVolatileLoc
86   | TempVarLoc  Unique
87
88   | RegLoc      MagicId                 -- in one of the magic registers
89                                         -- (probably {Int,Float,Char,etc}Reg
90
91   | VirHpLoc    VirtualHeapOffset       -- Hp+offset (address of closure)
92
93   | VirNodeLoc  VirtualHeapOffset       -- Cts of offset indirect from Node
94                                         -- ie *(Node+offset)
95 \end{code}
96
97 @StableLoc@ encodes where an Id can be found, used by
98 the @CgBindings@ environment in @CgBindery@.
99
100 \begin{code}
101 data StableLoc
102   = NoStableLoc
103   | VirStkLoc           VirtualSpOffset
104   | LitLoc              Literal
105   | StableAmodeLoc      CAddrMode
106
107 -- these are so StableLoc can be abstract:
108
109 maybeStkLoc (VirStkLoc offset) = Just offset
110 maybeStkLoc _                  = Nothing
111 \end{code}
112
113 %************************************************************************
114 %*                                                                      *
115 \subsection[Bindery-idInfo]{Manipulating IdInfo}
116 %*                                                                      *
117 %************************************************************************
118
119 \begin{code}
120 stableAmodeIdInfo i amode lf_info = MkCgIdInfo i NoVolatileLoc (StableAmodeLoc amode) lf_info
121 heapIdInfo i offset       lf_info = MkCgIdInfo i (VirHpLoc offset) NoStableLoc lf_info
122 tempIdInfo i uniq         lf_info = MkCgIdInfo i (TempVarLoc uniq) NoStableLoc lf_info
123
124 letNoEscapeIdInfo i sp lf_info
125   = MkCgIdInfo i NoVolatileLoc (StableAmodeLoc (CJoinPoint sp)) lf_info
126
127 newTempAmodeAndIdInfo :: Id -> LambdaFormInfo -> (CAddrMode, CgIdInfo)
128
129 newTempAmodeAndIdInfo name lf_info
130   = (temp_amode, temp_idinfo)
131   where
132     uniq        = getUnique name
133     temp_amode  = CTemp uniq (idPrimRep name)
134     temp_idinfo = tempIdInfo name uniq lf_info
135
136 idInfoToAmode :: PrimRep -> CgIdInfo -> FCode CAddrMode
137 idInfoToAmode kind (MkCgIdInfo _ vol stab _) = idInfoPiecesToAmode kind vol stab
138
139 idInfoPiecesToAmode :: PrimRep -> VolatileLoc -> StableLoc -> FCode CAddrMode
140
141 idInfoPiecesToAmode kind (TempVarLoc uniq) stable_loc   = returnFC (CTemp uniq kind)
142 idInfoPiecesToAmode kind (RegLoc magic_id) stable_loc   = returnFC (CReg magic_id)
143
144 idInfoPiecesToAmode kind NoVolatileLoc (LitLoc lit)           = returnFC (CLit lit)
145 idInfoPiecesToAmode kind NoVolatileLoc (StableAmodeLoc amode) = returnFC amode
146
147 idInfoPiecesToAmode kind (VirNodeLoc nd_off) stable_loc
148   = returnFC (CVal (nodeRel nd_off) kind)
149     -- Virtual offsets from Node increase into the closures,
150     -- and so do Node-relative offsets (which we want in the CVal),
151     -- so there is no mucking about to do to the offset.
152
153 idInfoPiecesToAmode kind (VirHpLoc hp_off) stable_loc
154   = getHpRelOffset hp_off `thenFC` \ rel_hp ->
155     returnFC (CAddr rel_hp)
156
157 idInfoPiecesToAmode kind NoVolatileLoc (VirStkLoc i)
158   = getSpRelOffset i `thenFC` \ rel_sp ->
159     returnFC (CVal rel_sp kind)
160
161 #ifdef DEBUG
162 idInfoPiecesToAmode kind NoVolatileLoc NoStableLoc = panic "idInfoPiecesToAmode: no loc"
163 #endif
164 \end{code}
165
166 %************************************************************************
167 %*                                                                      *
168 \subsection[Bindery-nuke-volatile]{Nuking volatile bindings}
169 %*                                                                      *
170 %************************************************************************
171
172 We sometimes want to nuke all the volatile bindings; we must be sure
173 we don't leave any (NoVolatile, NoStable) binds around...
174
175 \begin{code}
176 nukeVolatileBinds :: CgBindings -> CgBindings
177 nukeVolatileBinds binds
178   = mkVarEnv (foldr keep_if_stable [] (rngVarEnv binds))
179   where
180     keep_if_stable (MkCgIdInfo i _ NoStableLoc entry_info) acc = acc
181     keep_if_stable (MkCgIdInfo i _ stable_loc  entry_info) acc
182       = (i, MkCgIdInfo i NoVolatileLoc stable_loc entry_info) : acc
183 \end{code}
184
185
186 %************************************************************************
187 %*                                                                      *
188 \subsection[lookup-interface]{Interface functions to looking up bindings}
189 %*                                                                      *
190 %************************************************************************
191
192 I {\em think} all looking-up is done through @getCAddrMode(s)@.
193
194 \begin{code}
195 getCAddrModeAndInfo :: Id -> FCode (CAddrMode, LambdaFormInfo)
196
197 getCAddrModeAndInfo id
198   | not (isLocallyDefined name) || isWiredInName name
199     {- Why the "isWiredInName"?
200         Imagine you are compiling PrelBase.hs (a module that
201         supplies some of the wired-in values).  What can
202         happen is that the compiler will inject calls to
203         (e.g.) GHCbase.unpackPS, where-ever it likes -- it
204         assumes those values are ubiquitously available.
205         The main point is: it may inject calls to them earlier
206         in GHCbase.hs than the actual definition...
207     -}
208   = returnFC (global_amode, mkLFImported id)
209
210   | otherwise = -- *might* be a nested defn: in any case, it's something whose
211                 -- definition we will know about...
212     lookupBindC id `thenFC` \ (MkCgIdInfo _ volatile_loc stable_loc lf_info) ->
213     idInfoPiecesToAmode kind volatile_loc stable_loc `thenFC` \ amode ->
214     returnFC (amode, lf_info)
215   where
216     name = getName id
217     global_amode = CLbl (mkClosureLabel name) kind
218     kind = idPrimRep id
219
220 getCAddrMode :: Id -> FCode CAddrMode
221 getCAddrMode name
222   = getCAddrModeAndInfo name `thenFC` \ (amode, _) ->
223     returnFC amode
224 \end{code}
225
226 \begin{code}
227 getCAddrModeIfVolatile :: Id -> FCode (Maybe CAddrMode)
228 getCAddrModeIfVolatile name
229 --  | toplevelishId name = returnFC Nothing
230 --  | otherwise
231   = lookupBindC name `thenFC` \ ~(MkCgIdInfo _ volatile_loc stable_loc lf_info) ->
232     case stable_loc of
233         NoStableLoc ->  -- Aha!  So it is volatile!
234             idInfoPiecesToAmode (idPrimRep name) volatile_loc NoStableLoc `thenFC` \ amode ->
235             returnFC (Just amode)
236
237         a_stable_loc -> returnFC Nothing
238 \end{code}
239
240 @getVolatileRegs@ gets a set of live variables, and returns a list of
241 all registers on which these variables depend.  These are the regs
242 which must be saved and restored across any C calls.  If a variable is
243 both in a volatile location (depending on a register) {\em and} a
244 stable one (notably, on the stack), we modify the current bindings to
245 forget the volatile one.
246
247 \begin{code}
248 getVolatileRegs :: StgLiveVars -> FCode [MagicId]
249
250 getVolatileRegs vars
251   = mapFCs snaffle_it (varSetElems vars) `thenFC` \ stuff ->
252     returnFC (catMaybes stuff)
253   where
254     snaffle_it var
255       = lookupBindC var `thenFC` \ (MkCgIdInfo _ volatile_loc stable_loc lf_info) ->
256         let
257             -- commoned-up code...
258             consider_reg reg
259               = if not (isVolatileReg reg) then
260                         -- Potentially dies across C calls
261                         -- For now, that's everything; we leave
262                         -- it to the save-macros to decide which
263                         -- regs *really* need to be saved.
264                     returnFC Nothing
265                 else
266                     case stable_loc of
267                       NoStableLoc -> returnFC (Just reg) -- got one!
268                       is_a_stable_loc ->
269                         -- has both volatile & stable locations;
270                         -- force it to rely on the stable location
271                         modifyBindC var nuke_vol_bind `thenC`
272                         returnFC Nothing
273         in
274         case volatile_loc of
275           RegLoc reg   -> consider_reg reg
276           VirHpLoc _   -> consider_reg Hp
277           VirNodeLoc _ -> consider_reg node
278           non_reg_loc  -> returnFC Nothing
279
280     nuke_vol_bind (MkCgIdInfo i _ stable_loc lf_info)
281       = MkCgIdInfo i NoVolatileLoc stable_loc lf_info
282 \end{code}
283
284 \begin{code}
285 getArgAmodes :: [StgArg] -> FCode [CAddrMode]
286 getArgAmodes [] = returnFC []
287 getArgAmodes (atom:atoms)
288   = getArgAmode  atom  `thenFC` \ amode ->
289     getArgAmodes atoms `thenFC` \ amodes ->
290     returnFC ( amode : amodes )
291
292 getArgAmode :: StgArg -> FCode CAddrMode
293
294 getArgAmode (StgVarArg var) = getCAddrMode var          -- The common case
295
296 getArgAmode (StgConArg (DataCon con))
297      {- Why does this case differ from StgVarArg?
298         Because the program might look like this:
299                 data Foo a = Empty | Baz a
300                 f a x = let c = Empty! a
301                         in h c
302         Now, when we go Core->Stg, we drop the type applications, 
303         so we can inline c, giving
304                 f x = h Empty
305         Now we are referring to Empty as an argument (rather than in an STGCon), 
306         so we'll look it up with getCAddrMode.  We want to return an amode for
307         the static closure that we make for nullary constructors.  But if we blindly
308         go ahead with getCAddrMode we end up looking in the environment, and it ain't there!
309
310         This special case used to be in getCAddrModeAndInfo, but it doesn't work there.
311         Consider:
312                 f a x = Baz a x
313         If the constructor Baz isn't inlined we simply want to treat it like any other
314         identifier, with a top level definition.  We don't want to spot that it's a constructor.
315
316         In short 
317                 StgApp con args
318         and
319                 StgCon con args
320         are treated differently; the former is a call to a bog standard function while the
321         latter uses the specially-labelled, pre-defined info tables etc for the constructor.
322
323         The way to think of this case in getArgAmode is that
324                 SApp f Empty
325         is really
326                 App f (StgCon Empty [])
327      -}
328   = returnFC (CLbl (mkStaticClosureLabel (dataConName con)) PtrRep)
329
330
331 getArgAmode (StgConArg (Literal lit)) = returnFC (CLit lit)
332 \end{code}
333
334 %************************************************************************
335 %*                                                                      *
336 \subsection[binding-and-rebinding-interface]{Interface functions for binding and re-binding names}
337 %*                                                                      *
338 %************************************************************************
339
340 \begin{code}
341 bindNewToStack :: (Id, VirtualSpOffset) -> Code
342 bindNewToStack (name, offset)
343   = addBindC name info
344   where
345     info = MkCgIdInfo name NoVolatileLoc (VirStkLoc offset) mkLFArgument
346
347 bindNewToNode :: Id -> VirtualHeapOffset -> LambdaFormInfo -> Code
348 bindNewToNode name offset lf_info
349   = addBindC name info
350   where
351     info = MkCgIdInfo name (VirNodeLoc offset) NoStableLoc lf_info
352
353 -- Create a new temporary whose unique is that in the id,
354 -- bind the id to it, and return the addressing mode for the
355 -- temporary.
356 bindNewToTemp :: Id -> FCode CAddrMode
357 bindNewToTemp name
358   = let (temp_amode, id_info) = newTempAmodeAndIdInfo name mkLFArgument
359                 -- This is used only for things we don't know
360                 -- anything about; values returned by a case statement,
361                 -- for example.
362     in
363     addBindC name id_info       `thenC`
364     returnFC temp_amode
365
366 bindNewToReg :: Id -> MagicId -> LambdaFormInfo -> Code
367 bindNewToReg name magic_id lf_info
368   = addBindC name info
369   where
370     info = MkCgIdInfo name (RegLoc magic_id) NoStableLoc lf_info
371
372 bindNewToLit name lit
373   = addBindC name info
374   where
375     info = MkCgIdInfo name NoVolatileLoc (LitLoc lit) (error "bindNewToLit")
376
377 bindArgsToRegs :: [Id] -> [MagicId] -> Code
378 bindArgsToRegs args regs
379   = listCs (zipWithEqual "bindArgsToRegs" bind args regs)
380   where
381     arg `bind` reg = bindNewToReg arg reg mkLFArgument
382 \end{code}
383
384 @bindNewPrimToAmode@ works only for certain addressing modes.  Making
385 this work for stack offsets is non-trivial (virt vs. real stack offset
386 difficulties).
387
388 \begin{code}
389 bindNewPrimToAmode :: Id -> CAddrMode -> Code
390 bindNewPrimToAmode name (CReg reg) 
391   = bindNewToReg name reg (panic "bindNewPrimToAmode")
392
393 bindNewPrimToAmode name (CTemp uniq kind)
394   = addBindC name (tempIdInfo name uniq (panic "bindNewPrimToAmode"))
395
396 #ifdef DEBUG
397 bindNewPrimToAmode name amode
398   = pprPanic "bindNew...:" (pprAmode amode)
399 #endif
400 \end{code}
401
402 \begin{code}
403 rebindToStack :: Id -> VirtualSpOffset -> Code
404 rebindToStack name offset
405   = modifyBindC name replace_stable_fn
406   where
407     replace_stable_fn (MkCgIdInfo i vol stab einfo)
408       = MkCgIdInfo i vol (VirStkLoc offset) einfo
409 \end{code}
410
411 %************************************************************************
412 %*                                                                      *
413 \subsection[CgBindery-liveness]{Build a liveness mask for the current stack}
414 %*                                                                      *
415 %************************************************************************
416
417 ToDo: remove the dependency on 32-bit words.
418
419 There are two ways to build a liveness mask, and both appear to have
420 problems.
421
422   1) Find all the pointer words by searching through the binding list.
423      Invert this to find the non-pointer words and build the bitmap.
424
425   2) Find all the non-pointer words by search through the binding list.
426      Merge this with the list of currently free slots.  Build the
427      bitmap.
428
429 Method (1) conflicts with update frames - these contain pointers but
430 have no bindings in the environment.  We could bind the updatee to its
431 location in the update frame at the point when the update frame is
432 pushed, but this binding would be dropped by the first case expression
433 (nukeDeadBindings).
434
435 Method (2) causes problems because we must make sure that every
436 non-pointer word on the stack is either a free stack slot or has a
437 binding in the environment.  Things like cost centres break this (but
438 only for case-of-case expressions - because that's when there's a cost
439 centre on the stack from the outer case and we need to generate a
440 bitmap for the inner case's continuation).
441
442 This method also works "by accident" for update frames: since all
443 unaccounted for slots on the stack are assumed to be pointers, and an
444 update frame always occurs at virtual Sp offsets 0-3 (i.e. the bottom
445 of the stack frame), the bitmap will simply end at the start of the
446 update frame.
447
448 We use method (2) at the moment.
449
450 \begin{code}
451 buildLivenessMask 
452         :: Unique               -- unique for for large bitmap label
453         -> VirtualSpOffset      -- offset from which the bitmap should start
454         -> FCode Liveness       -- mask for free/unlifted slots
455
456 buildLivenessMask uniq sp info_down
457         state@(MkCgState abs_c binds ((vsp, free, _, _), heap_usage))
458   = ASSERT(all (>=0) rel_slots) 
459     livenessToAbsC uniq liveness_mask info_down state 
460   where
461         -- find all unboxed stack-resident ids
462         unboxed_slots =                    
463           [ (ofs, getPrimRepSize rep) | 
464                      (MkCgIdInfo id _ (VirStkLoc ofs) _) <- rngVarEnv binds,
465                 let rep = idPrimRep id,
466                 not (isFollowableRep rep)
467           ]
468
469         -- flatten this list into a list of unboxed stack slots
470         flatten_slots = foldr (\(ofs,size) r -> [ofs-size+1 .. ofs] ++ r) []
471                            unboxed_slots
472
473         -- merge in the free slots
474         all_slots = addFreeSlots flatten_slots free ++ 
475                     if vsp < sp then [vsp+1 .. sp] else []
476
477         -- recalibrate the list to be sp-relative
478         rel_slots = reverse (map (sp-) all_slots)
479
480         -- build the bitmap
481         liveness_mask = listToLivenessMask rel_slots
482
483 {- ALTERNATE version that doesn't work because update frames aren't
484    recorded in the environment.
485
486         -- find all boxed stack-resident ids
487         boxed_slots =              
488           [ ofs | (MkCgIdInfo id _ (VirStkLoc ofs) _) <- rngVarEnv binds,
489                 isFollowableRep (idPrimRep id)
490           ]
491         all_slots = [1..vsp]
492
493         -- invert to get unboxed slots
494         unboxed_slots = filter (`notElem` boxed_slots) all_slots
495 -}
496
497 listToLivenessMask :: [Int] -> LivenessMask
498 listToLivenessMask []    = []
499 listToLivenessMask slots = 
500    mkBS this : listToLivenessMask (map (\x -> x-32) rest)
501    where (this,rest) = span (<32) slots
502
503 livenessToAbsC :: Unique -> LivenessMask -> FCode Liveness
504 livenessToAbsC uniq []    = returnFC (LvSmall emptyBS)
505 livenessToAbsC uniq [one] = returnFC (LvSmall one)
506 livenessToAbsC uniq many  = 
507         absC (CBitmap lbl many) `thenC`
508         returnFC (LvLarge lbl)
509   where lbl = mkBitmapLabel uniq
510 \end{code}
511
512 In a continuation, we want a liveness mask that starts from just after
513 the return address, which is on the stack at realSp.
514
515 \begin{code}
516 buildContLivenessMask
517         :: Unique
518         -> FCode Liveness
519 buildContLivenessMask uniq
520   = getRealSp  `thenFC` \ realSp ->
521     buildLivenessMask uniq (realSp-1)
522 \end{code}
523
524 %************************************************************************
525 %*                                                                      *
526 \subsection[CgMonad-deadslots]{Finding dead stack slots}
527 %*                                                                      *
528 %************************************************************************
529
530 nukeDeadBindings does the following:
531
532       - Removes all bindings from the environment other than those
533         for variables in the argument to nukeDeadBindings.
534       - Collects any stack slots so freed, and returns them to the  stack free
535         list.
536       - Moves the virtual stack pointer to point to the topmost used
537         stack locations.
538
539 You can have multi-word slots on the stack (where a Double# used to
540 be, for instance); if dead, such a slot will be reported as *several*
541 offsets (one per word).
542
543 Probably *naughty* to look inside monad...
544
545 \begin{code}
546 nukeDeadBindings :: StgLiveVars  -- All the *live* variables
547                  -> Code
548
549 nukeDeadBindings live_vars info_down (MkCgState abs_c binds usage)
550   = freeStackSlots extra_free info_down (MkCgState abs_c (mkVarEnv bs') usage)
551   where
552     (dead_stk_slots, bs')
553       = dead_slots live_vars
554                    [] []
555                    [ (i, b) | b@(MkCgIdInfo i _ _ _) <- rngVarEnv binds ]
556
557     extra_free = sortLt (<) dead_stk_slots
558 \end{code}
559
560 Several boring auxiliary functions to do the dirty work.
561
562 \begin{code}
563 dead_slots :: StgLiveVars
564            -> [(Id,CgIdInfo)]
565            -> [VirtualSpOffset]
566            -> [(Id,CgIdInfo)]
567            -> ([VirtualSpOffset], [(Id,CgIdInfo)])
568
569 -- dead_slots carries accumulating parameters for
570 --      filtered bindings, dead slots
571 dead_slots live_vars fbs ds []
572   = (ds, reverse fbs) -- Finished; rm the dups, if any
573
574 dead_slots live_vars fbs ds ((v,i):bs)
575   | v `elementOfUniqSet` live_vars
576     = dead_slots live_vars ((v,i):fbs) ds bs
577           -- Live, so don't record it in dead slots
578           -- Instead keep it in the filtered bindings
579
580   | otherwise
581     = case i of
582         MkCgIdInfo _ _ stable_loc _
583          | is_stk_loc ->
584            dead_slots live_vars fbs ([offset-size+1 .. offset] ++ ds) bs
585          where
586           maybe_stk_loc = maybeStkLoc stable_loc
587           is_stk_loc    = maybeToBool maybe_stk_loc
588           (Just offset) = maybe_stk_loc
589
590         _ -> dead_slots live_vars fbs ds bs
591   where
592
593     size :: Int
594     size = (getPrimRepSize . typePrimRep . idType) v
595
596 \end{code}