Move register class name strings to a single array in MCRegisterInfo to reduce static table size and number of relocation entries.

Indices into the table are stored in each MCRegisterClass instead of a pointer. A new method, getRegClassName, is added to MCRegisterInfo and TargetRegisterInfo to lookup the string in the table.

llvm-svn: 222118
This commit is contained in:
Craig Topper 2014-11-17 05:50:14 +00:00
parent a3b5b60753
commit cf0444ba2a
17 changed files with 63 additions and 44 deletions

View File

@ -32,9 +32,9 @@ public:
typedef const MCPhysReg* iterator;
typedef const MCPhysReg* const_iterator;
const char *Name;
const iterator RegsBegin;
const uint8_t *const RegSet;
const uint32_t NameIdx;
const uint16_t RegsSize;
const uint16_t RegSetSize;
const uint16_t ID;
@ -46,10 +46,6 @@ public:
///
unsigned getID() const { return ID; }
/// getName() - Return the register class name for debugging.
///
const char *getName() const { return Name; }
/// begin/end - Return all of the registers in this class.
///
iterator begin() const { return RegsBegin; }
@ -162,6 +158,7 @@ private:
const MCPhysReg (*RegUnitRoots)[2]; // Pointer to regunit root table.
const MCPhysReg *DiffLists; // Pointer to the difflists array
const char *RegStrings; // Pointer to the string table.
const char *RegClassStrings; // Pointer to the class strings.
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
// array.
const SubRegCoveredBits *SubRegIdxRanges; // Pointer to the subreg covered
@ -243,6 +240,7 @@ public:
unsigned NRU,
const MCPhysReg *DL,
const char *Strings,
const char *ClassStrings,
const uint16_t *SubIndices,
unsigned NumIndices,
const SubRegCoveredBits *SubIdxRanges,
@ -254,6 +252,7 @@ public:
Classes = C;
DiffLists = DL;
RegStrings = Strings;
RegClassStrings = ClassStrings;
NumClasses = NC;
RegUnitRoots = RURoots;
NumRegUnits = NRU;
@ -401,6 +400,10 @@ public:
return Classes[i];
}
const char *getRegClassName(const MCRegisterClass *Class) const {
return RegClassStrings + Class->NameIdx;
}
/// \brief Returns the encoding for RegNo
uint16_t getEncodingValue(unsigned RegNo) const {
assert(RegNo < NumRegs &&

View File

@ -52,10 +52,6 @@ public:
///
unsigned getID() const { return MC->getID(); }
/// getName() - Return the register class name for debugging.
///
const char *getName() const { return MC->getName(); }
/// begin/end - Return all of the registers in this class.
///
iterator begin() const { return MC->begin(); }
@ -561,6 +557,11 @@ public:
return RegClassBegin[i];
}
/// getRegClassName - Returns the name of the register class.
const char *getRegClassName(const TargetRegisterClass *Class) const {
return MCRegisterInfo::getRegClassName(Class->MC);
}
/// getCommonSubClass - find the largest common subclass of A and B. Return
/// NULL if there is no common subclass.
const TargetRegisterClass *

View File

@ -518,7 +518,7 @@ BitVector AggressiveAntiDepBreaker::GetRenameRegisters(unsigned Reg) {
BV &= RCBV;
}
DEBUG(dbgs() << " " << RC->getName());
DEBUG(dbgs() << " " << TRI->getRegClassName(RC));
}
return BV;

View File

@ -720,7 +720,7 @@ bool ExeDepsFix::runOnMachineFunction(MachineFunction &mf) {
assert(NumRegs == RC->getNumRegs() && "Bad regclass");
DEBUG(dbgs() << "********** FIX EXECUTION DEPENDENCIES: "
<< RC->getName() << " **********\n");
<< TRI->getRegClassName(RC) << " **********\n");
// If no relevant registers are used in the function, we can skip it
// completely.

View File

