#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
-#include <functional>
#include <system_error>
namespace llvm {
class format_object_base;
class FormattedString;
class FormattedNumber;
-class raw_ostream;
template <typename T> class SmallVectorImpl;
namespace sys {
}
}
-/// 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<void(raw_ostream&)> 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
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);
}
};
+/// Helper class for printing registers on a raw_ostream.
/// Prints virtual and physical registers with or without a TRI instance.
///
/// The format is:
/// %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:
///
/// 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
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()) {
}
}
-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); }
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 *
return this->operator<<(format("%e", N));
}
-raw_ostream &raw_ostream::operator<<(Printable P) {
- P(*this);
- return *this;
-}
void raw_ostream::flush_nonempty() {