#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TableGen/Error.h"
using namespace llvm;
+cl::OptionCategory RegisterInfoCat("Options for -gen-register-info");
+
+static cl::opt<bool>
+ RegisterInfoDebug("register-info-debug", cl::init(false),
+ cl::desc("Dump register information to help debugging"),
+ cl::cat(RegisterInfoCat));
+
namespace {
class RegisterInfoEmitter {
+ CodeGenTarget Target;
RecordKeeper &Records;
public:
- RegisterInfoEmitter(RecordKeeper &R) : Records(R) {}
+ RegisterInfoEmitter(RecordKeeper &R) : Target(R), Records(R) {
+ CodeGenRegBank &RegBank = Target.getRegBank();
+ RegBank.computeDerivedInfo();
+ }
// runEnums - Print out enum values for all of the registers.
void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank);
// run - Output the register file description.
void run(raw_ostream &o);
+ void debugDump(raw_ostream &OS);
+
private:
void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs,
bool isCtor);
}
void RegisterInfoEmitter::run(raw_ostream &OS) {
- CodeGenTarget Target(Records);
CodeGenRegBank &RegBank = Target.getRegBank();
- RegBank.computeDerivedInfo();
-
runEnums(OS, Target, RegBank);
runMCDesc(OS, Target, RegBank);
runTargetHeader(OS, Target, RegBank);
runTargetDesc(OS, Target, RegBank);
+
+ if (RegisterInfoDebug)
+ debugDump(errs());
+}
+
+void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
+ CodeGenRegBank &RegBank = Target.getRegBank();
+
+ for (const CodeGenRegisterClass &RC : RegBank.getRegClasses()) {
+ OS << "RegisterClass " << RC.getName() << ":\n";
+ OS << "\tSpillSize: " << RC.SpillSize << '\n';
+ OS << "\tSpillAlignment: " << RC.SpillAlignment << '\n';
+ OS << "\tNumRegs: " << RC.getMembers().size() << '\n';
+ OS << "\tLaneMask: " << PrintLaneMask(RC.LaneMask) << '\n';
+ OS << "\tHasDisjunctSubRegs: " << RC.HasDisjunctSubRegs << '\n';
+ OS << "\tCoveredBySubRegs: " << RC.CoveredBySubRegs << '\n';
+ OS << "\tRegs:";
+ for (const CodeGenRegister *R : RC.getMembers()) {
+ OS << " " << R->getName();
+ }
+ OS << '\n';
+ OS << "\tSubClasses:";
+ const BitVector &SubClasses = RC.getSubClasses();
+ for (const CodeGenRegisterClass &SRC : RegBank.getRegClasses()) {
+ if (!SubClasses.test(SRC.EnumValue))
+ continue;
+ OS << " " << SRC.getName();
+ }
+ OS << '\n';
+ OS << "\tSuperClasses:";
+ for (const CodeGenRegisterClass *SRC : RC.getSuperClasses()) {
+ OS << " " << SRC->getName();
+ }
+ OS << '\n';
+ }
+
+ for (const CodeGenSubRegIndex &SRI : RegBank.getSubRegIndices()) {
+ OS << "SubRegIndex " << SRI.getName() << ":\n";
+ OS << "\tLaneMask: " << PrintLaneMask(SRI.LaneMask) << '\n';
+ OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n';
+ }
+
+ for (const CodeGenRegister &R : RegBank.getRegisters()) {
+ OS << "Register " << R.getName() << ":\n";
+ OS << "\tCostPerUse: " << R.CostPerUse << '\n';
+ OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
+ OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
+ for (std::pair<CodeGenSubRegIndex*,CodeGenRegister*> P : R.getSubRegs()) {
+ OS << "\tSubReg " << P.first->getName()
+ << " = " << P.second->getName() << '\n';
+ }
+ }
}
namespace llvm {