090b03ecd6543557fa3dce5e260e788bb962c748
[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
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".
215     /// @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.
218     /// @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,
222                                const VirtRegMap *vrm = 0,
223                                const char *renderSuffix = 0);
224
225   private:
226     class Spacer;
227
228     template <typename OStream>
229     friend OStream& operator<<(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       template <typename OStream> void print(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     template <typename OStream>
271     void renderMachineInstr(OStream &os,
272                             const MachineInstr *mi) const;
273
274     /// \brief Render vertical text.
275     template <typename OStream, typename T>
276     void renderVertical(const Spacer &indent,
277                         OStream &os,
278                         const T &t) const;
279
280     /// \brief Insert CSS layout info.
281     template <typename OStream>
282     void insertCSS(const Spacer &indent,
283                    OStream &os) const;
284
285     /// \brief Render a brief summary of the function (including rendering
286     ///        context).
287     template <typename OStream>
288     void renderFunctionSummary(const Spacer &indent,
289                                OStream &os,
290                                const char * const renderContextStr) const;
291
292     /// \brief Render a legend for the pressure table.
293     template <typename OStream>
294     void renderPressureTableLegend(const Spacer &indent,
295                                    OStream &os) const;
296
297     /// \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
305     /// \brief Render code listing, potentially with register pressure
306     ///        and live intervals shown alongside.
307     template <typename OStream>
308     void renderCodeTablePlusPI(const Spacer &indent,
309                                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>
315     void renderWarnings(const Spacer &indent,
316                         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;
324   };
325 }
326
327 #endif /* LLVM_CODEGEN_RENDERMACHINEFUNCTION_H */