//===-- llvm/CodeGen/RenderMachineFunction.cpp - MF->HTML -----s-----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "rendermf"

#include "RenderMachineFunction.h"

#include "VirtRegMap.h"

#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"

#include <sstream>

using namespace llvm;

char RenderMachineFunction::ID = 0;
INITIALIZE_PASS(RenderMachineFunction, "rendermf",
                "Render machine functions (and related info) to HTML pages",
                false, false);

static cl::opt<std::string>
outputFileSuffix("rmf-file-suffix",
                 cl::desc("Appended to function name to get output file name "
                          "(default: \".html\")"),
                 cl::init(".html"), cl::Hidden);

static cl::opt<std::string>
machineFuncsToRender("rmf-funcs",
                     cl::desc("Coma seperated list of functions to render"
                              ", or \"*\"."),
                     cl::init(""), cl::Hidden);

static cl::opt<std::string>
pressureClasses("rmf-classes",
                cl::desc("Register classes to render pressure for."),
                cl::init(""), cl::Hidden);

static cl::opt<std::string>
showIntervals("rmf-intervals",
              cl::desc("Live intervals to show alongside code."),
              cl::init(""), cl::Hidden);

static cl::opt<bool>
showEmptyIndexes("rmf-empty-indexes",
                 cl::desc("Render indexes not associated with instructions or "
                          "MBB starts."),
                 cl::init(false), cl::Hidden);

static cl::opt<bool>
useFancyVerticals("rmf-fancy-verts",
                  cl::desc("Use SVG for vertical text."),
                  cl::init(true), cl::Hidden);

static cl::opt<bool>
prettyHTML("rmf-pretty-html",
           cl::desc("Pretty print HTML. For debugging the renderer only.."),
           cl::init(false), cl::Hidden);


namespace llvm {

  bool MFRenderingOptions::renderingOptionsProcessed;
  std::set<std::string> MFRenderingOptions::mfNamesToRender;
  bool MFRenderingOptions::renderAllMFs = false;

  std::set<std::string> MFRenderingOptions::classNamesToRender;
  bool MFRenderingOptions::renderAllClasses = false;

  std::set<std::pair<unsigned, unsigned> >
    MFRenderingOptions::intervalNumsToRender;
  unsigned MFRenderingOptions::intervalTypesToRender = ExplicitOnly;

  template <typename OutputItr>
  void MFRenderingOptions::splitComaSeperatedList(const std::string &s,
                                                         OutputItr outItr) {
    std::string::const_iterator curPos = s.begin();
    std::string::const_iterator nextComa = std::find(curPos, s.end(), ',');
    while (nextComa != s.end()) {
      std::string elem;
      std::copy(curPos, nextComa, std::back_inserter(elem));
      *outItr = elem;
      ++outItr;
      curPos = llvm::next(nextComa);
      nextComa = std::find(curPos, s.end(), ',');
    }

    if (curPos != s.end()) {
      std::string elem;
      std::copy(curPos, s.end(), std::back_inserter(elem));
      *outItr = elem;
      ++outItr;
    }
  }

  void MFRenderingOptions::processOptions() {
    if (!renderingOptionsProcessed) {
      processFuncNames();
      processRegClassNames();
      processIntervalNumbers();
      renderingOptionsProcessed = true;
    }
  }

  void MFRenderingOptions::processFuncNames() {
    if (machineFuncsToRender == "*") {
      renderAllMFs = true;
    } else {
      splitComaSeperatedList(machineFuncsToRender,
                             std::inserter(mfNamesToRender,
                                           mfNamesToRender.begin()));
    }
  }

  void MFRenderingOptions::processRegClassNames() {
    if (pressureClasses == "*") {
      renderAllClasses = true;
    } else {
      splitComaSeperatedList(pressureClasses,
                             std::inserter(classNamesToRender,
                                           classNamesToRender.begin()));
    }
  }

  void MFRenderingOptions::processIntervalNumbers() {
    std::set<std::string> intervalRanges;
    splitComaSeperatedList(showIntervals,
                           std::inserter(intervalRanges,
                                         intervalRanges.begin()));
    std::for_each(intervalRanges.begin(), intervalRanges.end(),
                  processIntervalRange);
  }

