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 { operatorRegClassComp43 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 { operatorIntervalComp54 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 RenderMachineFunction()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: Spacer(unsigned numSpaces)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