@ -1377,7 +1377,7 @@ void InlineSpiller::spill(LiveRangeEdit &edit) {
StackInt = nullptr;
DEBUG(dbgs() << "Inline spilling "
<< MRI.getRegClass(edit.getReg())->getName()
<< TRI.getRegClassName(MRI.getRegClass(edit.getReg()))
<< ':' << edit.getParent()
<< "\nFrom original " << PrintReg(Original) << '\n');
assert(edit.getParent().isSpillable() &&

View File

@ -411,8 +411,11 @@ LiveRangeEdit::calculateRegClassAndHint(MachineFunction &MF,
for (unsigned I = 0, Size = size(); I < Size; ++I) {
LiveInterval &LI = LIS.getInterval(get(I));
if (MRI.recomputeRegClass(LI.reg, MF.getTarget()))
DEBUG(dbgs() << "Inflated " << PrintReg(LI.reg) << " to "
<< MRI.getRegClass(LI.reg)->getName() << '\n');
DEBUG({
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
dbgs() << "Inflated " << PrintReg(LI.reg) << " to "
<< TRI->getRegClassName(MRI.getRegClass(LI.reg)) << '\n'
});
VRAI.calculateSpillWeightAndHint(LI);
}
}

View File

@ -81,7 +81,7 @@ void LiveStacks::print(raw_ostream &OS, const Module*) const {
int Slot = I->first;
const TargetRegisterClass *RC = getIntervalRegClass(Slot);
if (RC)
OS << " [" << RC->getName() << "]\n";
OS << " [" << TRI->getRegClassName(RC) << "]\n";
else
OS << " [Unknown]\n";
}

View File

@ -1607,18 +1607,17 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
// call instructions much less noisy on targets where calls clobber lots
// of registers. Don't rely on MO.isDead() because we may be called before
// LiveVariables is run, or we may be looking at a non-allocatable reg.
if (MF && isCall() &&
if (MRI && isCall() &&
MO.isReg() && MO.isImplicit() && MO.isDef()) {
unsigned Reg = MO.getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
const MachineRegisterInfo &MRI = MF->getRegInfo();
if (MRI.use_empty(Reg)) {
if (MRI->use_empty(Reg)) {
bool HasAliasLive = false;
for (MCRegAliasIterator AI(
Reg, TM->getSubtargetImpl()->getRegisterInfo(), true);
AI.isValid(); ++AI) {
unsigned AliasReg = *AI;
if (!MRI.use_empty(AliasReg)) {
if (!MRI->use_empty(AliasReg)) {
HasAliasLive = true;
break;
}
@ -1669,13 +1668,12 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
unsigned RCID = 0;
if (InlineAsm::hasRegClassConstraint(Flag, RCID)) {
if (TM)
if (TM) {
const TargetRegisterInfo *TRI =
TM->getSubtargetImpl()->getRegisterInfo();
OS << ':'
<< TM->getSubtargetImpl()
->getRegisterInfo()
->getRegClass(RCID)
->getName();
else
<< TRI->getRegClassName(TRI->getRegClass(RCID));
} else
OS << ":RC" << RCID;
}
@ -1724,7 +1722,8 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM,
if (!HaveSemi) OS << ";"; HaveSemi = true;
for (unsigned i = 0; i != VirtRegs.size(); ++i) {
const TargetRegisterClass *RC = MRI->getRegClass(VirtRegs[i]);
OS << " " << RC->getName() << ':' << PrintReg(VirtRegs[i]);
OS << " " << MRI->getTargetRegisterInfo()->getRegClassName(RC)
<< ':' << PrintReg(VirtRegs[i]);
for (unsigned j = i+1; j != VirtRegs.size();) {
if (MRI->getRegClass(VirtRegs[j]) != RC) {
++j;

View File

@ -907,7 +907,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
if (!DRC->contains(Reg)) {
report("Illegal physical register for instruction", MO, MONum);
*OS << TRI->getName(Reg) << " is not a "
<< DRC->getName() << " register.\n";
<< TRI->getRegClassName(DRC) << " register.\n";
}
}
} else {
@ -918,13 +918,13 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
TRI->getSubClassWithSubReg(RC, SubIdx);
if (!SRC) {
report("Invalid subregister index for virtual register", MO, MONum);
*OS << "Register class " << RC->getName()
*OS << "Register class " << TRI->getRegClassName(RC)
<< " does not support subreg index " << SubIdx << "\n";
return;
}
if (RC != SRC) {
report("Invalid register class for subregister index", MO, MONum);
*OS << "Register class " << RC->getName()
*OS << "Register class " << TRI->getRegClassName(RC)
<< " does not fully support subreg index " << SubIdx << "\n";
return;
}
@ -946,8 +946,9 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
}
if (!RC->hasSuperClassEq(DRC)) {
report("Illegal virtual register for instruction", MO, MONum);
*OS << "Expected a " << DRC->getName() << " register, but got a "
<< RC->getName() << " register\n";
*OS << "Expected a " << TRI->getRegClassName(DRC)
<< " register, but got a " << TRI->getRegClassName(RC)
<< " register\n";
}
}
}

View File

@ -101,7 +101,7 @@ void RegAllocBase::allocatePhysRegs() {
// register if possible and populate a list of new live intervals that
// result from splitting.
DEBUG(dbgs() << "\nselectOrSplit "
<< MRI->getRegClass(VirtReg->reg)->getName()
<< TRI->getRegClassName(MRI->getRegClass(VirtReg->reg))
<< ':' << *VirtReg << " w=" << VirtReg->weight << '\n');
typedef SmallVector<unsigned, 4> VirtRegVec;
VirtRegVec SplitVRegs;

View File

@ -548,7 +548,7 @@ RAFast::LiveRegMap::iterator RAFast::allocVirtReg(MachineInstr *MI,
}
DEBUG(dbgs() << "Allocating " << PrintReg(VirtReg) << " from "
<< RC->getName() << "\n");
<< TRI->getRegClassName(RC) << "\n");
unsigned BestReg = 0, BestCost = spillImpossible;
for (ArrayRef<MCPhysReg>::iterator I = AO.begin(), E = AO.end(); I != E; ++I){

View File

@ -817,7 +817,7 @@ unsigned RAGreedy::tryEvict(LiveInterval &VirtReg,
const TargetRegisterClass *RC = MRI->getRegClass(VirtReg.reg);
unsigned MinCost = RegClassInfo.getMinCost(RC);
if (MinCost >= CostPerUseLimit) {
DEBUG(dbgs() << RC->getName() << " minimum cost = " << MinCost
DEBUG(dbgs() << TRI->getRegClassName(RC) << " minimum cost = " << MinCost
<< ", no cheaper registers to be found.\n");
return 0;
}

View File

@ -137,7 +137,7 @@ void RegisterClassInfo::compute(const TargetRegisterClass *RC) const {
RCI.LastCostChange = LastCostChange;
DEBUG({
dbgs() << "AllocationOrder(" << RC->getName() << ") = [";
dbgs() << "AllocationOrder(" << TRI->getRegClassName(RC) << ") = [";
for (unsigned I = 0; I != RCI.NumRegs; ++I)
dbgs() << ' ' << PrintReg(RCI.Order[I], TRI);
dbgs() << (RCI.ProperSubClass ? " ] (sub-class)\n" : " ]\n");

View File

@ -1106,8 +1106,8 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
}
} else {
DEBUG({
dbgs() << "\tConsidering merging to " << CP.getNewRC()->getName()
<< " with ";
dbgs() << "\tConsidering merging to "
<< TRI->getRegClassName(CP.getNewRC()) << " with ";
if (CP.getDstIdx() && CP.getSrcIdx())
dbgs() << PrintReg(CP.getDstReg()) << " in "
<< TRI->getSubRegIndexName(CP.getDstIdx()) << " and "
@ -2264,7 +2264,7 @@ bool RegisterCoalescer::runOnMachineFunction(MachineFunction &fn) {
continue;
if (MRI->recomputeRegClass(Reg, *TM)) {
DEBUG(dbgs() << PrintReg(Reg) << " inflated to "
<< MRI->getRegClass(Reg)->getName() << '\n');
<< TRI->getRegClassName(MRI->getRegClass(Reg)) << '\n');
++NumInflated;
}
}

View File

@ -1935,8 +1935,8 @@ void RegReductionPQBase::dumpRegPressure() const {
unsigned Id = RC->getID();
unsigned RP = RegPressure[Id];
if (!RP) continue;
DEBUG(dbgs() << RC->getName() << ": " << RP << " / " << RegLimit[Id]
<< '\n');
DEBUG(dbgs() << TRI->getRegClassName(RC) << ": " << RP << " / "
<< RegLimit[Id] << '\n');
}
#endif
}

View File

@ -124,7 +124,7 @@ void VirtRegMap::print(raw_ostream &OS, const Module*) const {
if (Virt2PhysMap[Reg] != (unsigned)VirtRegMap::NO_PHYS_REG) {
OS << '[' << PrintReg(Reg, TRI) << " -> "
<< PrintReg(Virt2PhysMap[Reg], TRI) << "] "
<< MRI->getRegClass(Reg)->getName() << "\n";
<< TRI->getRegClassName(MRI->getRegClass(Reg)) << "\n";
}
}
@ -132,7 +132,7 @@ void VirtRegMap::print(raw_ostream &OS, const Module*) const {
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
if (Virt2StackSlotMap[Reg] != VirtRegMap::NO_STACK_SLOT) {
OS << '[' << PrintReg(Reg, TRI) << " -> fi#" << Virt2StackSlotMap[Reg]
<< "] " << MRI->getRegClass(Reg)->getName() << "\n";
<< "] " << TRI->getRegClassName(MRI->getRegClass(Reg)) << "\n";
}
}
OS << '\n';

View File

@ -848,6 +848,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
// Loop over all of the register classes... emitting each one.
OS << "namespace { // Register classes...\n";
SequenceToOffsetTable<std::string> RegClassStrings;
// Emit the register enum value arrays for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = *RegisterClasses[rc];
@ -856,6 +858,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
// Give the register class a legal C name if it's anonymous.
std::string Name = RC.getName();
RegClassStrings.add(Name);
// Emit the register list now.
OS << " // " << Name << " Register Class...\n"
<< " const MCPhysReg " << Name
@ -880,6 +884,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
}
OS << "}\n\n";
RegClassStrings.layout();
OS << "extern const char " << TargetName << "RegClassStrings[] = {\n";
RegClassStrings.emit(OS, printChar);
OS << "};\n\n";
OS << "extern const MCRegisterClass " << TargetName
<< "MCRegisterClasses[] = {\n";
@ -892,8 +901,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
assert((RC.SpillAlignment/8) <= 0xffff && "SpillAlignment too large.");
assert(RC.CopyCost >= -128 && RC.CopyCost <= 127 && "Copy cost too large.");
OS << " { " << '\"' << RC.getName() << "\", "
<< RC.getName() << ", " << RC.getName() << "Bits, "
OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
<< RegClassStrings.get(RC.getName()) << ", "
<< RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
<< RC.getQualifiedName() + "RegClassID" << ", "
<< RC.SpillSize/8 << ", "
@ -934,6 +943,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
<< RegBank.getNumNativeRegUnits() << ", "
<< TargetName << "RegDiffLists, "
<< TargetName << "RegStrings, "
<< TargetName << "RegClassStrings, "
<< TargetName << "SubRegIdxLists, "
<< (SubRegIndices.size() + 1) << ",\n"
<< TargetName << "SubRegIdxRanges, "
@ -1267,6 +1277,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
OS << "extern const char " << TargetName << "RegStrings[];\n";
OS << "extern const char " << TargetName << "RegClassStrings[];\n";
OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
OS << "extern const MCRegisterInfo::SubRegCoveredBits "
@ -1289,6 +1300,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
<< " " << TargetName << "RegDiffLists,\n"
<< " " << TargetName << "RegStrings,\n"
<< " " << TargetName << "RegClassStrings,\n"
<< " " << TargetName << "SubRegIdxLists,\n"
<< " " << SubRegIndices.size() + 1 << ",\n"
<< " " << TargetName << "SubRegIdxRanges,\n"