1 //===-- llvm/CodeGen/RenderMachineFunction.h - MF->HTML -*- C++ -*---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
12 #ifndef LLVM_CODEGEN_RENDERMACHINEFUNCTION_H
13 #define LLVM_CODEGEN_RENDERMACHINEFUNCTION_H
15 #include "llvm/CodeGen/LiveInterval.h"
16 #include "llvm/CodeGen/MachineFunctionPass.h"
17 #include "llvm/CodeGen/SlotIndexes.h"
18 #include "llvm/Target/TargetRegisterInfo.h"
30 class MachineRegisterInfo
;
31 class RenderMachineFunction
;
32 class TargetRegisterClass
;
33 class TargetRegisterInfo
;
37 /// \brief Helper class to process rendering options. Tries to be as lazy as
39 class MFRenderingOptions
{
43 bool operator()(const TargetRegisterClass
*trc1
,
44 const TargetRegisterClass
*trc2
) const {
45 std::string
trc1Name(trc1
->getName()), trc2Name(trc2
->getName());
46 return std::lexicographical_compare(trc1Name
.begin(), trc1Name
.end(),
47 trc2Name
.begin(), trc2Name
.end());
51 typedef std::set
<const TargetRegisterClass
*, RegClassComp
> RegClassSet
;
54 bool operator()(const LiveInterval
*li1
, const LiveInterval
*li2
) const {
55 return li1
->reg
< li2
->reg
;
59 typedef std::set
<const LiveInterval
*, IntervalComp
> IntervalSet
;
61 /// Initialise the rendering options.
62 void setup(MachineFunction
*mf
, const TargetRegisterInfo
*tri
,
63 LiveIntervals
*lis
, const RenderMachineFunction
*rmf
);
65 /// Clear translations of options to the current function.
68 /// Reset any options computed for this specific rendering.
69 void resetRenderSpecificOptions();
71 /// Should we render the current function.
72 bool shouldRenderCurrentMachineFunction() const;
74 /// Return the set of register classes to render pressure for.
75 const RegClassSet
& regClasses() const;
77 /// Return the set of live intervals to render liveness for.
78 const IntervalSet
& intervals() const;
80 /// Render indexes which are not associated with instructions / MBB starts.
81 bool renderEmptyIndexes() const;
83 /// Return whether or not to render using SVG for fancy vertical text.
84 bool fancyVerticals() const;
88 static bool renderingOptionsProcessed
;
89 static std::set
<std::string
> mfNamesToRender
;
90 static bool renderAllMFs
;
92 static std::set
<std::string
> classNamesToRender
;
93 static bool renderAllClasses
;
96 static std::set
<std::pair
<unsigned, unsigned> > intervalNumsToRender
;
97 typedef enum { ExplicitOnly
= 0,
103 IntervalTypesToRender
;
104 static unsigned intervalTypesToRender
;
106 template <typename OutputItr
>
107 static void splitComaSeperatedList(const std::string
&s
, OutputItr outItr
);
109 static void processOptions();
111 static void processFuncNames();
112 static void processRegClassNames();
113 static void processIntervalNumbers();
115 static void processIntervalRange(const std::string
&intervalRangeStr
);
118 const TargetRegisterInfo
*tri
;
120 const RenderMachineFunction
*rmf
;
122 mutable bool regClassesTranslatedToCurrentFunction
;
123 mutable RegClassSet regClassSet
;
125 mutable bool intervalsTranslatedToCurrentFunction
;
126 mutable IntervalSet intervalSet
;
128 void translateRegClassNamesToCurrentFunction() const;
130 void translateIntervalNumbersToCurrentFunction() const;
133 /// \brief Provide extra information about the physical and virtual registers
134 /// in the function being compiled.
135 class TargetRegisterExtraInfo
{
137 TargetRegisterExtraInfo();
139 /// \brief Set up TargetRegisterExtraInfo with pointers to necessary
140 /// sources of information.
141 void setup(MachineFunction
*mf
, MachineRegisterInfo
*mri
,
142 const TargetRegisterInfo
*tri
, LiveIntervals
*lis
);
144 /// \brief Recompute tables for changed function.
147 /// \brief Free all tables in TargetRegisterExtraInfo.
150 /// \brief Maximum number of registers from trc which alias reg.
151 unsigned getWorst(unsigned reg
, const TargetRegisterClass
*trc
) const;
153 /// \brief Returns the number of allocable registers in trc.
154 unsigned getCapacity(const TargetRegisterClass
*trc
) const;
156 /// \brief Return the number of registers of class trc that may be
157 /// needed at slot i.
158 unsigned getPressureAtSlot(const TargetRegisterClass
*trc
,
161 /// \brief Return true if the number of registers of type trc that may be
162 /// needed at slot i is greater than the capacity of trc.
163 bool classOverCapacityAtSlot(const TargetRegisterClass
*trc
,
169 MachineRegisterInfo
*mri
;
170 const TargetRegisterInfo
*tri
;
173 typedef std::map
<const TargetRegisterClass
*, unsigned> WorstMapLine
;
174 typedef std::map
<const TargetRegisterClass
*, WorstMapLine
> VRWorstMap
;
177 typedef std::map
<unsigned, WorstMapLine
> PRWorstMap
;
180 typedef std::map
<const TargetRegisterClass
*, unsigned> CapacityMap
;
181 CapacityMap capacityMap
;
183 typedef std::map
<const TargetRegisterClass
*, unsigned> PressureMapLine
;
184 typedef std::map
<SlotIndex
, PressureMapLine
> PressureMap
;
185 PressureMap pressureMap
;
189 /// \brief Initialise the 'worst' table.
192 /// \brief Initialise the 'capacity' table.
195 /// \brief Initialise/Reset the 'pressure' and live states tables.
196 void resetPressureAndLiveStates();
199 /// \brief Render MachineFunction objects and related information to a HTML
201 class RenderMachineFunction
: public MachineFunctionPass
{
205 RenderMachineFunction() : MachineFunctionPass(ID
) {
206 initializeRenderMachineFunctionPass(*PassRegistry::getPassRegistry());
209 virtual void getAnalysisUsage(AnalysisUsage
&au
) const;
211 virtual bool runOnMachineFunction(MachineFunction
&fn
);
213 virtual void releaseMemory();
215 void rememberUseDefs(const LiveInterval
*li
);
217 void rememberSpills(const LiveInterval
*li
,
218 const std::vector
<LiveInterval
*> &spills
);
220 bool isSpill(const LiveInterval
*li
) const;
222 /// \brief Render this machine function to HTML.
224 /// @param renderContextStr This parameter will be included in the top of
225 /// the html file to explain where (in the
226 /// codegen pipeline) this function was rendered
227 /// from. Set it to something like
228 /// "Pre-register-allocation".
229 /// @param vrm If non-null the VRM will be queried to determine
230 /// whether a virtual register was allocated to a
231 /// physical register or spilled.
232 /// @param renderFilePrefix This string will be appended to the function
233 /// name (before the output file suffix) to enable
234 /// multiple renderings from the same function.
235 void renderMachineFunction(const char *renderContextStr
,
236 const VirtRegMap
*vrm
= 0,
237 const char *renderSuffix
= 0);
241 friend raw_ostream
& operator<<(raw_ostream
&os
, const Spacer
&s
);
246 MachineRegisterInfo
*mri
;
247 const TargetRegisterInfo
*tri
;
250 const VirtRegMap
*vrm
;
252 TargetRegisterExtraInfo trei
;
253 MFRenderingOptions ro
;
258 typedef enum { Dead
, Defined
, Used
, AliveReg
, AliveStack
} LiveState
;
259 LiveState
getLiveStateAt(const LiveInterval
*li
, SlotIndex i
) const;
261 typedef enum { Zero
, Low
, High
} PressureState
;
262 PressureState
getPressureStateAt(const TargetRegisterClass
*trc
,
265 typedef std::map
<const LiveInterval
*, std::set
<const LiveInterval
*> >
267 SpillIntervals spillIntervals
;
269 typedef std::map
<const LiveInterval
*, const LiveInterval
*> SpillForMap
;
270 SpillForMap spillFor
;
272 typedef std::set
<SlotIndex
> SlotSet
;
273 typedef std::map
<const LiveInterval
*, SlotSet
> UseDefs
;
276 // ---------- Rendering methods ----------
278 /// For inserting spaces when pretty printing.
281 explicit Spacer(unsigned numSpaces
) : ns(numSpaces
) {}
282 Spacer
operator+(const Spacer
&o
) const { return Spacer(ns
+ o
.ns
); }
283 void print(raw_ostream
&os
) const;
288 Spacer
s(unsigned ns
) const;
290 template <typename Iterator
>
291 std::string
escapeChars(Iterator sBegin
, Iterator sEnd
) const;
293 /// \brief Render a machine instruction.
294 void renderMachineInstr(raw_ostream
&os
,
295 const MachineInstr
*mi
) const;
297 /// \brief Render vertical text.
298 template <typename T
>
299 void renderVertical(const Spacer
&indent
,
303 /// \brief Insert CSS layout info.
304 void insertCSS(const Spacer
&indent
,
305 raw_ostream
&os
) const;
307 /// \brief Render a brief summary of the function (including rendering
309 void renderFunctionSummary(const Spacer
&indent
,
311 const char * const renderContextStr
) const;
313 /// \brief Render a legend for the pressure table.
314 void renderPressureTableLegend(const Spacer
&indent
,
315 raw_ostream
&os
) const;
317 /// \brief Render a consecutive set of HTML cells of the same class using
318 /// the colspan attribute for run-length encoding.
319 template <typename CellType
>
320 void renderCellsWithRLE(
321 const Spacer
&indent
, raw_ostream
&os
,
322 const std::pair
<CellType
, unsigned> &rleAccumulator
,
323 const std::map
<CellType
, std::string
> &cellTypeStrs
) const;
325 /// \brief Render code listing, potentially with register pressure
326 /// and live intervals shown alongside.
327 void renderCodeTablePlusPI(const Spacer
&indent
,
328 raw_ostream
&os
) const;
330 /// \brief Render the HTML page representing the MachineFunction.
331 void renderFunctionPage(raw_ostream
&os
,
332 const char * const renderContextStr
) const;
334 std::string
escapeChars(const std::string
&s
) const;
338 #endif /* LLVM_CODEGEN_RENDERMACHINEFUNCTION_H */