  void MFRenderingOptions::processIntervalRange(
                                          const std::string &intervalRangeStr) {
    if (intervalRangeStr == "*") {
      intervalTypesToRender |= All;
    } else if (intervalRangeStr == "virt*") {
      intervalTypesToRender |= VirtPlusExplicit;
    } else if (intervalRangeStr == "phys*") {
      intervalTypesToRender |= PhysPlusExplicit;
    } else {
      std::istringstream iss(intervalRangeStr);
      unsigned reg1, reg2;
      if ((iss >> reg1 >> std::ws)) {
        if (iss.eof()) {
          intervalNumsToRender.insert(std::make_pair(reg1, reg1 + 1));
        } else {
          char c;
          iss >> c;
          if (c == '-' && (iss >> reg2)) {
            intervalNumsToRender.insert(std::make_pair(reg1, reg2 + 1));
          } else {
            dbgs() << "Warning: Invalid interval range \""
                   << intervalRangeStr << "\" in -rmf-intervals. Skipping.\n";
          }
        }
      } else {
        dbgs() << "Warning: Invalid interval number \""
               << intervalRangeStr << "\" in -rmf-intervals. Skipping.\n";
      }
    }
  }

  void MFRenderingOptions::setup(MachineFunction *mf,
                                 const TargetRegisterInfo *tri,
                                 LiveIntervals *lis) {
    this->mf = mf;
    this->tri = tri;
    this->lis = lis;

    clear();
  }

  void MFRenderingOptions::clear() {
    regClassesTranslatedToCurrentFunction = false;
    regClassSet.clear();

    intervalsTranslatedToCurrentFunction = false;
    intervalSet.clear();
  }

  void MFRenderingOptions::resetRenderSpecificOptions() {
    intervalSet.clear();
    intervalsTranslatedToCurrentFunction = false;
  }

  bool MFRenderingOptions::shouldRenderCurrentMachineFunction() const {
    processOptions();

    return (renderAllMFs ||
            mfNamesToRender.find(mf->getFunction()->getName()) !=
              mfNamesToRender.end());    
  }

  const MFRenderingOptions::RegClassSet& MFRenderingOptions::regClasses() const{
    translateRegClassNamesToCurrentFunction();
    return regClassSet;
  }

  const MFRenderingOptions::IntervalSet& MFRenderingOptions::intervals() const {
    translateIntervalNumbersToCurrentFunction();
    return intervalSet;
  }

  bool MFRenderingOptions::renderEmptyIndexes() const {
    return showEmptyIndexes;
  }

  bool MFRenderingOptions::fancyVerticals() const {
    return useFancyVerticals;
  }

  void MFRenderingOptions::translateRegClassNamesToCurrentFunction() const {
    if (!regClassesTranslatedToCurrentFunction) {
      processOptions();
      for (TargetRegisterInfo::regclass_iterator rcItr = tri->regclass_begin(),
                                                 rcEnd = tri->regclass_end();
           rcItr != rcEnd; ++rcItr) {
        const TargetRegisterClass *trc = *rcItr;
        if (renderAllClasses ||
            classNamesToRender.find(trc->getName()) !=
              classNamesToRender.end()) {
          regClassSet.insert(trc);
        }
      }
      regClassesTranslatedToCurrentFunction = true;
    }
  }

