Changeset View
Changeset View
Standalone View
Standalone View
llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp
Show All 20 Lines | |||||
#include "llvm/ADT/BitVector.h" | #include "llvm/ADT/BitVector.h" | ||||
#include "llvm/ADT/SetVector.h" | #include "llvm/ADT/SetVector.h" | ||||
#include "llvm/ADT/SmallVector.h" | #include "llvm/ADT/SmallVector.h" | ||||
#include "llvm/ADT/SparseBitVector.h" | #include "llvm/ADT/SparseBitVector.h" | ||||
#include "llvm/ADT/STLExtras.h" | #include "llvm/ADT/STLExtras.h" | ||||
#include "llvm/ADT/Twine.h" | #include "llvm/ADT/Twine.h" | ||||
#include "llvm/CodeGen/MachineValueType.h" | #include "llvm/CodeGen/MachineValueType.h" | ||||
#include "llvm/Support/Casting.h" | #include "llvm/Support/Casting.h" | ||||
#include "llvm/Support/CommandLine.h" | |||||
#include "llvm/Support/Format.h" | #include "llvm/Support/Format.h" | ||||
#include "llvm/Support/raw_ostream.h" | #include "llvm/Support/raw_ostream.h" | ||||
#include "llvm/TableGen/Error.h" | #include "llvm/TableGen/Error.h" | ||||
#include "llvm/TableGen/Record.h" | #include "llvm/TableGen/Record.h" | ||||
#include "llvm/TableGen/SetTheory.h" | #include "llvm/TableGen/SetTheory.h" | ||||
#include "llvm/TableGen/TableGenBackend.h" | #include "llvm/TableGen/TableGenBackend.h" | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cassert> | #include <cassert> | ||||
#include <cstddef> | #include <cstddef> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <deque> | #include <deque> | ||||
#include <iterator> | #include <iterator> | ||||
#include <set> | #include <set> | ||||
#include <string> | #include <string> | ||||
#include <vector> | #include <vector> | ||||
using namespace llvm; | 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 { | namespace { | ||||
class RegisterInfoEmitter { | class RegisterInfoEmitter { | ||||
CodeGenTarget Target; | |||||
RecordKeeper &Records; | RecordKeeper &Records; | ||||
public: | 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. | // runEnums - Print out enum values for all of the registers. | ||||
void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); | void runEnums(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); | ||||
// runMCDesc - Print out MC register descriptions. | // runMCDesc - Print out MC register descriptions. | ||||
void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); | void runMCDesc(raw_ostream &o, CodeGenTarget &Target, CodeGenRegBank &Bank); | ||||
// runTargetHeader - Emit a header fragment for the register info emitter. | // runTargetHeader - Emit a header fragment for the register info emitter. | ||||
void runTargetHeader(raw_ostream &o, CodeGenTarget &Target, | void runTargetHeader(raw_ostream &o, CodeGenTarget &Target, | ||||
CodeGenRegBank &Bank); | CodeGenRegBank &Bank); | ||||
// runTargetDesc - Output the target register and register file descriptions. | // runTargetDesc - Output the target register and register file descriptions. | ||||
void runTargetDesc(raw_ostream &o, CodeGenTarget &Target, | void runTargetDesc(raw_ostream &o, CodeGenTarget &Target, | ||||
CodeGenRegBank &Bank); | CodeGenRegBank &Bank); | ||||
// run - Output the register file description. | // run - Output the register file description. | ||||
void run(raw_ostream &o); | void run(raw_ostream &o); | ||||
void debugDump(raw_ostream &OS); | |||||
private: | private: | ||||
void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs, | void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs, | ||||
bool isCtor); | bool isCtor); | ||||
void EmitRegMappingTables(raw_ostream &o, | void EmitRegMappingTables(raw_ostream &o, | ||||
const std::deque<CodeGenRegister> &Regs, | const std::deque<CodeGenRegister> &Regs, | ||||
bool isCtor); | bool isCtor); | ||||
void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, | void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, | ||||
const std::string &ClassName); | const std::string &ClassName); | ||||
▲ Show 20 Lines • Show All 1,436 Lines • ▼ Show 20 Lines | OS << "const " << TargetName << "FrameLowering *\n" << TargetName | ||||
<< " MF.getSubtarget().getFrameLowering());\n" | << " MF.getSubtarget().getFrameLowering());\n" | ||||
<< "}\n\n"; | << "}\n\n"; | ||||
OS << "} // end namespace llvm\n\n"; | OS << "} // end namespace llvm\n\n"; | ||||
OS << "#endif // GET_REGINFO_TARGET_DESC\n\n"; | OS << "#endif // GET_REGINFO_TARGET_DESC\n\n"; | ||||
} | } | ||||
void RegisterInfoEmitter::run(raw_ostream &OS) { | void RegisterInfoEmitter::run(raw_ostream &OS) { | ||||
CodeGenTarget Target(Records); | |||||
CodeGenRegBank &RegBank = Target.getRegBank(); | CodeGenRegBank &RegBank = Target.getRegBank(); | ||||
RegBank.computeDerivedInfo(); | |||||
runEnums(OS, Target, RegBank); | runEnums(OS, Target, RegBank); | ||||
runMCDesc(OS, Target, RegBank); | runMCDesc(OS, Target, RegBank); | ||||
runTargetHeader(OS, Target, RegBank); | runTargetHeader(OS, Target, RegBank); | ||||
runTargetDesc(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 { | namespace llvm { | ||||
void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS) { | void EmitRegisterInfo(RecordKeeper &RK, raw_ostream &OS) { | ||||
RegisterInfoEmitter(RK).run(OS); | RegisterInfoEmitter(RK).run(OS); | ||||
} | } | ||||
} // end namespace llvm | } // end namespace llvm |