Add vreg-conflicts and vreg-conflict-lifetimes to drop-asm-stats
[ghc-hetmet.git] / compiler / nativeGen / RegAllocStats.hs
1
2 -- Carries interesting info for debugging / profiling of the 
3 --      graph coloring register allocator.
4
5 module RegAllocStats (
6         RegAllocStats (..),
7         regDotColor,
8
9         pprStatsSpills,
10         pprStatsLifetimes,
11         pprStatsConflict,
12         pprStatsLifeConflict
13 )
14
15 where
16
17 #include "nativeGen/NCG.h"
18
19 import qualified GraphColor as Color
20 import RegLiveness
21 import RegSpill
22 import MachRegs
23
24 import Outputable
25 import UniqFM
26 import UniqSet
27
28 import Data.List
29
30 data RegAllocStats
31
32         -- a spill stage
33         = RegAllocStatsSpill
34         { raLiveCmm     :: [LiveCmmTop]                 -- ^ code we tried to allocate regs for
35         , raGraph       :: Color.Graph Reg RegClass Reg -- ^ the partially colored graph
36         , raSpillStats  :: SpillStats                   -- ^ spiller stats
37         , raLifetimes   :: UniqFM (Reg, Int) }          -- ^ number of instrs each reg lives for
38
39         -- a successful coloring
40         | RegAllocStatsColored
41         { raLiveCmm     :: [LiveCmmTop]                 -- ^ the code we allocated regs for
42         , raGraph       :: Color.Graph Reg RegClass Reg -- ^ the colored graph
43         , raPatchedCmm  :: [LiveCmmTop]                 -- ^ code with register allocation
44         , raLifetimes   :: UniqFM (Reg, Int) }          -- ^ number of instrs each reg lives for
45
46
47 instance Outputable RegAllocStats where
48
49  ppr (s@RegAllocStatsSpill{})
50         = text "-- Spill"
51
52         $$ text "-- Native code with liveness information."
53         $$ ppr (raLiveCmm s)
54         $$ text " "
55
56         $$ text "-- Register conflict graph."
57         $$ Color.dotGraph regDotColor trivColorable (raGraph s)
58
59         $$ text "-- Spill statistics."
60         $$ ppr (raSpillStats s)
61
62
63  ppr (s@RegAllocStatsColored{})
64         = text "-- Colored"
65
66         $$ text "-- Native code with liveness information."
67         $$ ppr (raLiveCmm s)
68         $$ text " "
69
70         $$ text "-- Register conflict graph."
71         $$ Color.dotGraph regDotColor trivColorable (raGraph s)
72
73         $$ text "-- Native code after register allocation."
74         $$ ppr (raPatchedCmm s)
75
76
77 -- | Dump a table of how many spill loads / stores were inserted for each vreg.
78 pprStatsSpills
79         :: [RegAllocStats] -> SDoc
80
81 pprStatsSpills stats
82  = let  -- slurp out the stats from all the spiller stages
83         spillStats      = [ s   | s@RegAllocStatsSpill{} <- stats]
84
85         -- build a map of how many spill load/stores were inserted for each vreg
86         spillLS         = foldl' (plusUFM_C accSpillLS) emptyUFM
87                         $ map (spillLoadStore . raSpillStats) spillStats
88
89         -- print the count of load/spills as a tuple so we can read back from the file easilly
90         pprSpillLS (r, loads, stores)
91          = (parens $ (hcat $ punctuate (text ", ") [doubleQuotes (ppr r), int loads, int stores]))
92
93
94     in  (  text "-- spills-added"
95         $$ text "--    (reg_name, spill_loads_added, spill_stores_added)."
96         $$ (vcat $ map pprSpillLS $ eltsUFM spillLS)
97         $$ text "\n")
98
99
100
101 -- | Dump a table of how long vregs tend to live for.
102 pprStatsLifetimes
103         :: [RegAllocStats] -> SDoc
104
105 pprStatsLifetimes stats
106  = let  lifeMap         = foldl' plusUFM emptyUFM $ map raLifetimes stats
107         lifeBins        = binLifetimeCount lifeMap
108
109    in   (  text "-- vreg-population-lifetimes"
110         $$ text "--   (instruction_count, number_of_vregs_that_lived_that_long)"
111         $$ (vcat $ map ppr $ eltsUFM lifeBins)
112         $$ text "\n")
113
114 binLifetimeCount :: UniqFM (Reg, Int) -> UniqFM (Int, Int)
115 binLifetimeCount fm
116  = let  lifes   = map (\l -> (l, (l, 1)))
117                 $ map snd
118                 $ eltsUFM fm
119
120    in   addListToUFM_C
121                 (\(l1, c1) (l2, c2) -> (l1, c1 + c2))
122                 emptyUFM
123                 lifes
124
125
126 -- | Dump a table of how many conflicts vregs tend to have.
127 pprStatsConflict
128         :: [RegAllocStats] -> SDoc
129
130 pprStatsConflict stats
131  = let  confMap = foldl' (plusUFM_C (\(c1, n1) (c2, n2) -> (c1, n1 + n2)))
132                         emptyUFM
133                 $ map Color.slurpNodeConflictCount
134                 $ map raGraph stats
135
136    in   (  text "-- vreg-conflicts"
137         $$ text "--   (conflict_count, number_of_vregs_that_had_that_many_conflicts)"
138         $$ (vcat $ map ppr $ eltsUFM confMap)
139         $$ text "\n")
140
141
142 -- | For every vreg, dump it's how many conflicts it has and its lifetime
143 --      good for making a scatter plot.
144 pprStatsLifeConflict
145         :: [RegAllocStats] -> Color.Graph Reg RegClass Reg -> SDoc
146
147 pprStatsLifeConflict stats graph
148  = let  lifeMap = foldl' plusUFM emptyUFM $ map raLifetimes stats
149         scatter = map   (\r ->  let Just (_, lifetime)  = lookupUFM lifeMap r
150                                     Just node           = Color.lookupNode graph r
151                                 in parens $ hcat $ punctuate (text ", ")
152                                         [ doubleQuotes $ ppr $ Color.nodeId node
153                                         , ppr $ sizeUniqSet (Color.nodeConflicts node)
154                                         , ppr $ lifetime ])
155                 $ map Color.nodeId
156                 $ eltsUFM
157                 $ Color.graphMap graph
158
159    in   (  text "-- vreg-conflict-lifetime"
160         $$ text "--   (vreg, vreg_conflicts, vreg_lifetime)"
161         $$ (vcat scatter)
162         $$ text "\n")
163
164
165 -----
166 -- Register colors for drawing conflict graphs
167 --      Keep this out of MachRegs.hs because it's specific to the graph coloring allocator.
168
169
170 -- reg colors for x86
171 #if i386_TARGET_ARCH
172 regDotColor :: Reg -> SDoc
173 regDotColor reg
174  = let  Just    str     = lookupUFM regColors reg
175    in   text str
176
177 regColors
178  = listToUFM
179  $      [ (eax, "#00ff00")
180         , (ebx, "#0000ff")
181         , (ecx, "#00ffff")
182         , (edx, "#0080ff")
183
184         , (fake0, "#ff00ff")
185         , (fake1, "#ff00aa")
186         , (fake2, "#aa00ff")
187         , (fake3, "#aa00aa")
188         , (fake4, "#ff0055")
189         , (fake5, "#5500ff") ]
190 #endif
191
192
193 -- reg colors for x86_64
194 #if x86_64_TARGET_ARCH
195 regDotColor :: Reg -> SDoc
196 regDotColor reg
197  = let  Just    str     = lookupUFM regColors reg
198    in   text str
199
200 regColors
201  = listToUFM
202  $      [ (rax, "#00ff00"), (eax, "#00ff00")
203         , (rbx, "#0000ff"), (ebx, "#0000ff")
204         , (rcx, "#00ffff"), (ecx, "#00ffff")
205         , (rdx, "#0080ff"), (edx, "#00ffff")
206         , (r8,  "#00ff80")
207         , (r9,  "#008080")
208         , (r10, "#0040ff")
209         , (r11, "#00ff40")
210         , (r12, "#008040")
211         , (r13, "#004080")
212         , (r14, "#004040")
213         , (r15, "#002080") ]
214
215         ++ zip (map RealReg [16..31]) (repeat "red")
216 #endif
217
218
219 -- reg colors for ppc
220 #if powerpc_TARGET_ARCH
221 regDotColor :: Reg -> SDoc
222 regDotColor reg
223  = case regClass reg of
224         RcInteger       -> text "blue"
225         RcFloat         -> text "red"
226 #endif
227
228
229 {-
230 toX11Color (r, g, b)
231  = let  rs      = padL 2 '0' (showHex r "")
232         gs      = padL 2 '0' (showHex r "")
233         bs      = padL 2 '0' (showHex r "")
234
235         padL n c s
236                 = replicate (n - length s) c ++ s
237   in    "#" ++ rs ++ gs ++ bs
238 -}