Index: include/llvm/Support/Printable.h =================================================================== --- /dev/null +++ include/llvm/Support/Printable.h @@ -0,0 +1,45 @@ +//===--- Printable.h - Print function helpers -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the Printable struct. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_PRINTABLE_H +#define LLVM_SUPPORT_PRINTABLE_H + +#include + +namespace llvm { + +class raw_ostream; + +/// Used to conveniently create Print functions. +/// Example: +/// Printable PrintRegister(unsigned Register) { +/// return Printable([Register](raw_ostream &OS) { +/// OS << getRegisterName(Register); +/// } +/// } +/// ... OS << PrintRegister(Register); ... +class Printable { +public: + std::function Print; + Printable(const std::function Print) + : Print(Print) {} +}; + +static inline raw_ostream &operator<<(raw_ostream &OS, const Printable &P) { + P.Print(OS); + return OS; +} + +} + +#endif Index: include/llvm/Target/TargetRegisterInfo.h =================================================================== --- include/llvm/Target/TargetRegisterInfo.h +++ include/llvm/Target/TargetRegisterInfo.h @@ -22,6 +22,7 @@ #include "llvm/IR/CallingConv.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/Printable.h" #include #include @@ -955,7 +956,7 @@ } }; -/// PrintReg - Helper class for printing registers on a raw_ostream. +/// Create Printable object to print registers on a \ref raw_ostream. /// Prints virtual and physical registers with or without a TRI instance. /// /// The format is: @@ -966,24 +967,10 @@ /// %physreg17 - a physical register when no TRI instance given. /// /// Usage: OS << PrintReg(Reg, TRI) << '\n'; -/// -class PrintReg { - const TargetRegisterInfo *TRI; - unsigned Reg; - unsigned SubIdx; -public: - explicit PrintReg(unsigned reg, const TargetRegisterInfo *tri = nullptr, - unsigned subidx = 0) - : TRI(tri), Reg(reg), SubIdx(subidx) {} - void print(raw_ostream&) const; -}; +Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI = nullptr, + unsigned SubRegIdx = 0); -static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) { - PR.print(OS); - return OS; -} - -/// PrintRegUnit - Helper class for printing register units on a raw_ostream. +/// Create Printable object to print register units on a \ref raw_ostream. /// /// Register units are named after their root registers: /// @@ -991,54 +978,14 @@ /// FP0~ST7 - Dual roots. /// /// Usage: OS << PrintRegUnit(Unit, TRI) << '\n'; -/// -class PrintRegUnit { -protected: - const TargetRegisterInfo *TRI; - unsigned Unit; -public: - PrintRegUnit(unsigned unit, const TargetRegisterInfo *tri) - : TRI(tri), Unit(unit) {} - void print(raw_ostream&) const; -}; - -static inline raw_ostream &operator<<(raw_ostream &OS, const PrintRegUnit &PR) { - PR.print(OS); - return OS; -} +Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI); -/// PrintVRegOrUnit - It is often convenient to track virtual registers and -/// physical register units in the same list. -class PrintVRegOrUnit : protected PrintRegUnit { -public: - PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *tri) - : PrintRegUnit(VRegOrUnit, tri) {} - void print(raw_ostream&) const; -}; - -static inline raw_ostream &operator<<(raw_ostream &OS, - const PrintVRegOrUnit &PR) { - PR.print(OS); - return OS; -} - -/// Helper class for printing lane masks. -/// -/// They are currently printed out as hexadecimal numbers. -/// Usage: OS << PrintLaneMask(Mask); -class PrintLaneMask { -protected: - LaneBitmask LaneMask; -public: - PrintLaneMask(LaneBitmask LaneMask) - : LaneMask(LaneMask) {} - void print(raw_ostream&) const; -}; +/// \brief Create Printable object to print virtual registers and physical +/// registers on a \ref raw_ostream. +Printable PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI); -static inline raw_ostream &operator<<(raw_ostream &OS, const PrintLaneMask &P) { - P.print(OS); - return OS; -} +/// Create Printable object to print LaneBitmasks on a \ref raw_ostream. +Printable PrintLaneMask(LaneBitmask LaneMask); } // End llvm namespace Index: lib/CodeGen/TargetRegisterInfo.cpp =================================================================== --- lib/CodeGen/TargetRegisterInfo.cpp +++ lib/CodeGen/TargetRegisterInfo.cpp @@ -40,58 +40,71 @@ TargetRegisterInfo::~TargetRegisterInfo() {} -void PrintReg::print(raw_ostream &OS) const { - if (!Reg) - OS << "%noreg"; - else if (TargetRegisterInfo::isStackSlot(Reg)) - OS << "SS#" << TargetRegisterInfo::stackSlot2Index(Reg); - else if (TargetRegisterInfo::isVirtualRegister(Reg)) - OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Reg); - else if (TRI && Reg < TRI->getNumRegs()) - OS << '%' << TRI->getName(Reg); - else - OS << "%physreg" << Reg; - if (SubIdx) { - if (TRI) - OS << ':' << TRI->getSubRegIndexName(SubIdx); +namespace llvm { + +Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI, + unsigned SubIdx) { + return Printable([Reg, TRI, SubIdx](raw_ostream &OS) { + if (!Reg) + OS << "%noreg"; + else if (TargetRegisterInfo::isStackSlot(Reg)) + OS << "SS#" << TargetRegisterInfo::stackSlot2Index(Reg); + else if (TargetRegisterInfo::isVirtualRegister(Reg)) + OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Reg); + else if (TRI && Reg < TRI->getNumRegs()) + OS << '%' << TRI->getName(Reg); else - OS << ":sub(" << SubIdx << ')'; - } + OS << "%physreg" << Reg; + if (SubIdx) { + if (TRI) + OS << ':' << TRI->getSubRegIndexName(SubIdx); + else + OS << ":sub(" << SubIdx << ')'; + } + }); } -void PrintRegUnit::print(raw_ostream &OS) const { - // Generic printout when TRI is missing. - if (!TRI) { - OS << "Unit~" << Unit; - return; - } +Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) { + return Printable([Unit, TRI](raw_ostream &OS) { + // Generic printout when TRI is missing. + if (!TRI) { + OS << "Unit~" << Unit; + return; + } - // Check for invalid register units. - if (Unit >= TRI->getNumRegUnits()) { - OS << "BadUnit~" << Unit; - return; - } + // Check for invalid register units. + if (Unit >= TRI->getNumRegUnits()) { + OS << "BadUnit~" << Unit; + return; + } - // Normal units have at least one root. - MCRegUnitRootIterator Roots(Unit, TRI); - assert(Roots.isValid() && "Unit has no roots."); - OS << TRI->getName(*Roots); - for (++Roots; Roots.isValid(); ++Roots) - OS << '~' << TRI->getName(*Roots); + // Normal units have at least one root. + MCRegUnitRootIterator Roots(Unit, TRI); + assert(Roots.isValid() && "Unit has no roots."); + OS << TRI->getName(*Roots); + for (++Roots; Roots.isValid(); ++Roots) + OS << '~' << TRI->getName(*Roots); + }); } -void PrintVRegOrUnit::print(raw_ostream &OS) const { - if (TRI && TRI->isVirtualRegister(Unit)) { - OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Unit); - return; - } - PrintRegUnit::print(OS); +Printable PrintVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) { + return Printable([Unit, TRI](raw_ostream &OS) { + if (TRI && TRI->isVirtualRegister(Unit)) { + OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Unit); + } else { + OS << PrintRegUnit(Unit, TRI); + } + }); } -void PrintLaneMask::print(raw_ostream &OS) const { - OS << format("%08X", LaneMask); +Printable PrintLaneMask(unsigned LaneMask) { + return Printable([LaneMask](raw_ostream &OS) { + OS << format("%08X", LaneMask); + }); } +} // End of llvm namespace + /// getAllocatableClass - Return the maximal subclass of the given register /// class that is alloctable, or NULL. const TargetRegisterClass *