Home | History | Annotate | Download | only in CodeGen
      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 */
    339