  void MFRenderingOptions::translateIntervalNumbersToCurrentFunction() const {
    if (!intervalsTranslatedToCurrentFunction) {
      processOptions();

      // If we're not just doing explicit then do a copy over all matching
      // types.
      if (intervalTypesToRender != ExplicitOnly) {
        for (LiveIntervals::iterator liItr = lis->begin(), liEnd = lis->end();
             liItr != liEnd; ++liItr) {

          if ((TargetRegisterInfo::isPhysicalRegister(liItr->first) &&
               (intervalTypesToRender & PhysPlusExplicit)) ||
              (TargetRegisterInfo::isVirtualRegister(liItr->first) &&
               (intervalTypesToRender & VirtPlusExplicit))) {
            intervalSet.insert(liItr->second);
          }
        }
      }

      // If we need to process the explicit list...
      if (intervalTypesToRender != All) {
        for (std::set<std::pair<unsigned, unsigned> >::const_iterator
               regRangeItr = intervalNumsToRender.begin(),
               regRangeEnd = intervalNumsToRender.end();
             regRangeItr != regRangeEnd; ++regRangeItr) {
          const std::pair<unsigned, unsigned> &range = *regRangeItr;
          for (unsigned reg = range.first; reg != range.second; ++reg) {
            if (lis->hasInterval(reg)) {
              intervalSet.insert(&lis->getInterval(reg));
            }
          }
        }
      }

      intervalsTranslatedToCurrentFunction = true;
    }
  }

  // ---------- TargetRegisterExtraInformation implementation ----------

  TargetRegisterExtraInfo::TargetRegisterExtraInfo()
    : mapsPopulated(false) {
  }

  void TargetRegisterExtraInfo::setup(MachineFunction *mf,
                                      MachineRegisterInfo *mri,
                                      const TargetRegisterInfo *tri,
                                      LiveIntervals *lis) {
    this->mf = mf;
    this->mri = mri;
    this->tri = tri;
    this->lis = lis;
  }

  void TargetRegisterExtraInfo::reset() {
    if (!mapsPopulated) {
      initWorst();
      //initBounds();
      initCapacity();
      mapsPopulated = true;
    }

    resetPressureAndLiveStates();
  }

  void TargetRegisterExtraInfo::clear() {
    prWorst.clear();
    vrWorst.clear();
    capacityMap.clear();
    pressureMap.clear();
    //liveStatesMap.clear();
    mapsPopulated = false;
  }

  void TargetRegisterExtraInfo::initWorst() {
    assert(!mapsPopulated && prWorst.empty() && vrWorst.empty() &&
           "Worst map already initialised?");

    // Start with the physical registers.
    for (unsigned preg = 1; preg < tri->getNumRegs(); ++preg) {
      WorstMapLine &pregLine = prWorst[preg];

      for (TargetRegisterInfo::regclass_iterator rcItr = tri->regclass_begin(),
                                                 rcEnd = tri->regclass_end();
           rcItr != rcEnd; ++rcItr) {
        const TargetRegisterClass *trc = *rcItr;

        unsigned numOverlaps = 0;
        for (TargetRegisterClass::iterator rItr = trc->begin(),
                                           rEnd = trc->end();
             rItr != rEnd; ++rItr) {
          unsigned trcPReg = *rItr;
          if (tri->regsOverlap(preg, trcPReg))
            ++numOverlaps;
        }
        
        pregLine[trc] = numOverlaps;
      }
    }

    // Now the register classes.
    for (TargetRegisterInfo::regclass_iterator rc1Itr = tri->regclass_begin(),
                                               rcEnd = tri->regclass_end();
         rc1Itr != rcEnd; ++rc1Itr) {
      const TargetRegisterClass *trc1 = *rc1Itr;
      WorstMapLine &classLine = vrWorst[trc1];

      for (TargetRegisterInfo::regclass_iterator rc2Itr = tri->regclass_begin();
           rc2Itr != rcEnd; ++rc2Itr) {
        const TargetRegisterClass *trc2 = *rc2Itr;

        unsigned worst = 0;

        for (TargetRegisterClass::iterator trc1Itr = trc1->begin(),
                                           trc1End = trc1->end();
             trc1Itr != trc1End; ++trc1Itr) {
          unsigned trc1Reg = *trc1Itr;
          unsigned trc1RegWorst = 0;

          for (TargetRegisterClass::iterator trc2Itr = trc2->begin(),
                                             trc2End = trc2->end();
               trc2Itr != trc2End; ++trc2Itr) {
            unsigned trc2Reg = *trc2Itr;
            if (tri->regsOverlap(trc1Reg, trc2Reg))
              ++trc1RegWorst;
          }
          if (trc1RegWorst > worst) {
            worst = trc1RegWorst;
          }    
        }

        if (worst != 0) {
          classLine[trc2] = worst;
        }
      }
    }
  }

