[project @ 1996-06-05 06:44:31 by partain]
[ghc-hetmet.git] / ghc / compiler / codeGen / CgUsages.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
3 %
4 \section[CgUsages]{Accessing and modifying stacks and heap usage info}
5
6 This module provides the functions to access (\tr{get*} functions) and
7 modify (\tr{set*} functions) the stacks and heap usage information.
8
9 \begin{code}
10 #include "HsVersions.h"
11
12 module CgUsages (
13         initHeapUsage, setVirtHp, getVirtAndRealHp, setRealHp,
14         setRealAndVirtualSps,
15
16         getVirtSps,
17
18         getHpRelOffset, getSpARelOffset, getSpBRelOffset,
19
20         freeBStkSlot
21     ) where
22
23 IMP_Ubiq(){-uitous-}
24 IMPORT_DELOOPER(CgLoop1)        -- here for paranoia-checking
25
26 import AbsCSyn          ( RegRelative(..), AbstractC, CAddrMode )
27 import CgMonad
28 import HeapOffs         ( zeroOff,
29                           VirtualHeapOffset(..),
30                           VirtualSpAOffset(..),
31                           VirtualSpBOffset(..)
32                         )
33 import Id               ( IdEnv(..) )
34 \end{code}
35
36 %************************************************************************
37 %*                                                                      *
38 \subsection[CgUsages-heapery]{Monad things for fiddling with heap usage}
39 %*                                                                      *
40 %************************************************************************
41
42 @initHeapUsage@ applies a function to the amount of heap that it uses.
43 It initialises the heap usage to zeros, and passes on an unchanged
44 heap usage.
45
46 It is usually a prelude to performing a GC check, so everything must
47 be in a tidy and consistent state.
48
49 \begin{code}
50 initHeapUsage :: (VirtualHeapOffset -> Code) -> Code
51
52 initHeapUsage fcode info_down (MkCgState absC binds (a_usage, b_usage, heap_usage))
53   = state3
54   where
55     state1 = MkCgState absC binds (a_usage, b_usage, (zeroOff, zeroOff))
56     state2 = fcode (heapHWM heap_usage2) info_down state1
57     (MkCgState absC2 binds2 (a_usage2, b_usage2, heap_usage2)) = state2
58     state3 = MkCgState  absC2
59                         binds2
60                         (a_usage2, b_usage2, heap_usage {- unchanged -})
61 \end{code}
62
63 \begin{code}
64 setVirtHp :: VirtualHeapOffset -> Code
65 setVirtHp new_virtHp info_down
66           state@(MkCgState absC binds (a_stk, b_stk, (virtHp, realHp)))
67   = MkCgState absC binds (a_stk, b_stk, (new_virtHp, realHp))
68 \end{code}
69
70 \begin{code}
71 getVirtAndRealHp :: FCode (VirtualHeapOffset, VirtualHeapOffset)
72 getVirtAndRealHp info_down state@(MkCgState _ _ (au, bu, (virtHp, realHp)))
73   = ((virtHp, realHp), state)
74 \end{code}
75
76 \begin{code}
77 setRealHp ::  VirtualHeapOffset -> Code
78 setRealHp realHp info_down (MkCgState absC binds (au, bu, (vHp, _)))
79   = MkCgState absC binds (au, bu, (vHp, realHp))
80 \end{code}
81
82 \begin{code}
83 getHpRelOffset :: VirtualHeapOffset -> FCode RegRelative
84 getHpRelOffset virtual_offset info_down state@(MkCgState _ _ (_,_,(_,realHp)))
85   = (HpRel realHp virtual_offset, state)
86 \end{code}
87
88 The heap high water mark is the larger of virtHp and hwHp.  The latter is
89 only records the high water marks of forked-off branches, so to find the
90 heap high water mark you have to take the max of virtHp and hwHp.  Remember,
91 virtHp never retreats!
92
93 \begin{code}
94 heapHWM (virtHp, realHp) = virtHp
95 \end{code}
96
97 %************************************************************************
98 %*                                                                      *
99 \subsection[CgUsages-stackery]{Monad things for fiddling with stack usage}
100 %*                                                                      *
101 %************************************************************************
102
103 @setRealAndVirtualSps@ sets into the environment the offsets of the
104 current position of the real and virtual stack pointers in the current
105 stack frame.  The high-water mark is set too.  It generates no code.
106 It is used to initialise things at the beginning of a closure body.
107
108 \begin{code}
109 setRealAndVirtualSps :: VirtualSpAOffset        -- New real SpA
110                      -> VirtualSpBOffset        -- Ditto B stack
111                      -> Code
112
113 setRealAndVirtualSps spA spB info_down (MkCgState absC binds
114                                         ((vspA,fA,realSpA,hwspA),
115                                          (vspB,fB,realSpB,hwspB),
116                                          h_usage))
117   = MkCgState absC binds new_usage
118   where
119     new_usage = ((spA, fA, spA, spA),
120                  (spB, fB, spB, spB),
121                  h_usage)
122 \end{code}
123
124 \begin{code}
125 getVirtSps :: FCode (VirtualSpAOffset,VirtualSpBOffset)
126 getVirtSps info_down state@(MkCgState absC binds ((virtSpA,_,_,_), (virtSpB,_,_,_), _))
127   = ((virtSpA,virtSpB), state)
128 \end{code}
129
130 \begin{code}
131 getSpARelOffset :: VirtualSpAOffset -> FCode RegRelative
132 getSpARelOffset virtual_offset info_down state@(MkCgState _ _ ((_,_,realSpA,_),_,_))
133   = (SpARel realSpA virtual_offset, state)
134
135 getSpBRelOffset :: VirtualSpBOffset -> FCode RegRelative
136 getSpBRelOffset virtual_offset info_down state@(MkCgState _ _ (_,(_,_,realSpB,_),_))
137   = (SpBRel realSpB virtual_offset, state)
138 \end{code}
139
140 \begin{code}
141 freeBStkSlot :: VirtualSpBOffset -> Code
142 freeBStkSlot b_slot info_down
143         state@(MkCgState absC binds (spa_usage, (virtSpB,free_b,realSpB,hwSpB), heap_usage))
144   = MkCgState absC binds (spa_usage, (virtSpB,new_free_b,realSpB,hwSpB), heap_usage)
145   where
146     new_free_b = addFreeBSlots free_b [b_slot]
147 \end{code}