Add a deterministic finite automaton based packetizer for VLIW architectures
[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 RenderMachineFunction;
32   class TargetRegisterClass;
33   class TargetRegisterInfo;
34   class VirtRegMap;
35   class raw_ostream;
36
37   /// \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
133   /// \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
199   /// \brief Render MachineFunction objects and related information to a HTML
200   ///        page.
201   class RenderMachineFunction : public MachineFunctionPass {
202   public:
203     static char ID;
204
205     RenderMachineFunction() : MachineFunctionPass(ID) {
206       initializeRenderMachineFunctionPass(*PassRegistry::getPassRegistry());
207     }
208
209     virtual void getAnalysisUsage(AnalysisUsage &au) const;
210
211     virtual bool runOnMachineFunction(MachineFunction &fn);
212
213     virtual void releaseMemory();
214
215     void rememberUseDefs(const LiveInterval *li);
216
217     void rememberSpills(const LiveInterval *li,
218                         const std::vector<LiveInterval*> &spills);
219
220     bool isSpill(const LiveInterval *li) const;
221
222     /// \brief Render this machine function to HTML.
223     /// 
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);
238
239   private:
240     class Spacer;
241     friend raw_ostream& operator<<(raw_ostream &os, const Spacer &s);
242
243     std::string fqn;
244
245     MachineFunction *mf;
246     MachineRegisterInfo *mri;
247     const TargetRegisterInfo *tri;
248     LiveIntervals *lis;
249     SlotIndexes *sis;
250     const VirtRegMap *vrm;
251
252     TargetRegisterExtraInfo trei;
253     MFRenderingOptions ro;
254
255     
256
257     // Utilities.
258     typedef enum { Dead, Defined, Used, AliveReg, AliveStack } LiveState;
259     LiveState getLiveStateAt(const LiveInterval *li, SlotIndex i) const;
260
261     typedef enum { Zero, Low, High } PressureState;
262     PressureState getPressureStateAt(const TargetRegisterClass *trc,
263                                      SlotIndex i) const;
264
265     typedef std::map<const LiveInterval*, std::set<const LiveInterval*> >
266       SpillIntervals;
267     SpillIntervals spillIntervals;
268
269     typedef std::map<const LiveInterval*, const LiveInterval*> SpillForMap;
270     SpillForMap spillFor;
271
272     typedef std::set<SlotIndex> SlotSet;
273     typedef std::map<const LiveInterval*, SlotSet> UseDefs;
274     UseDefs useDefs;
275
276     // ---------- Rendering methods ----------
277
278     /// For inserting spaces when pretty printing.
279     class Spacer {
280     public:
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;
284     private:
285       unsigned ns;
286     };
287
288     Spacer s(unsigned ns) const;
289
290     template <typename Iterator>
291     std::string escapeChars(Iterator sBegin, Iterator sEnd) const;
292
293     /// \brief Render a machine instruction.
294     void renderMachineInstr(raw_ostream &os,
295                             const MachineInstr *mi) const;
296
297     /// \brief Render vertical text.
298     template <typename T>
299     void renderVertical(const Spacer &indent,
300                         raw_ostream &os,
301                         const T &t) const;
302
303     /// \brief Insert CSS layout info.
304     void insertCSS(const Spacer &indent,
305                    raw_ostream &os) const;
306
307     /// \brief Render a brief summary of the function (including rendering
308     ///        context).
309     void renderFunctionSummary(const Spacer &indent,
310                                raw_ostream &os,
311                                const char * const renderContextStr) const;
312
313     /// \brief Render a legend for the pressure table.
314     void renderPressureTableLegend(const Spacer &indent,
315                                    raw_ostream &os) const;
316
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;
324
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;
329
330     /// \brief Render the HTML page representing the MachineFunction.
331     void renderFunctionPage(raw_ostream &os,
332                             const char * const renderContextStr) const;
333
334     std::string escapeChars(const std::string &s) const;
335   };
336 }
337
338 #endif /* LLVM_CODEGEN_RENDERMACHINEFUNCTION_H */