  unsigned TargetRegisterExtraInfo::getWorst(
                                        unsigned reg,
                                        const TargetRegisterClass *trc) const {
    const WorstMapLine *wml = 0;
    if (TargetRegisterInfo::isPhysicalRegister(reg)) {
      PRWorstMap::const_iterator prwItr = prWorst.find(reg);
      assert(prwItr != prWorst.end() && "Missing prWorst entry.");
      wml = &prwItr->second;
    } else {
      const TargetRegisterClass *regTRC = mri->getRegClass(reg);
      VRWorstMap::const_iterator vrwItr = vrWorst.find(regTRC);
      assert(vrwItr != vrWorst.end() && "Missing vrWorst entry.");
      wml = &vrwItr->second;
    }
    
    WorstMapLine::const_iterator wmlItr = wml->find(trc);
    if (wmlItr == wml->end())
      return 0;

    return wmlItr->second;
  }

  void TargetRegisterExtraInfo::initCapacity() {
    assert(!mapsPopulated && capacityMap.empty() &&
           "Capacity map already initialised?");

    for (TargetRegisterInfo::regclass_iterator rcItr = tri->regclass_begin(),
           rcEnd = tri->regclass_end();
         rcItr != rcEnd; ++rcItr) {
      const TargetRegisterClass *trc = *rcItr;
      unsigned capacity = std::distance(trc->allocation_order_begin(*mf),
                                        trc->allocation_order_end(*mf));

      if (capacity != 0)
        capacityMap[trc] = capacity;
    }
  }

  unsigned TargetRegisterExtraInfo::getCapacity(
                                         const TargetRegisterClass *trc) const {
    CapacityMap::const_iterator cmItr = capacityMap.find(trc);
    assert(cmItr != capacityMap.end() &&
           "vreg with unallocable register class");
    return cmItr->second;
  }

  void TargetRegisterExtraInfo::resetPressureAndLiveStates() {
    pressureMap.clear();
    //liveStatesMap.clear();

    // Iterate over all slots.
    

    // Iterate over all live intervals.
    for (LiveIntervals::iterator liItr = lis->begin(),
           liEnd = lis->end();
         liItr != liEnd; ++liItr) {
      LiveInterval *li = liItr->second;

      const TargetRegisterClass *liTRC;

      if (TargetRegisterInfo::isPhysicalRegister(li->reg))
        continue;
      
      liTRC = mri->getRegClass(li->reg);
     

      // For all ranges in the current interal.
      for (LiveInterval::iterator lrItr = li->begin(),
             lrEnd = li->end();
           lrItr != lrEnd; ++lrItr) {
        LiveRange *lr = &*lrItr;
        
        // For all slots in the current range.
        for (SlotIndex i = lr->start; i != lr->end; i = i.getNextSlot()) {

          // Record increased pressure at index for all overlapping classes.
          for (TargetRegisterInfo::regclass_iterator
                 rcItr = tri->regclass_begin(),
                 rcEnd = tri->regclass_end();
               rcItr != rcEnd; ++rcItr) {
            const TargetRegisterClass *trc = *rcItr;

            if (trc->allocation_order_begin(*mf) ==
                trc->allocation_order_end(*mf))
              continue;

            unsigned worstAtI = getWorst(li->reg, trc);

            if (worstAtI != 0) {
              pressureMap[i][trc] += worstAtI;
            }
          }
        }
      }
    } 
  }

  unsigned TargetRegisterExtraInfo::getPressureAtSlot(
                                                 const TargetRegisterClass *trc,
                                                 SlotIndex i) const {
    PressureMap::const_iterator pmItr = pressureMap.find(i);
    if (pmItr == pressureMap.end())
      return 0;
    const PressureMapLine &pmLine = pmItr->second;
    PressureMapLine::const_iterator pmlItr = pmLine.find(trc);
    if (pmlItr == pmLine.end())
      return 0;
    return pmlItr->second;
  }

