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

#ifndef LLVM_CODEGEN_RENDERMACHINEFUNCTION_H
#define LLVM_CODEGEN_RENDERMACHINEFUNCTION_H

#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/Target/TargetRegisterInfo.h"

#include <algorithm>
#include <map>
#include <set>
#include <string>

namespace llvm {

  class LiveInterval;
  class LiveIntervals;
  class MachineInstr;
  class MachineRegisterInfo;
  class RenderMachineFunction;
  class TargetRegisterClass;
  class TargetRegisterInfo;
  class VirtRegMap;
  class raw_ostream;

  /// \brief Helper class to process rendering options. Tries to be as lazy as
  ///        possible.
  class MFRenderingOptions {
  public:

    struct RegClassComp {
      bool operator()(const TargetRegisterClass *trc1,
                      const TargetRegisterClass *trc2) const {
        std::string trc1Name(trc1->getName()), trc2Name(trc2->getName());
        return std::lexicographical_compare(trc1Name.begin(), trc1Name.end(),
                                            trc2Name.begin(), trc2Name.end());
      }
    };

    typedef std::set<const TargetRegisterClass*, RegClassComp> RegClassSet;

    struct IntervalComp {
      bool operator()(const LiveInterval *li1, const LiveInterval *li2) const {
        return li1->reg < li2->reg;
      }
    };

    typedef std::set<const LiveInterval*, IntervalComp> IntervalSet;

    /// Initialise the rendering options.
    void setup(MachineFunction *mf, const TargetRegisterInfo *tri,
               LiveIntervals *lis, const RenderMachineFunction *rmf);

    /// Clear translations of options to the current function.
    void clear();

    /// Reset any options computed for this specific rendering.
    void resetRenderSpecificOptions();

    /// Should we render the current function.
    bool shouldRenderCurrentMachineFunction() const;

    /// Return the set of register classes to render pressure for.
    const RegClassSet& regClasses() const;

    /// Return the set of live intervals to render liveness for.
    const IntervalSet& intervals() const;

    /// Render indexes which are not associated with instructions / MBB starts.
    bool renderEmptyIndexes() const;

    /// Return whether or not to render using SVG for fancy vertical text.
    bool fancyVerticals() const;

  private:

    static bool renderingOptionsProcessed;
    static std::set<std::string> mfNamesToRender;
    static bool renderAllMFs;

    static std::set<std::string> classNamesToRender;
    static bool renderAllClasses;


    static std::set<std::pair<unsigned, unsigned> > intervalNumsToRender;
    typedef enum { ExplicitOnly     = 0,
                   AllPhys          = 1,
                   VirtNoSpills     = 2,
                   VirtSpills       = 4,
                   AllVirt          = 6,
                   All              = 7 }
      IntervalTypesToRender;
    static unsigned intervalTypesToRender;

    template <typename OutputItr>
    static void splitComaSeperatedList(const std::string &s, OutputItr outItr);

    static void processOptions();

    static void processFuncNames();
    static void processRegClassNames();
    static void processIntervalNumbers();

    static void processIntervalRange(const std::string &intervalRangeStr);

    MachineFunction *mf;
    const TargetRegisterInfo *tri;
    LiveIntervals *lis;
    const RenderMachineFunction *rmf;

    mutable bool regClassesTranslatedToCurrentFunction;
    mutable RegClassSet regClassSet;

    mutable bool intervalsTranslatedToCurrentFunction;
    mutable IntervalSet intervalSet;

    void translateRegClassNamesToCurrentFunction() const;

    void translateIntervalNumbersToCurrentFunction() const;
  };

  /// \brief Provide extra information about the physical and virtual registers
  ///        in the function being compiled.
  class TargetRegisterExtraInfo {
  public:
    TargetRegisterExtraInfo();

    /// \brief Set up TargetRegisterExtraInfo with pointers to necessary
    ///        sources of information.
    void setup(MachineFunction *mf, MachineRegisterInfo *mri,
               const TargetRegisterInfo *tri, LiveIntervals *lis);

    /// \brief Recompute tables for changed function.
    void reset(); 

    /// \brief Free all tables in TargetRegisterExtraInfo.
    void clear();

    /// \brief Maximum number of registers from trc which alias reg.
    unsigned getWorst(unsigned reg, const TargetRegisterClass *trc) const;

    /// \brief Returns the number of allocable registers in trc.
    unsigned getCapacity(const TargetRegisterClass *trc) const;

    /// \brief Return the number of registers of class trc that may be
    ///        needed at slot i.
    unsigned getPressureAtSlot(const TargetRegisterClass *trc,
                               SlotIndex i) const;

    /// \brief Return true if the number of registers of type trc that may be
    ///        needed at slot i is greater than the capacity of trc.
    bool classOverCapacityAtSlot(const TargetRegisterClass *trc,
                                 SlotIndex i) const;

  private:

    MachineFunction *mf;
    MachineRegisterInfo *mri;
    const TargetRegisterInfo *tri;
    LiveIntervals *lis;

    typedef std::map<const TargetRegisterClass*, unsigned> WorstMapLine;
    typedef std::map<const TargetRegisterClass*, WorstMapLine> VRWorstMap;
    VRWorstMap vrWorst;

    typedef std::map<unsigned, WorstMapLine> PRWorstMap;
    PRWorstMap prWorst;

