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