  bool TargetRegisterExtraInfo::classOverCapacityAtSlot(
                                                 const TargetRegisterClass *trc,
                                                 SlotIndex i) const {
    return (getPressureAtSlot(trc, i) > getCapacity(trc));
  }

  // ---------- MachineFunctionRenderer implementation ----------

  void RenderMachineFunction::Spacer::print(raw_ostream &os) const {
    if (!prettyHTML)
      return;
    for (unsigned i = 0; i < ns; ++i) {
      os << " ";
    }
  }

  RenderMachineFunction::Spacer RenderMachineFunction::s(unsigned ns) const {
    return Spacer(ns);
  }

  raw_ostream& operator<<(raw_ostream &os, const RenderMachineFunction::Spacer &s) {
    s.print(os);
    return os;
  }

  template <typename Iterator>
  std::string RenderMachineFunction::escapeChars(Iterator sBegin, Iterator sEnd) const {
    std::string r;

    for (Iterator sItr = sBegin; sItr != sEnd; ++sItr) {
      char c = *sItr;

      switch (c) {
        case '<': r.append("&lt;"); break;
        case '>': r.append("&gt;"); break;
        case '&': r.append("&amp;"); break;
        case ' ': r.append("&nbsp;"); break;
        case '\"': r.append("&quot;"); break;
        default: r.push_back(c); break;
      }
    }

    return r;
  }

  RenderMachineFunction::LiveState
  RenderMachineFunction::getLiveStateAt(const LiveInterval *li,
                                        SlotIndex i) const {
    const MachineInstr *mi = sis->getInstructionFromIndex(i);

    if (li->liveAt(i)) {
      if (mi == 0) {
        if (vrm == 0 || 
            (vrm->getStackSlot(li->reg) == VirtRegMap::NO_STACK_SLOT)) {
          return AliveReg;
        } else {
          return AliveStack;
        }
      } else {
        if (i.getSlot() == SlotIndex::DEF &&
            mi->definesRegister(li->reg, tri)) {
          return Defined;
        } else if (i.getSlot() == SlotIndex::USE &&
                   mi->readsRegister(li->reg)) {
          return Used;
        } else {
          if (vrm == 0 || 
              (vrm->getStackSlot(li->reg) == VirtRegMap::NO_STACK_SLOT)) {
            return AliveReg;
          } else {
            return AliveStack;
          }
        }
      }
    }
    return Dead;
  }

  RenderMachineFunction::PressureState
  RenderMachineFunction::getPressureStateAt(const TargetRegisterClass *trc,
                                              SlotIndex i) const {
    if (trei.getPressureAtSlot(trc, i) == 0) {
      return Zero;
    } else if (trei.classOverCapacityAtSlot(trc, i)){
      return High;
    }
    return Low;
  }

  /// \brief Render a machine instruction.
  void RenderMachineFunction::renderMachineInstr(raw_ostream &os,
                                                 const MachineInstr *mi) const {
    std::string s;
    raw_string_ostream oss(s);
    oss << *mi;

    os << escapeChars(oss.str());
  }

  template <typename T>
  void RenderMachineFunction::renderVertical(const Spacer &indent,
                                             raw_ostream &os,
                                             const T &t) const {
    if (ro.fancyVerticals()) {
      os << indent << "<object\n"
         << indent + s(2) << "class=\"obj\"\n"
         << indent + s(2) << "type=\"image/svg+xml\"\n"
         << indent + s(2) << "width=\"14px\"\n"
         << indent + s(2) << "height=\"55px\"\n"
         << indent + s(2) << "data=\"data:image/svg+xml,\n"
         << indent + s(4) << "<svg xmlns='http://www.w3.org/2000/svg'>\n"
         << indent + s(6) << "<text x='-55' y='10' "
                             "font-family='Courier' font-size='12' "
                             "transform='rotate(-90)' "
                             "text-rendering='optimizeSpeed' "
                             "fill='#000'>" << t << "</text>\n"
         << indent + s(4) << "</svg>\">\n"
         << indent << "</object>\n";
    } else {
      std::ostringstream oss;
      oss << t;
      std::string tStr(oss.str());

      os << indent;
      for (std::string::iterator tStrItr = tStr.begin(), tStrEnd = tStr.end();
           tStrItr != tStrEnd; ++tStrItr) {
        os << *tStrItr << "<br/>";
      }
      os << "\n";
    }
  }

