blob: 090b03ecd6543557fa3dce5e260e788bb962c748 [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;
31 class TargetRegisterClass;
32 class TargetRegisterInfo;
Lang Hamesc4bcc772010-07-20 07:41:44 +000033 class VirtRegMap;
Lang Hames54cc2ef2010-07-19 15:22:28 +000034
35 /// \brief Provide extra information about the physical and virtual registers
36 /// in the function being compiled.
37 class TargetRegisterExtraInfo {
38 public:
39 TargetRegisterExtraInfo();
40
41 /// \brief Set up TargetRegisterExtraInfo with pointers to necessary
42 /// sources of information.
43 void setup(MachineFunction *mf, MachineRegisterInfo *mri,
44 const TargetRegisterInfo *tri, LiveIntervals *lis);
45
46 /// \brief Recompute tables for changed function.
47 void reset();
48
49 /// \brief Free all tables in TargetRegisterExtraInfo.
50 void clear();
51
52 /// \brief Maximum number of registers from trc which alias reg.
53 unsigned getWorst(unsigned reg, const TargetRegisterClass *trc) const;
54
55 /// \brief Returns the number of allocable registers in trc.
56 unsigned getCapacity(const TargetRegisterClass *trc) const;
57
58 /// \brief Return the number of registers of class trc that may be
59 /// needed at slot i.
60 unsigned getPressureAtSlot(const TargetRegisterClass *trc,
61 SlotIndex i) const;
62
63 /// \brief Return true if the number of registers of type trc that may be
64 /// needed at slot i is greater than the capacity of trc.
65 bool classOverCapacityAtSlot(const TargetRegisterClass *trc,
66 SlotIndex i) const;
67
68 private:
69
70 MachineFunction *mf;
71 MachineRegisterInfo *mri;
72 const TargetRegisterInfo *tri;
73 LiveIntervals *lis;
74
75 typedef std::map<const TargetRegisterClass*, unsigned> WorstMapLine;
76 typedef std::map<const TargetRegisterClass*, WorstMapLine> VRWorstMap;
77 VRWorstMap vrWorst;
78
79 typedef std::map<unsigned, WorstMapLine> PRWorstMap;
80 PRWorstMap prWorst;
81
82 typedef std::map<const TargetRegisterClass*, unsigned> CapacityMap;
83 CapacityMap capacityMap;
84
85 typedef std::map<const TargetRegisterClass*, unsigned> PressureMapLine;
86 typedef std::map<SlotIndex, PressureMapLine> PressureMap;
87 PressureMap pressureMap;
88
89 bool mapsPopulated;
90
91 /// \brief Initialise the 'worst' table.
92 void initWorst();
93
94 /// \brief Initialise the 'capacity' table.
95 void initCapacity();
96
97 /// \brief Initialise/Reset the 'pressure' and live states tables.
98 void resetPressureAndLiveStates();
99 };
100
101 /// \brief Helper class to process rendering options. Tries to be as lazy as
102 /// possible.
103 class MFRenderingOptions {
104 public:
105
106 struct RegClassComp {
107 bool operator()(const TargetRegisterClass *trc1,
108 const TargetRegisterClass *trc2) const {
109 std::string trc1Name(trc1->getName()), trc2Name(trc2->getName());
110 return std::lexicographical_compare(trc1Name.begin(), trc1Name.end(),
111 trc2Name.begin(), trc2Name.end());
112 }
113 };
114
115 typedef std::set<const TargetRegisterClass*, RegClassComp> RegClassSet;
116
117 struct IntervalComp {
118 bool operator()(const LiveInterval *li1, const LiveInterval *li2) const {
119 return li1->reg < li2->reg;
120 }
121 };
122
123 typedef std::set<const LiveInterval*, IntervalComp> IntervalSet;
124
125 /// Initialise the rendering options.
126 void setup(MachineFunction *mf, const TargetRegisterInfo *tri,
127 LiveIntervals *lis);
128
129 /// Clear translations of options to the current function.
130 void clear();
131
132 /// Reset any options computed for this specific rendering.
133 void resetRenderSpecificOptions();
134
135 /// Should we render the current function.
136 bool shouldRenderCurrentMachineFunction() const;
137
138 /// Return the set of register classes to render pressure for.
139 const RegClassSet& regClasses() const;
140
141 /// Return the set of live intervals to render liveness for.
142 const IntervalSet& intervals() const;
143
144 /// Render indexes which are not associated with instructions / MBB starts.
145 bool renderEmptyIndexes() const;
146
147 /// Return whether or not to render using SVG for fancy vertical text.
148 bool fancyVerticals() const;
149
150 private:
151
152 static bool renderingOptionsProcessed;
153 static std::set<std::string> mfNamesToRender;
154 static bool renderAllMFs;
155
156 static std::set<std::string> classNamesToRender;
157 static bool renderAllClasses;
158
159
160 static std::set<std::pair<unsigned, unsigned> > intervalNumsToRender;
161 typedef enum { ExplicitOnly = 0,
162 VirtPlusExplicit = 1,
163 PhysPlusExplicit = 2,
164 All = 3 }
165 IntervalTypesToRender;
166 static unsigned intervalTypesToRender;
167
168 template <typename OutputItr>
169 static void splitComaSeperatedList(const std::string &s, OutputItr outItr);
170
171 static void processOptions();
172
173 static void processFuncNames();
174 static void processRegClassNames();
175 static void processIntervalNumbers();
176
177 static void processIntervalRange(const std::string &intervalRangeStr);
178
179 MachineFunction *mf;
180 const TargetRegisterInfo *tri;
181 LiveIntervals *lis;
182
183 mutable bool regClassesTranslatedToCurrentFunction;
184 mutable RegClassSet regClassSet;
185
186 mutable bool intervalsTranslatedToCurrentFunction;
187 mutable IntervalSet intervalSet;
188
189 void translateRegClassNamesToCurrentFunction() const;
190
191 void translateIntervalNumbersToCurrentFunction() const;
192 };
193
194 /// \brief Render MachineFunction objects and related information to a HTML
195 /// page.
196 class RenderMachineFunction : public MachineFunctionPass {
197 public:
198 static char ID;
199
200 RenderMachineFunction() : MachineFunctionPass(&ID) {}
201
202 virtual void getAnalysisUsage(AnalysisUsage &au) const;
203
204 virtual bool runOnMachineFunction(MachineFunction &fn);
205
206 virtual void releaseMemory();
207
208 /// \brief Render this machine function to HTML.
209 ///
210 /// @param renderContextStr This parameter will be included in the top of
211 /// the html file to explain where (in the
212 /// codegen pipeline) this function was rendered
213 /// from. Set it to something like
214 /// "Pre-register-allocation".
Lang Hamesc4bcc772010-07-20 07:41:44 +0000215 /// @param vrm If non-null the VRM will be queried to determine
216 /// whether a virtual register was allocated to a
217 /// physical register or spilled.
Lang Hames54cc2ef2010-07-19 15:22:28 +0000218 /// @param renderFilePrefix This string will be appended to the function
219 /// name (before the output file suffix) to enable
220 /// multiple renderings from the same function.
221 void renderMachineFunction(const char *renderContextStr,
Lang Hamesc4bcc772010-07-20 07:41:44 +0000222 const VirtRegMap *vrm = 0,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000223 const char *renderSuffix = 0);
224
225 private:
Lang Hamesf80f31e2010-07-20 10:18:54 +0000226 class Spacer;
227
228 template <typename OStream>
229 friend OStream& operator<<(OStream &os, const Spacer &s);
230
Lang Hames54cc2ef2010-07-19 15:22:28 +0000231
232 std::string fqn;
233
234 MachineFunction *mf;
235 MachineRegisterInfo *mri;
236 const TargetRegisterInfo *tri;
237 LiveIntervals *lis;
238 SlotIndexes *sis;
Lang Hamesc4bcc772010-07-20 07:41:44 +0000239 const VirtRegMap *vrm;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000240
241 TargetRegisterExtraInfo trei;
242 MFRenderingOptions ro;
243
Lang Hamesc4bcc772010-07-20 07:41:44 +0000244 // Utilities.
245 typedef enum { Dead, Defined, Used, AliveReg, AliveStack } LiveState;
Lang Hamesc4bcc772010-07-20 07:41:44 +0000246 LiveState getLiveStateAt(const LiveInterval *li, SlotIndex i) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000247
Lang Hamesf80f31e2010-07-20 10:18:54 +0000248 typedef enum { Zero, Low, High } PressureState;
249 PressureState getPressureStateAt(const TargetRegisterClass *trc,
250 SlotIndex i) const;
251
Lang Hames54cc2ef2010-07-19 15:22:28 +0000252 // ---------- Rendering methods ----------
253
Lang Hames245581b2010-07-20 09:13:29 +0000254 /// For inserting spaces when pretty printing.
255 class Spacer {
256 public:
257 explicit Spacer(unsigned numSpaces) : ns(numSpaces) {}
258 Spacer operator+(const Spacer &o) const { return Spacer(ns + o.ns); }
259 template <typename OStream> void print(OStream &os) const;
260 private:
261 unsigned ns;
262 };
263
264 Spacer s(unsigned ns) const;
265
Lang Hames54cc2ef2010-07-19 15:22:28 +0000266 template <typename Iterator>
267 std::string escapeChars(Iterator sBegin, Iterator sEnd) const;
268
Lang Hamesc4bcc772010-07-20 07:41:44 +0000269 /// \brief Render a machine instruction.
270 template <typename OStream>
271 void renderMachineInstr(OStream &os,
272 const MachineInstr *mi) const;
273
Lang Hames54cc2ef2010-07-19 15:22:28 +0000274 /// \brief Render vertical text.
275 template <typename OStream, typename T>
Lang Hames245581b2010-07-20 09:13:29 +0000276 void renderVertical(const Spacer &indent,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000277 OStream &os,
278 const T &t) const;
279
280 /// \brief Insert CSS layout info.
281 template <typename OStream>
Lang Hames245581b2010-07-20 09:13:29 +0000282 void insertCSS(const Spacer &indent,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000283 OStream &os) const;
284
285 /// \brief Render a brief summary of the function (including rendering
286 /// context).
287 template <typename OStream>
Lang Hames245581b2010-07-20 09:13:29 +0000288 void renderFunctionSummary(const Spacer &indent,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000289 OStream &os,
290 const char * const renderContextStr) const;
291
292 /// \brief Render a legend for the pressure table.
293 template <typename OStream>
Lang Hames245581b2010-07-20 09:13:29 +0000294 void renderPressureTableLegend(const Spacer &indent,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000295 OStream &os) const;
296
Lang Hamesf80f31e2010-07-20 10:18:54 +0000297 /// \brief Render a consecutive set of HTML cells of the same class using
298 /// the colspan attribute for run-length encoding.
299 template <typename OStream, typename CellType>
300 void renderCellsWithRLE(
301 const Spacer &indent, OStream &os,
302 const std::pair<CellType, unsigned> &rleAccumulator,
303 const std::map<CellType, std::string> &cellTypeStrs) const;
304
Lang Hames54cc2ef2010-07-19 15:22:28 +0000305 /// \brief Render code listing, potentially with register pressure
306 /// and live intervals shown alongside.
307 template <typename OStream>
Lang Hames245581b2010-07-20 09:13:29 +0000308 void renderCodeTablePlusPI(const Spacer &indent,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000309 OStream &os) const;
310
311 /// \brief Render warnings about the machine function, or weird rendering
312 /// parameter combinations (e.g. rendering specified live intervals
313 /// over more than one machine function).
314 template <typename OStream>
Lang Hames245581b2010-07-20 09:13:29 +0000315 void renderWarnings(const Spacer &indent,
Lang Hames54cc2ef2010-07-19 15:22:28 +0000316 OStream &os) const;
317
318 /// \brief Render the HTML page representing the MachineFunction.
319 template <typename OStream>
320 void renderFunctionPage(OStream &os,
321 const char * const renderContextStr) const;
322
323 std::string escapeChars(const std::string &s) const;
Lang Hames54cc2ef2010-07-19 15:22:28 +0000324 };
325}
326
327#endif /* LLVM_CODEGEN_RENDERMACHINEFUNCTION_H */