--- /dev/null
+//===--- 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 <functional>
+
+namespace llvm {
+
+class raw_ostream;
+
+/// Simple wrapper around std::function<void(raw_ostream&)>.
+/// This class is usefull to construct print helpers for raw_ostream.
+///
+/// Example:
+/// Printable PrintRegister(unsigned Register) {
+/// return Printable([Register](raw_ostream &OS) {
+/// OS << getRegisterName(Register);
+/// }
+/// }
+/// ... OS << PrintRegister(Register); ...
+///
+/// Implementation note: Ideally this would just be a typedef, but doing so
+/// leads to operator << being ambiguous as function has matching constructors
+/// in some STL versions. I have seen the problem on gcc 4.6 libstdc++ and
+/// microsoft STL.
+class Printable {
+public:
+ std::function<void(raw_ostream &OS)> Print;
+ Printable(const std::function<void(raw_ostream &OS)> Print)
+ : Print(Print) {}
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const Printable &P) {
+ P.Print(OS);
+ return OS;
+}
+
+}
+
+#endif
#include "llvm/IR/CallingConv.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Printable.h"
#include <cassert>
#include <functional>
}
};
-/// 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';
-///
-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;
-}
-
-/// 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:
///
/// 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);
-/// 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
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Printable.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
return true;
}
-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 {
+/// Create Printable object for node and register info.
+static Printable PrintNodeInfo(PBQP::RegAlloc::PBQPRAGraph::NodeId NId,
+ const PBQP::RegAlloc::PBQPRAGraph &G) {
+ return Printable([NId, &G](raw_ostream &OS) {
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()) {
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/Printable.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetIntrinsicInfo.h"
}
}
-namespace {
-class PrintNodeId {
- const SDNode &Node;
-public:
- explicit PrintNodeId(const SDNode &Node)
- : Node(Node) {}
- void print(raw_ostream &OS) const {
+static Printable PrintNodeId(const SDNode &Node) {
+ return Printable([&Node](raw_ostream &OS) {
#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() {}
-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(LaneBitmask 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 *