From add5c9809ba804ed03c7f289a29fccb158d27ae9 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 3 Dec 2015 23:00:28 +0000 Subject: [PATCH] Revert "raw_ostream: << operator for callables with raw_stream argument" This commit provoked "error C2593: 'operator <<' is ambiguous" on MSVC. This reverts commit r254655. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254661 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/raw_ostream.h | 14 ---- include/llvm/Target/TargetRegisterInfo.h | 73 ++++++++++++++++--- lib/CodeGen/RegAllocPBQP.cpp | 26 +++++-- lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp | 17 ++++- lib/CodeGen/TargetRegisterInfo.cpp | 95 +++++++++++-------------- lib/Support/raw_ostream.cpp | 4 -- 6 files changed, 140 insertions(+), 89 deletions(-) diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 38a96fa6ab7..e5cc40e7d6b 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -17,14 +17,12 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" -#include #include namespace llvm { class format_object_base; class FormattedString; class FormattedNumber; -class raw_ostream; template class SmallVectorImpl; namespace sys { @@ -33,15 +31,6 @@ enum OpenFlags : unsigned; } } -/// Type of function that prints to raw_ostream. -/// -/// Typical usage: -/// Printable PrintFoo(Foo x) { -/// return [] (raw_ostream &os) { os << /* ... */; }; -/// } -/// os << "Foo: " << PrintFoo(foo) << '\n'; -typedef std::function Printable; - /// This class implements an extremely fast bulk output stream that can *only* /// output to a stream. It does not support seeking, reopening, rewinding, line /// buffered disciplines etc. It is a simple buffer that outputs @@ -214,9 +203,6 @@ public: raw_ostream &operator<<(double N); - /// IO manipulator, \see Printable. - raw_ostream &operator<<(Printable P); - /// Output \p N in hexadecimal, without any prefix or padding. raw_ostream &write_hex(unsigned long long N); diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index de6f46eba01..7d293fe82a6 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -932,6 +932,7 @@ struct VirtReg2IndexFunctor : public std::unary_function { } }; +/// Helper class for printing registers on a raw_ostream. /// Prints virtual and physical registers with or without a TRI instance. /// /// The format is: @@ -942,10 +943,24 @@ struct VirtReg2IndexFunctor : public std::unary_function { /// %physreg17 - a physical register when no TRI instance given. /// /// Usage: OS << PrintReg(Reg, TRI) << '\n'; -Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI = nullptr, - unsigned SubRegIdx = 0); +/// +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; +}; -/// Create Printable object to print register units on a \ref raw_ostream. +static inline raw_ostream &operator<<(raw_ostream &OS, const PrintReg &PR) { + PR.print(OS); + return OS; +} + +/// Helper class for printing register units on a raw_ostream. /// /// Register units are named after their root registers: /// @@ -953,14 +968,54 @@ Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI = nullptr, /// FP0~ST7 - Dual roots. /// /// Usage: OS << PrintRegUnit(Unit, TRI) << '\n'; -Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI); +/// +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; +} -/// \brief Create Printable object to print virtual registers and physical -/// registers on a \ref raw_ostream. -Printable PrintVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI); +/// 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; +}; -/// Create Printable object to print LaneBitmasks on a \ref raw_ostream. -Printable PrintLaneMask(LaneBitmask LaneMask); +static inline raw_ostream &operator<<(raw_ostream &OS, const PrintLaneMask &P) { + P.print(OS); + return OS; +} } // End llvm namespace diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp index f08d616e681..afa98b26d72 100644 --- a/lib/CodeGen/RegAllocPBQP.cpp +++ b/lib/CodeGen/RegAllocPBQP.cpp @@ -805,17 +805,33 @@ bool RegAllocPBQP::runOnMachineFunction(MachineFunction &MF) { return true; } -/// Create Printable object for node and register info. -static Printable PrintNodeInfo(PBQP::RegAlloc::PBQPRAGraph::NodeId NId, - const PBQP::RegAlloc::PBQPRAGraph &G) { - return [NId, &G](raw_ostream &OS) { +namespace { +// A helper class for printing node and register info in a consistent way +class PrintNodeInfo { +public: + typedef PBQP::RegAlloc::PBQPRAGraph Graph; + typedef PBQP::RegAlloc::PBQPRAGraph::NodeId NodeId; + + PrintNodeInfo(NodeId NId, const Graph &G) : G(G), NId(NId) {} + + void print(raw_ostream &OS) const { const MachineRegisterInfo &MRI = G.getMetadata().MF.getRegInfo(); const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo(); unsigned VReg = G.getNodeMetadata(NId).getVReg(); const char *RegClassName = TRI->getRegClassName(MRI.getRegClass(VReg)); OS << NId << " (" << RegClassName << ':' << PrintReg(VReg, TRI) << ')'; - }; + } + +private: + const Graph &G; + NodeId NId; +}; + +inline raw_ostream &operator<<(raw_ostream &OS, const PrintNodeInfo &PR) { + PR.print(OS); + return OS; } +} // anonymous namespace void PBQP::RegAlloc::PBQPRAGraph::dump(raw_ostream &OS) const { for (auto NId : nodeIds()) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp index 8c3a0f2d81e..d362f98d646 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp @@ -369,14 +369,25 @@ const char *SDNode::getIndexedModeName(ISD::MemIndexedMode AM) { } } -static Printable PrintNodeId(const SDNode &Node) { - return [&Node](raw_ostream &OS) { +namespace { +class PrintNodeId { + const SDNode &Node; +public: + explicit PrintNodeId(const SDNode &Node) + : Node(Node) {} + void print(raw_ostream &OS) const { #ifndef NDEBUG OS << 't' << Node.PersistentId; #else OS << (const void*)&Node; #endif - }; + } +}; + +static inline raw_ostream &operator<<(raw_ostream &OS, const PrintNodeId &P) { + P.print(OS); + return OS; +} } void SDNode::dump() const { dump(nullptr); } diff --git a/lib/CodeGen/TargetRegisterInfo.cpp b/lib/CodeGen/TargetRegisterInfo.cpp index 839d9ef31ad..0c4a3dcb226 100644 --- a/lib/CodeGen/TargetRegisterInfo.cpp +++ b/lib/CodeGen/TargetRegisterInfo.cpp @@ -40,71 +40,58 @@ TargetRegisterInfo::TargetRegisterInfo(const TargetRegisterInfoDesc *ID, TargetRegisterInfo::~TargetRegisterInfo() {} -namespace llvm { - -Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI, - unsigned SubIdx) { - return [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); +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); else - OS << "%physreg" << Reg; - if (SubIdx) { - if (TRI) - OS << ':' << TRI->getSubRegIndexName(SubIdx); - else - OS << ":sub(" << SubIdx << ')'; - } - }; + OS << ":sub(" << SubIdx << ')'; + } } -Printable PrintRegUnit(unsigned Unit, const TargetRegisterInfo *TRI) { - return [Unit, TRI](raw_ostream &OS) { - // Generic printout when TRI is missing. - if (!TRI) { - OS << "Unit~" << Unit; - return; - } +void PrintRegUnit::print(raw_ostream &OS) const { + // 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); } -Printable PrintVRegOrUnit(unsigned Unit, const TargetRegisterInfo *TRI) { - return [Unit, TRI](raw_ostream &OS) { - if (TRI && TRI->isVirtualRegister(Unit)) { - OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Unit); - } else { - OS << PrintRegUnit(Unit, TRI); - } - }; +void PrintVRegOrUnit::print(raw_ostream &OS) const { + if (TRI && TRI->isVirtualRegister(Unit)) { + OS << "%vreg" << TargetRegisterInfo::virtReg2Index(Unit); + return; + } + PrintRegUnit::print(OS); } -Printable PrintLaneMask(LaneBitmask LaneMask) { - return [LaneMask](raw_ostream &OS) { - OS << format("%08X", LaneMask); - }; +void PrintLaneMask::print(raw_ostream &OS) const { + 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 * diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index 5b1dceca0bf..49ef400c5f2 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -264,10 +264,6 @@ raw_ostream &raw_ostream::operator<<(double N) { return this->operator<<(format("%e", N)); } -raw_ostream &raw_ostream::operator<<(Printable P) { - P(*this); - return *this; -} void raw_ostream::flush_nonempty() { -- 2.11.0