  void RenderMachineFunction::insertCSS(const Spacer &indent,
                                        raw_ostream &os) const {
    os << indent << "<style type=\"text/css\">\n"
       << indent + s(2) << "body { font-color: black; }\n"
       << indent + s(2) << "table.code td { font-family: monospace; "
                    "border-width: 0px; border-style: solid; "
                    "border-bottom: 1px solid #dddddd; white-space: nowrap; }\n"
       << indent + s(2) << "table.code td.p-z { background-color: #000000; }\n"
       << indent + s(2) << "table.code td.p-l { background-color: #00ff00; }\n"
       << indent + s(2) << "table.code td.p-h { background-color: #ff0000; }\n"
       << indent + s(2) << "table.code td.l-n { background-color: #ffffff; }\n"
       << indent + s(2) << "table.code td.l-d { background-color: #ff0000; }\n"
       << indent + s(2) << "table.code td.l-u { background-color: #ffff00; }\n"
       << indent + s(2) << "table.code td.l-r { background-color: #000000; }\n"
       << indent + s(2) << "table.code td.l-s { background-color: #770000; }\n"
       << indent + s(2) << "table.code th { border-width: 0px; "
                    "border-style: solid; }\n"
       << indent << "</style>\n";
  }

  void RenderMachineFunction::renderFunctionSummary(
                                    const Spacer &indent, raw_ostream &os,
                                    const char * const renderContextStr) const {
    os << indent << "<h1>Function: " << mf->getFunction()->getName()
                 << "</h1>\n"
       << indent << "<h2>Rendering context: " << renderContextStr << "</h2>\n";
  }


  void RenderMachineFunction::renderPressureTableLegend(
                                                      const Spacer &indent,
                                                      raw_ostream &os) const {
    os << indent << "<h2>Rendering Pressure Legend:</h2>\n"
       << indent << "<table class=\"code\">\n"
       << indent + s(2) << "<tr>\n"
       << indent + s(4) << "<th>Pressure</th><th>Description</th>"
                    "<th>Appearance</th>\n"
       << indent + s(2) << "</tr>\n"
       << indent + s(2) << "<tr>\n"
       << indent + s(4) << "<td>No Pressure</td>"
                    "<td>No physical registers of this class requested.</td>"
                    "<td class=\"p-z\">&nbsp;&nbsp;</td>\n"
       << indent + s(2) << "</tr>\n"
       << indent + s(2) << "<tr>\n"
       << indent + s(4) << "<td>Low Pressure</td>"
                    "<td>Sufficient physical registers to meet demand.</td>"
                    "<td class=\"p-l\">&nbsp;&nbsp;</td>\n"
       << indent + s(2) << "</tr>\n"
       << indent + s(2) << "<tr>\n"
       << indent + s(4) << "<td>High Pressure</td>"
                    "<td>Potentially insufficient physical registers to meet demand.</td>"
                    "<td class=\"p-h\">&nbsp;&nbsp;</td>\n"
       << indent + s(2) << "</tr>\n"
       << indent << "</table>\n";
  }

  template <typename CellType>
  void RenderMachineFunction::renderCellsWithRLE(
                   const Spacer &indent, raw_ostream &os,
                   const std::pair<CellType, unsigned> &rleAccumulator,
                   const std::map<CellType, std::string> &cellTypeStrs) const {

    if (rleAccumulator.second == 0)
      return; 

    typename std::map<CellType, std::string>::const_iterator ctsItr =
      cellTypeStrs.find(rleAccumulator.first);

    assert(ctsItr != cellTypeStrs.end() && "No string for given cell type.");

    os << indent + s(4) << "<td class=\"" << ctsItr->second << "\"";
    if (rleAccumulator.second > 1)
      os << " colspan=" << rleAccumulator.second;
    os << "></td>\n";
  }


