blob: 8d56a8292ac59ffd4f1f35ff83a3cb044dee3d65 [file] [log] [blame]
Lang Hames54cc2ef2010-07-19 15:22:28 +00001//===-- llvm/CodeGen/RenderMachineFunction.h - MF->HTML -*- C++ -*---------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//===----------------------------------------------------------------------===//
11
12#ifndef LLVM_CODEGEN_RENDERMACHINEFUNCTION_H
13#define LLVM_CODEGEN_RENDERMACHINEFUNCTION_H
14
15#include "llvm/CodeGen/LiveInterval.h"
16#include "llvm/CodeGen/MachineFunctionPass.h"
17#include "llvm/CodeGen/SlotIndexes.h"
18#include "llvm/Target/TargetRegisterInfo.h"
19
20#include <algorithm>
21#include <map>
22#include <set>
23#include <string>
24
25namespace llvm {
26
27 class LiveInterval;
28 class LiveIntervals;
29 class MachineInstr;
30 class MachineRegisterInfo;
Lang Hames33198392010-09-02 08:27:00 +000031 class RenderMachineFunction;
Lang Hames54cc2ef2010-07-19 15:22:28 +000032 class TargetRegisterClass;
33 class TargetRegisterInfo;
Lang Hamesc4bcc772010-07-20 07:41:44 +000034 class VirtRegMap;
Lang Hames5a8ea652010-07-21 09:02:06 +000035 class raw_ostream;
Lang Hames54cc2ef2010-07-19 15:22:28 +000036
Lang Hames33198392010-09-02 08:27:00 +000037 /// \brief Helper class to process rendering options. Tries to be as lazy as
38 /// possible.
39 class MFRenderingOptions {
40 public:
41
42 struct RegClassComp {
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());
48 }
49 };
50
51 typedef std::set<const TargetRegisterClass*, RegClassComp> RegClassSet;
52
53 struct IntervalComp {
54 bool operator()(const LiveInterval *li1, const LiveInterval *li2) const {
55 return li1->reg < li2->reg;
56 }
57 };
58
59 typedef std::set<const LiveInterval*, IntervalComp> IntervalSet;
60
61 /// Initialise the rendering options.
62 void setup(MachineFunction *mf, const TargetRegisterInfo *tri,
63 LiveIntervals *lis, const RenderMachineFunction *rmf);
64
65 /// Clear translations of options to the current function.
66 void clear();
67
68 /// Reset any options computed for this specific rendering.
69 void resetRenderSpecificOptions();
70
71 /// Should we render the current function.
72 bool shouldRenderCurrentMachineFunction() const;
73
74 /// Return the set of register classes to render pressure for.
75 const RegClassSet& regClasses() const;
76
77 /// Return the set of live intervals to render liveness for.
78 const IntervalSet& intervals() const;
79
80 /// Render indexes which are not associated with instructions / MBB starts.
81 bool renderEmptyIndexes() const;
82
83 /// Return whether or not to render using SVG for fancy vertical text.
84 bool fancyVerticals() const;
85
86 private:
87
88 static bool renderingOptionsProcessed;
89 static std::set<std::string> mfNamesToRender;
90 static bool renderAllMFs;
91
92 static std::set<std::string> classNamesToRender;
93 static bool renderAllClasses;
94
95
96 static std::set<std::pair<unsigned, unsigned> > intervalNumsToRender;
97 typedef enum { ExplicitOnly = 0,
98 AllPhys = 1,
99 VirtNoSpills = 2,
100 VirtSpills = 4,
101 AllVirt = 6,
102 All = 7 }
103 IntervalTypesToRender;
104 static unsigned intervalTypesToRender;
105
106 template <typename OutputItr>
107 static void splitComaSeperatedList(const std::string &s, OutputItr outItr);
108
109 static void processOptions();
110
111 static void processFuncNames();
112 static void processRegClassNames();
113 static void processIntervalNumbers();
114
115 static void processIntervalRange(const std::string &intervalRangeStr);
116
117 MachineFunction *mf;
118 const TargetRegisterInfo *tri;
119 LiveIntervals *lis;
120 const RenderMachineFunction *rmf;
121
122 mutable bool regClassesTranslatedToCurrentFunction;
123 mutable RegClassSet regClassSet;
124
125 mutable bool intervalsTranslatedToCurrentFunction;
126 mutable IntervalSet intervalSet;
127
128 void translateRegClassNamesToCurrentFunction() const;
129
130 void translateIntervalNumbersToCurrentFunction() const;
131 };
132
Lang Hames54cc2ef2010-07-19 15:22:28 +0000133 /// \brief Provide extra information about the physical and virtual registers
134 /// in the function being compiled.
135 class TargetRegisterExtraInfo {
136 public:
137 TargetRegisterExtraInfo();
138
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);
143
144 /// \brief Recompute tables for changed function.
145 void reset();
146
147 /// \brief Free all tables in TargetRegisterExtraInfo.
148 void clear();
149
150 /// \brief Maximum number of registers from trc which alias reg.
151 unsigned getWorst(unsigned reg, const TargetRegisterClass *trc) const;
152
153 /// \brief Returns the number of allocable registers in trc.
154 unsigned getCapacity(const TargetRegisterClass *trc) const;
155
156 /// \brief Return the number of registers of class trc that may be
157 /// needed at slot i.
158 unsigned getPressureAtSlot(const TargetRegisterClass *trc,
159 SlotIndex i) const;
160
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,
164 SlotIndex i) const;
165
166 private:
167
168 MachineFunction *mf;
169 MachineRegisterInfo *mri;
170 const TargetRegisterInfo *tri;
171 LiveIntervals *lis;
172
173 typedef std::map<const TargetRegisterClass*, unsigned> WorstMapLine;
174 typedef std::map<const TargetRegisterClass*, WorstMapLine> VRWorstMap;
175 VRWorstMap vrWorst;
176
177 typedef std::map<unsigned, WorstMapLine> PRWorstMap;
178 PRWorstMap prWorst;
179
180 typedef std::map<const TargetRegisterClass*, unsigned> CapacityMap;
181 CapacityMap capacityMap;
182
183 typedef std::map<const TargetRegisterClass*, unsigned> PressureMapLine;
184 typedef std::map<SlotIndex, PressureMapLine> PressureMap;
185 PressureMap pressureMap;
186
187 bool mapsPopulated;
188
189 /// \brief Initialise the 'worst' table.
190 void initWorst();
191
192 /// \brief Initialise the 'capacity' table.
193 void initCapacity();
194
195 /// \brief Initialise/Reset the 'pressure' and live states tables.
196 void resetPressureAndLiveStates();
197 };
198
Lang Hames54cc2ef2010-07-19 15:22:28 +0000199 /// \brief Render MachineFunction objects and related information to a HTML
200 /// page.
201 class RenderMachineFunction : public MachineFunctionPass {
202 public:
203 static char ID;
204
Owen Anderson90c579d2010-08-06 18:33:48 +0000205 RenderMachineFunction() : MachineFunctionPass(ID) {}
Lang Hames54cc2ef2010-07-19 15:22:28 +0000206
207 virtual void getAnalysisUsage(AnalysisUsage &au) const;
208
209 virtual bool runOnMachineFunction(MachineFunction &fn);
210
211 virtual void releaseMemory();
212
Lang Hames33198392010-09-02 08:27:00 +0000213 void rememberUseDefs(const LiveInterval *li);
214
215 void rememberSpills(const LiveInterval *li,
216 const std::vector<LiveInterval*> &spills);
217
218 bool isSpill(const LiveInterval *li) const;
219
Lang Hames54cc2ef2010-07-19 15:22:28 +0000220 /// \brief Render this machine function to HTML.
221 ///
222 /// @param renderContextStr This parameter will be included in the top of
223 /// the html file to explain where (in the
224 /// codegen pipeline) this function was rendered
225 /// from. Set it to something like
226 /// "Pre-register-allocation".
Lang Hamesc4bcc772010-07-20 07:41:44 +0000227 /// @param vrm If non-null the VRM will be queried to determine
228 /// whether a virtual register was allocated to a
229 /// physical register or spilled.
Lang Hames54cc2ef2010-07-19 15:22:28 +0000230 /// @param renderFilePrefix This string will be appended to the function
231 /// name (before the output file suffix) to enable
232 /// multiple renderings from the same function.
233 void renderMachineFunction(const char *renderContextStr,
Lang Hamesc4bcc772010-07-20 07:41:44 +0000234 const VirtRegMap *vrm = 0,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000235 const char *renderSuffix = 0);
236
237 private:
Lang Hamesf80f31e2010-07-20 10:18:54 +0000238 class Spacer;
Lang Hames5a8ea652010-07-21 09:02:06 +0000239 friend raw_ostream& operator<<(raw_ostream &os, const Spacer &s);
Lang Hamesf80f31e2010-07-20 10:18:54 +0000240
Lang Hames54cc2ef2010-07-19 15:22:28 +0000241 std::string fqn;
242
243 MachineFunction *mf;
244 MachineRegisterInfo *mri;
245 const TargetRegisterInfo *tri;
246 LiveIntervals *lis;
247 SlotIndexes *sis;
Lang Hamesc4bcc772010-07-20 07:41:44 +0000248 const VirtRegMap *vrm;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000249
250 TargetRegisterExtraInfo trei;
251 MFRenderingOptions ro;
252
Lang Hames33198392010-09-02 08:27:00 +0000253
254
Lang Hamesc4bcc772010-07-20 07:41:44 +0000255 // Utilities.
256 typedef enum { Dead, Defined, Used, AliveReg, AliveStack } LiveState;
Lang Hamesc4bcc772010-07-20 07:41:44 +0000257 LiveState getLiveStateAt(const LiveInterval *li, SlotIndex i) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000258
Lang Hamesf80f31e2010-07-20 10:18:54 +0000259 typedef enum { Zero, Low, High } PressureState;
260 PressureState getPressureStateAt(const TargetRegisterClass *trc,
261 SlotIndex i) const;
262
Lang Hames33198392010-09-02 08:27:00 +0000263 typedef std::map<const LiveInterval*, std::set<const LiveInterval*> >
264 SpillIntervals;
265 SpillIntervals spillIntervals;
266
267 typedef std::map<const LiveInterval*, const LiveInterval*> SpillForMap;
268 SpillForMap spillFor;
269
270 typedef std::set<SlotIndex> SlotSet;
271 typedef std::map<const LiveInterval*, SlotSet> UseDefs;
272 UseDefs useDefs;
273
Lang Hames54cc2ef2010-07-19 15:22:28 +0000274 // ---------- Rendering methods ----------
275
Lang Hames245581b2010-07-20 09:13:29 +0000276 /// For inserting spaces when pretty printing.
277 class Spacer {
278 public:
279 explicit Spacer(unsigned numSpaces) : ns(numSpaces) {}
280 Spacer operator+(const Spacer &o) const { return Spacer(ns + o.ns); }
Lang Hames5a8ea652010-07-21 09:02:06 +0000281 void print(raw_ostream &os) const;
Lang Hames245581b2010-07-20 09:13:29 +0000282 private:
283 unsigned ns;
284 };
285
286 Spacer s(unsigned ns) const;
287
Lang Hames54cc2ef2010-07-19 15:22:28 +0000288 template <typename Iterator>
289 std::string escapeChars(Iterator sBegin, Iterator sEnd) const;
290
Lang Hamesc4bcc772010-07-20 07:41:44 +0000291 /// \brief Render a machine instruction.
Lang Hames5a8ea652010-07-21 09:02:06 +0000292 void renderMachineInstr(raw_ostream &os,
Lang Hamesc4bcc772010-07-20 07:41:44 +0000293 const MachineInstr *mi) const;
294
Lang Hames54cc2ef2010-07-19 15:22:28 +0000295 /// \brief Render vertical text.
Lang Hames5a8ea652010-07-21 09:02:06 +0000296 template <typename T>
Lang Hames245581b2010-07-20 09:13:29 +0000297 void renderVertical(const Spacer &indent,
Lang Hames5a8ea652010-07-21 09:02:06 +0000298 raw_ostream &os,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000299 const T &t) const;
300
301 /// \brief Insert CSS layout info.
Lang Hames245581b2010-07-20 09:13:29 +0000302 void insertCSS(const Spacer &indent,
Lang Hames5a8ea652010-07-21 09:02:06 +0000303 raw_ostream &os) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000304
305 /// \brief Render a brief summary of the function (including rendering
306 /// context).
Lang Hames245581b2010-07-20 09:13:29 +0000307 void renderFunctionSummary(const Spacer &indent,
Lang Hames5a8ea652010-07-21 09:02:06 +0000308 raw_ostream &os,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000309 const char * const renderContextStr) const;
310
311 /// \brief Render a legend for the pressure table.
Lang Hames245581b2010-07-20 09:13:29 +0000312 void renderPressureTableLegend(const Spacer &indent,
Lang Hames5a8ea652010-07-21 09:02:06 +0000313 raw_ostream &os) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000314
Lang Hamesf80f31e2010-07-20 10:18:54 +0000315 /// \brief Render a consecutive set of HTML cells of the same class using
316 /// the colspan attribute for run-length encoding.
Lang Hames5a8ea652010-07-21 09:02:06 +0000317 template <typename CellType>
Lang Hamesf80f31e2010-07-20 10:18:54 +0000318 void renderCellsWithRLE(
Lang Hames5a8ea652010-07-21 09:02:06 +0000319 const Spacer &indent, raw_ostream &os,
Lang Hamesf80f31e2010-07-20 10:18:54 +0000320 const std::pair<CellType, unsigned> &rleAccumulator,
321 const std::map<CellType, std::string> &cellTypeStrs) const;
322
Lang Hames54cc2ef2010-07-19 15:22:28 +0000323 /// \brief Render code listing, potentially with register pressure
324 /// and live intervals shown alongside.
Lang Hames245581b2010-07-20 09:13:29 +0000325 void renderCodeTablePlusPI(const Spacer &indent,
Lang Hames5a8ea652010-07-21 09:02:06 +0000326 raw_ostream &os) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000327
328 /// \brief Render the HTML page representing the MachineFunction.
Lang Hames5a8ea652010-07-21 09:02:06 +0000329 void renderFunctionPage(raw_ostream &os,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000330 const char * const renderContextStr) const;
331
332 std::string escapeChars(const std::string &s) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000333 };
334}
335
336#endif /* LLVM_CODEGEN_RENDERMACHINEFUNCTION_H */