mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-19 01:27:40 +00:00
Eliminate the large XXXSubRegTable constant arrays.
These tables were indexed by [register][subreg index] which made them, very large and sparse. Replace them with lists of sub-register indexes that match the existing lists of sub-registers. MCRI::getSubReg() becomes a very short linear search, like getSubRegIndex() already was. llvm-svn: 160843
This commit is contained in:
parent
7031003c8d
commit
49c17daace
@ -111,6 +111,10 @@ struct MCRegisterDesc {
|
||||
uint32_t SubRegs; // Sub-register set, described above
|
||||
uint32_t SuperRegs; // Super-register set, described above
|
||||
|
||||
// Offset into MCRI::SubRegIndices of a list of sub-register indices for each
|
||||
// sub-register in SubRegs.
|
||||
uint32_t SubRegIndices;
|
||||
|
||||
// RegUnits - Points to the list of register units. The low 4 bits holds the
|
||||
// Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator.
|
||||
uint32_t RegUnits;
|
||||
@ -305,9 +309,7 @@ public:
|
||||
/// getSubReg - Returns the physical register number of sub-register "Index"
|
||||
/// for physical register RegNo. Return zero if the sub-register does not
|
||||
/// exist.
|
||||
unsigned getSubReg(unsigned Reg, unsigned Idx) const {
|
||||
return *(SubRegIndices + (Reg - 1) * NumSubRegIndices + Idx - 1);
|
||||
}
|
||||
unsigned getSubReg(unsigned Reg, unsigned Idx) const;
|
||||
|
||||
/// getMatchingSuperReg - Return a super-register of the specified register
|
||||
/// Reg so its sub-register of index SubIdx is Reg.
|
||||
@ -317,12 +319,7 @@ public:
|
||||
/// getSubRegIndex - For a given register pair, return the sub-register index
|
||||
/// if the second register is a sub-register of the first. Return zero
|
||||
/// otherwise.
|
||||
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {
|
||||
for (unsigned I = 1; I <= NumSubRegIndices; ++I)
|
||||
if (getSubReg(RegNo, I) == SubRegNo)
|
||||
return I;
|
||||
return 0;
|
||||
}
|
||||
unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;
|
||||
|
||||
/// getName - Return the human-readable symbolic target-specific name for the
|
||||
/// specified physical register.
|
||||
@ -443,11 +440,33 @@ inline
|
||||
unsigned MCRegisterInfo::getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
|
||||
const MCRegisterClass *RC) const {
|
||||
for (MCSuperRegIterator Supers(Reg, this); Supers.isValid(); ++Supers)
|
||||
if (Reg == getSubReg(*Supers, SubIdx) && RC->contains(*Supers))
|
||||
if (RC->contains(*Supers) && Reg == getSubReg(*Supers, SubIdx))
|
||||
return *Supers;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned MCRegisterInfo::getSubReg(unsigned Reg, unsigned Idx) const {
|
||||
// Get a pointer to the corresponding SubRegIndices list. This list has the
|
||||
// name of each sub-register in the same order as MCSubRegIterator.
|
||||
const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
|
||||
for (MCSubRegIterator Subs(Reg, this); Subs.isValid(); ++Subs, ++SRI)
|
||||
if (*SRI == Idx)
|
||||
return *Subs;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const {
|
||||
// Get a pointer to the corresponding SubRegIndices list. This list has the
|
||||
// name of each sub-register in the same order as MCSubRegIterator.
|
||||
const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices;
|
||||
for (MCSubRegIterator Subs(Reg, this); Subs.isValid(); ++Subs, ++SRI)
|
||||
if (*Subs == SubReg)
|
||||
return *SRI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Register Units
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -484,7 +484,7 @@ static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) {
|
||||
}
|
||||
|
||||
static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) {
|
||||
OS << Idx->getQualifiedName();
|
||||
OS << Idx->EnumValue;
|
||||
}
|
||||
|
||||
// Differentially encoded register and regunit lists allow for better
|
||||
@ -555,6 +555,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
|
||||
SmallVector<unsigned, 4> RegUnitInitScale(Regs.size());
|
||||
|
||||
// Keep track of sub-register names as well. These are not differentially
|
||||
// encoded.
|
||||
typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
|
||||
SequenceToOffsetTable<SubRegIdxVec> SubRegIdxSeqs;
|
||||
SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
|
||||
|
||||
SequenceToOffsetTable<std::string> RegStrings;
|
||||
|
||||
// Precompute register lists for the SequenceToOffsetTable.
|
||||
@ -569,6 +575,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
diffEncode(SubRegLists[i], Reg->EnumValue, SR.begin(), SR.end());
|
||||
DiffSeqs.add(SubRegLists[i]);
|
||||
|
||||
// Compute the corresponding sub-register indexes.
|
||||
SubRegIdxVec &SRIs = SubRegIdxLists[i];
|
||||
for (unsigned j = 0, je = SR.size(); j != je; ++j)
|
||||
SRIs.push_back(Reg->getSubRegIndex(SR[j]));
|
||||
SubRegIdxSeqs.add(SRIs);
|
||||
|
||||
// Super-registers are already computed.
|
||||
const RegVec &SuperRegList = Reg->getSuperRegs();
|
||||
diffEncode(SuperRegLists[i], Reg->EnumValue,
|
||||
@ -612,6 +624,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
// Compute the final layout of the sequence table.
|
||||
DiffSeqs.layout();
|
||||
SubRegIdxSeqs.layout();
|
||||
|
||||
OS << "namespace llvm {\n\n";
|
||||
|
||||
@ -622,6 +635,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
DiffSeqs.emit(OS, printDiff16);
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the table of sub-register indexes.
|
||||
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
|
||||
SubRegIdxSeqs.emit(OS, printSubRegIndex);
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the string table.
|
||||
RegStrings.layout();
|
||||
OS << "extern const char " << TargetName << "RegStrings[] = {\n";
|
||||
@ -630,7 +648,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
OS << "extern const MCRegisterDesc " << TargetName
|
||||
<< "RegDesc[] = { // Descriptors\n";
|
||||
OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0 },\n";
|
||||
OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n";
|
||||
|
||||
// Emit the register descriptors now.
|
||||
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
||||
@ -639,6 +657,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< DiffSeqs.get(OverlapLists[i]) << ", "
|
||||
<< DiffSeqs.get(SubRegLists[i]) << ", "
|
||||
<< DiffSeqs.get(SuperRegLists[i]) << ", "
|
||||
<< SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
|
||||
<< (DiffSeqs.get(RegUnitLists[i])*16 + RegUnitInitScale[i]) << " },\n";
|
||||
}
|
||||
OS << "};\n\n"; // End of register descriptors...
|
||||
@ -718,37 +737,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
OS << "};\n\n";
|
||||
|
||||
// Emit the data table for getSubReg().
|
||||
ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
|
||||
if (SubRegIndices.size()) {
|
||||
OS << "const uint16_t " << TargetName << "SubRegTable[]["
|
||||
<< SubRegIndices.size() << "] = {\n";
|
||||
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
|
||||
const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs();
|
||||
OS << " /* " << Regs[i]->TheDef->getName() << " */\n";
|
||||
if (SRM.empty()) {
|
||||
OS << " {0},\n";
|
||||
continue;
|
||||
}
|
||||
OS << " {";
|
||||
for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) {
|
||||
// FIXME: We really should keep this to 80 columns...
|
||||
CodeGenRegister::SubRegMap::const_iterator SubReg =
|
||||
SRM.find(SubRegIndices[j]);
|
||||
if (SubReg != SRM.end())
|
||||
OS << getQualifiedName(SubReg->second->TheDef);
|
||||
else
|
||||
OS << "0";
|
||||
if (j != je - 1)
|
||||
OS << ", ";
|
||||
}
|
||||
OS << "}" << (i != e ? "," : "") << "\n";
|
||||
}
|
||||
OS << "};\n\n";
|
||||
OS << "const uint16_t *get" << TargetName
|
||||
<< "SubRegTable() {\n return (const uint16_t *)" << TargetName
|
||||
<< "SubRegTable;\n}\n\n";
|
||||
}
|
||||
|
||||
EmitRegMappingTables(OS, Regs, false);
|
||||
|
||||
@ -772,21 +761,17 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
// MCRegisterInfo initialization routine.
|
||||
OS << "static inline void Init" << TargetName
|
||||
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
|
||||
<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n";
|
||||
OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
||||
<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"
|
||||
<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
||||
<< Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
|
||||
<< RegisterClasses.size() << ", "
|
||||
<< TargetName << "RegUnitRoots, "
|
||||
<< RegBank.getNumNativeRegUnits() << ", "
|
||||
<< TargetName << "RegDiffLists, "
|
||||
<< TargetName << "RegStrings, ";
|
||||
if (SubRegIndices.size() != 0)
|
||||
OS << "(uint16_t*)" << TargetName << "SubRegTable, "
|
||||
<< SubRegIndices.size() << ",\n";
|
||||
else
|
||||
OS << "NULL, 0,\n";
|
||||
|
||||
OS << " " << TargetName << "RegEncodingTable);\n\n";
|
||||
<< TargetName << "RegStrings, "
|
||||
<< TargetName << "SubRegIdxLists, "
|
||||
<< SubRegIndices.size() << ",\n"
|
||||
<< " " << TargetName << "RegEncodingTable);\n\n";
|
||||
|
||||
EmitRegMapping(OS, Regs, false);
|
||||
|
||||
@ -1139,9 +1124,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n";
|
||||
OS << "extern const char " << TargetName << "RegStrings[];\n";
|
||||
OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n";
|
||||
if (SubRegIndices.size() != 0)
|
||||
OS << "extern const uint16_t *get" << TargetName
|
||||
<< "SubRegTable();\n";
|
||||
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
|
||||
OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
|
||||
|
||||
EmitRegMappingTables(OS, Regs, true);
|
||||
@ -1158,14 +1141,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
|
||||
<< " " << TargetName << "RegDiffLists,\n"
|
||||
<< " " << TargetName << "RegStrings,\n"
|
||||
<< " ";
|
||||
if (SubRegIndices.size() != 0)
|
||||
OS << "get" << TargetName << "SubRegTable(), "
|
||||
<< SubRegIndices.size() << ",\n";
|
||||
else
|
||||
OS << "NULL, 0,\n";
|
||||
|
||||
OS << " " << TargetName << "RegEncodingTable);\n\n";
|
||||
<< " " << TargetName << "SubRegIdxLists,\n"
|
||||
<< " " << SubRegIndices.size() << ",\n"
|
||||
<< " " << TargetName << "RegEncodingTable);\n\n";
|
||||
|
||||
EmitRegMapping(OS, Regs, true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user