diff options
author | dim <dim@FreeBSD.org> | 2010-09-17 15:48:55 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2010-09-17 15:48:55 +0000 |
commit | 5d5cc59cc77afe655b3707cb0e69e0827b444cad (patch) | |
tree | 36453626c792cccd91f783a38a169d610a6b9db9 /lib/CodeGen/RenderMachineFunction.h | |
parent | 786a18553586229ad99ecb5ecde8a9d914c45e27 (diff) | |
download | FreeBSD-src-5d5cc59cc77afe655b3707cb0e69e0827b444cad.zip FreeBSD-src-5d5cc59cc77afe655b3707cb0e69e0827b444cad.tar.gz |
Vendor import of llvm r114020 (from the release_28 branch):
http://llvm.org/svn/llvm-project/llvm/branches/release_28@114020
Approved by: rpaulo (mentor)
Diffstat (limited to 'lib/CodeGen/RenderMachineFunction.h')
-rw-r--r-- | lib/CodeGen/RenderMachineFunction.h | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/lib/CodeGen/RenderMachineFunction.h b/lib/CodeGen/RenderMachineFunction.h new file mode 100644 index 0000000..8d56a82 --- /dev/null +++ b/lib/CodeGen/RenderMachineFunction.h @@ -0,0 +1,336 @@ +//===-- 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) {} + + 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 */ |