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 */