  void RenderMachineFunction::renderCodeTablePlusPI(const Spacer &indent,
                                                    raw_ostream &os) const {

    std::map<LiveState, std::string> lsStrs;
    lsStrs[Dead] = "l-n";
    lsStrs[Defined] = "l-d";
    lsStrs[Used] = "l-u";
    lsStrs[AliveReg] = "l-r";
    lsStrs[AliveStack] = "l-s";

    std::map<PressureState, std::string> psStrs;
    psStrs[Zero] = "p-z";
    psStrs[Low] = "p-l";
    psStrs[High] = "p-h";

    // Open the table... 

    os << indent << "<table cellpadding=0 cellspacing=0 class=\"code\">\n"
       << indent + s(2) << "<tr>\n";

    // Render the header row...

    os << indent + s(4) << "<th>index</th>\n"
       << indent + s(4) << "<th>instr</th>\n";

    // Render class names if necessary...
    if (!ro.regClasses().empty()) {
      for (MFRenderingOptions::RegClassSet::const_iterator
             rcItr = ro.regClasses().begin(),
             rcEnd = ro.regClasses().end();
           rcItr != rcEnd; ++rcItr) {
        const TargetRegisterClass *trc = *rcItr;
        os << indent + s(4) << "<th>\n";
        renderVertical(indent + s(6), os, trc->getName());
        os << indent + s(4) << "</th>\n";
      }
    }

    // FIXME: Is there a nicer way to insert space between columns in HTML?
    if (!ro.regClasses().empty() && !ro.intervals().empty())
      os << indent + s(4) << "<th>&nbsp;&nbsp;</th>\n";

    // Render interval numbers if necessary...
    if (!ro.intervals().empty()) {
      for (MFRenderingOptions::IntervalSet::const_iterator
             liItr = ro.intervals().begin(),
             liEnd = ro.intervals().end();
           liItr != liEnd; ++liItr) {

        const LiveInterval *li = *liItr;
        os << indent + s(4) << "<th>\n";
        renderVertical(indent + s(6), os, li->reg);
        os << indent + s(4) << "</th>\n";
      }
    }

    os << indent + s(2) << "</tr>\n";

    // End header row, start with the data rows...

    MachineInstr *mi = 0;

    // Data rows:
    for (SlotIndex i = sis->getZeroIndex(); i != sis->getLastIndex();
         i = i.getNextSlot()) {
     
      // Render the slot column. 
      os << indent + s(2) << "<tr height=6ex>\n";
      
      // Render the code column.
      if (i.getSlot() == SlotIndex::LOAD) {
        MachineBasicBlock *mbb = sis->getMBBFromIndex(i);
        mi = sis->getInstructionFromIndex(i);

        if (i == sis->getMBBStartIdx(mbb) || mi != 0 ||
            ro.renderEmptyIndexes()) {
          os << indent + s(4) << "<td rowspan=4>" << i << "&nbsp;</td>\n"
             << indent + s(4) << "<td rowspan=4>\n";

          if (i == sis->getMBBStartIdx(mbb)) {
            os << indent + s(6) << "BB#" << mbb->getNumber() << ":&nbsp;\n";
          } else if (mi != 0) {
            os << indent + s(6) << "&nbsp;&nbsp;";
            renderMachineInstr(os, mi);
          } else {
            // Empty interval - leave blank.
          }
          os << indent + s(4) << "</td>\n";
        } else {
          i = i.getStoreIndex(); // <- Will be incremented to the next index.
          continue;
        }
      }

      // Render the class columns.
      if (!ro.regClasses().empty()) {
        std::pair<PressureState, unsigned> psRLEAccumulator(Zero, 0);
        for (MFRenderingOptions::RegClassSet::const_iterator
               rcItr = ro.regClasses().begin(),
               rcEnd = ro.regClasses().end();
             rcItr != rcEnd; ++rcItr) {
          const TargetRegisterClass *trc = *rcItr;
          PressureState newPressure = getPressureStateAt(trc, i);

          if (newPressure == psRLEAccumulator.first) {
            ++psRLEAccumulator.second;
          } else {
            renderCellsWithRLE(indent + s(4), os, psRLEAccumulator, psStrs);
            psRLEAccumulator.first = newPressure;
            psRLEAccumulator.second = 1;
          }
        }
        renderCellsWithRLE(indent + s(4), os, psRLEAccumulator, psStrs);
      }
  
      // FIXME: Is there a nicer way to insert space between columns in HTML?
      if (!ro.regClasses().empty() && !ro.intervals().empty())
        os << indent + s(4) << "<td width=2em></td>\n";

      if (!ro.intervals().empty()) {
        std::pair<LiveState, unsigned> lsRLEAccumulator(Dead, 0);
        for (MFRenderingOptions::IntervalSet::const_iterator
               liItr = ro.intervals().begin(),
               liEnd = ro.intervals().end();
             liItr != liEnd; ++liItr) {
          const LiveInterval *li = *liItr;
          LiveState newLiveness = getLiveStateAt(li, i);

          if (newLiveness == lsRLEAccumulator.first) {
            ++lsRLEAccumulator.second;
          } else {
            renderCellsWithRLE(indent + s(4), os, lsRLEAccumulator, lsStrs);
            lsRLEAccumulator.first = newLiveness;
            lsRLEAccumulator.second = 1;
          }
        }
        renderCellsWithRLE(indent + s(4), os, lsRLEAccumulator, lsStrs);
      }
      os << indent + s(2) << "</tr>\n";
    }

    os << indent << "</table>\n";

    if (!ro.regClasses().empty())
      renderPressureTableLegend(indent, os);
  }