    typedef std::map<const TargetRegisterClass*, unsigned> CapacityMap;
    CapacityMap capacityMap;

    typedef std::map<const TargetRegisterClass*, unsigned> PressureMapLine;
    typedef std::map<SlotIndex, PressureMapLine> PressureMap;
    PressureMap pressureMap;

    bool mapsPopulated;

    /// \brief Initialise the 'worst' table.
    void initWorst();
 
    /// \brief Initialise the 'capacity' table.
    void initCapacity();

    /// \brief Initialise/Reset the 'pressure' and live states tables.
    void resetPressureAndLiveStates();
  };

  /// \brief Render MachineFunction objects and related information to a HTML
  ///        page.
  class RenderMachineFunction : public MachineFunctionPass {
  public:
    static char ID;

    RenderMachineFunction() : MachineFunctionPass(ID) {
      initializeRenderMachineFunctionPass(*PassRegistry::getPassRegistry());
    }

    virtual void getAnalysisUsage(AnalysisUsage &au) const;

    virtual bool runOnMachineFunction(MachineFunction &fn);

    virtual void releaseMemory();

    void rememberUseDefs(const LiveInterval *li);

    void rememberSpills(const LiveInterval *li,
                        const std::vector<LiveInterval*> &spills);

    bool isSpill(const LiveInterval *li) const;

    /// \brief Render this machine function to HTML.
    /// 
    /// @param renderContextStr This parameter will be included in the top of
    ///                         the html file to explain where (in the
    ///                         codegen pipeline) this function was rendered
    ///                         from. Set it to something like
    ///                         "Pre-register-allocation".
    /// @param vrm              If non-null the VRM will be queried to determine
    ///                         whether a virtual register was allocated to a
    ///                         physical register or spilled.
    /// @param renderFilePrefix This string will be appended to the function
    ///                         name (before the output file suffix) to enable
    ///                         multiple renderings from the same function.
    void renderMachineFunction(const char *renderContextStr,
                               const VirtRegMap *vrm = 0,
                               const char *renderSuffix = 0);

  private:
    class Spacer;
    friend raw_ostream& operator<<(raw_ostream &os, const Spacer &s);

    std::string fqn;

    MachineFunction *mf;
    MachineRegisterInfo *mri;
    const TargetRegisterInfo *tri;
    LiveIntervals *lis;
    SlotIndexes *sis;
    const VirtRegMap *vrm;

    TargetRegisterExtraInfo trei;
    MFRenderingOptions ro;

    

    // Utilities.
    typedef enum { Dead, Defined, Used, AliveReg, AliveStack } LiveState;
    LiveState getLiveStateAt(const LiveInterval *li, SlotIndex i) const;

    typedef enum { Zero, Low, High } PressureState;
    PressureState getPressureStateAt(const TargetRegisterClass *trc,
                                     SlotIndex i) const;

    typedef std::map<const LiveInterval*, std::set<const LiveInterval*> >
      SpillIntervals;
    SpillIntervals spillIntervals;

    typedef std::map<const LiveInterval*, const LiveInterval*> SpillForMap;
    SpillForMap spillFor;

    typedef std::set<SlotIndex> SlotSet;
    typedef std::map<const LiveInterval*, SlotSet> UseDefs;
    UseDefs useDefs;

    // ---------- Rendering methods ----------

    /// For inserting spaces when pretty printing.
    class Spacer {
    public:
      explicit Spacer(unsigned numSpaces) : ns(numSpaces) {}
      Spacer operator+(const Spacer &o) const { return Spacer(ns + o.ns); }
      void print(raw_ostream &os) const;
    private:
      unsigned ns;
    };

    Spacer s(unsigned ns) const;

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

    /// \brief Render a machine instruction.
    void renderMachineInstr(raw_ostream &os,
                            const MachineInstr *mi) const;

    /// \brief Render vertical text.
    template <typename T>
    void renderVertical(const Spacer &indent,
                        raw_ostream &os,
                        const T &t) const;

    /// \brief Insert CSS layout info.
    void insertCSS(const Spacer &indent,
                   raw_ostream &os) const;

    /// \brief Render a brief summary of the function (including rendering
    ///        context).
    void renderFunctionSummary(const Spacer &indent,
                               raw_ostream &os,
                               const char * const renderContextStr) const;

    /// \brief Render a legend for the pressure table.
    void renderPressureTableLegend(const Spacer &indent,
                                   raw_ostream &os) const;

    /// \brief Render a consecutive set of HTML cells of the same class using
    /// the colspan attribute for run-length encoding.
    template <typename CellType>
    void renderCellsWithRLE(
                     const Spacer &indent, raw_ostream &os,
                     const std::pair<CellType, unsigned> &rleAccumulator,
                     const std::map<CellType, std::string> &cellTypeStrs) const;

    /// \brief Render code listing, potentially with register pressure
    ///        and live intervals shown alongside.
    void renderCodeTablePlusPI(const Spacer &indent,
                               raw_ostream &os) const;

    /// \brief Render the HTML page representing the MachineFunction.
    void renderFunctionPage(raw_ostream &os,
                            const char * const renderContextStr) const;

    std::string escapeChars(const std::string &s) const;
  };
}

#endif /* LLVM_CODEGEN_RENDERMACHINEFUNCTION_H */
