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