  void RenderMachineFunction::renderFunctionPage(
                                    raw_ostream &os,
                                    const char * const renderContextStr) const {
    os << "<html>\n"
       << s(2) << "<head>\n"
       << s(4) << "<title>" << fqn << "</title>\n";

    insertCSS(s(4), os);

    os << s(2) << "<head>\n"
       << s(2) << "<body >\n";

    renderFunctionSummary(s(4), os, renderContextStr);

    os << s(4) << "<br/><br/><br/>\n";

    //renderLiveIntervalInfoTable("    ", os);

    os << s(4) << "<br/><br/><br/>\n";

    renderCodeTablePlusPI(s(4), os);

    os << s(2) << "</body>\n"
       << "</html>\n";
  }

  void RenderMachineFunction::getAnalysisUsage(AnalysisUsage &au) const {
    au.addRequired<SlotIndexes>();
    au.addRequired<LiveIntervals>();
    au.setPreservesAll();
    MachineFunctionPass::getAnalysisUsage(au);
  }

  bool RenderMachineFunction::runOnMachineFunction(MachineFunction &fn) {
    mf = &fn;
    mri = &mf->getRegInfo();
    tri = mf->getTarget().getRegisterInfo();
    lis = &getAnalysis<LiveIntervals>();
    sis = &getAnalysis<SlotIndexes>();

    trei.setup(mf, mri, tri, lis);
    ro.setup(mf, tri, lis);

    fqn = mf->getFunction()->getParent()->getModuleIdentifier() + "." +
          mf->getFunction()->getName().str();

    return false;
  }

  void RenderMachineFunction::releaseMemory() {
    trei.clear();
    ro.clear();
  }

  void RenderMachineFunction::renderMachineFunction(
                                                   const char *renderContextStr,
                                                   const VirtRegMap *vrm,
                                                   const char *renderSuffix) {
    if (!ro.shouldRenderCurrentMachineFunction())
      return; 

    this->vrm = vrm;
    trei.reset();

    std::string rpFileName(mf->getFunction()->getName().str() +
                           (renderSuffix ? renderSuffix : "") +
                           outputFileSuffix);

    std::string errMsg;
    raw_fd_ostream outFile(rpFileName.c_str(), errMsg, raw_fd_ostream::F_Binary);

    renderFunctionPage(outFile, renderContextStr);

    ro.resetRenderSpecificOptions();
  }

  std::string RenderMachineFunction::escapeChars(const std::string &s) const {
    return escapeChars(s.begin(), s.end());
  }

}
