aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils/TableGen/RegisterInfoEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/utils/TableGen/RegisterInfoEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/RegisterInfoEmitter.cpp122
1 files changed, 78 insertions, 44 deletions
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index dce7594dec2f..037fad207ac7 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -305,9 +305,8 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
for (unsigned i = 0, e = NumRCUnitSets; i != e; ++i) {
ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
PSets[i].reserve(PSetIDs.size());
- for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
- PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) {
- PSets[i].push_back(RegBank.getRegPressureSet(*PSetI).Order);
+ for (unsigned PSetID : PSetIDs) {
+ PSets[i].push_back(RegBank.getRegPressureSet(PSetID).Order);
}
llvm::sort(PSets[i]);
PSetsSeqs.add(PSets[i]);
@@ -399,11 +398,9 @@ void RegisterInfoEmitter::EmitRegMappingTables(
return;
// Now we know maximal length of number list. Append -1's, where needed
- for (DwarfRegNumsVecTy::iterator I = DwarfRegNums.begin(),
- E = DwarfRegNums.end();
- I != E; ++I)
- for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
- I->second.push_back(-1);
+ for (auto &DwarfRegNum : DwarfRegNums)
+ for (unsigned I = DwarfRegNum.second.size(), E = maxLength; I != E; ++I)
+ DwarfRegNum.second.push_back(-1);
StringRef Namespace = Regs.front().TheDef->getValueAsString("Namespace");
@@ -411,10 +408,10 @@ void RegisterInfoEmitter::EmitRegMappingTables(
// Emit reverse information about the dwarf register numbers.
for (unsigned j = 0; j < 2; ++j) {
- for (unsigned i = 0, e = maxLength; i != e; ++i) {
+ for (unsigned I = 0, E = maxLength; I != E; ++I) {
OS << "extern const MCRegisterInfo::DwarfLLVMRegPair " << Namespace;
OS << (j == 0 ? "DwarfFlavour" : "EHFlavour");
- OS << i << "Dwarf2L[]";
+ OS << I << "Dwarf2L[]";
if (!isCtor) {
OS << " = {\n";
@@ -422,17 +419,15 @@ void RegisterInfoEmitter::EmitRegMappingTables(
// Store the mapping sorted by the LLVM reg num so lookup can be done
// with a binary search.
std::map<uint64_t, Record*> Dwarf2LMap;
- for (DwarfRegNumsVecTy::iterator
- I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
- int DwarfRegNo = I->second[i];
+ for (auto &DwarfRegNum : DwarfRegNums) {
+ int DwarfRegNo = DwarfRegNum.second[I];
if (DwarfRegNo < 0)
continue;
- Dwarf2LMap[DwarfRegNo] = I->first;
+ Dwarf2LMap[DwarfRegNo] = DwarfRegNum.first;
}
- for (std::map<uint64_t, Record*>::iterator
- I = Dwarf2LMap.begin(), E = Dwarf2LMap.end(); I != E; ++I)
- OS << " { " << I->first << "U, " << getQualifiedName(I->second)
+ for (auto &I : Dwarf2LMap)
+ OS << " { " << I.first << "U, " << getQualifiedName(I.second)
<< " },\n";
OS << "};\n";
@@ -443,11 +438,10 @@ void RegisterInfoEmitter::EmitRegMappingTables(
// We have to store the size in a const global, it's used in multiple
// places.
OS << "extern const unsigned " << Namespace
- << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i << "Dwarf2LSize";
+ << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2LSize";
if (!isCtor)
OS << " = array_lengthof(" << Namespace
- << (j == 0 ? "DwarfFlavour" : "EHFlavour") << i
- << "Dwarf2L);\n\n";
+ << (j == 0 ? "DwarfFlavour" : "EHFlavour") << I << "Dwarf2L);\n\n";
else
OS << ";\n\n";
}
@@ -486,13 +480,12 @@ void RegisterInfoEmitter::EmitRegMappingTables(
OS << " = {\n";
// Store the mapping sorted by the Dwarf reg num so lookup can be done
// with a binary search.
- for (DwarfRegNumsVecTy::iterator
- I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) {
- int RegNo = I->second[i];
+ for (auto &DwarfRegNum : DwarfRegNums) {
+ int RegNo = DwarfRegNum.second[i];
if (RegNo == -1) // -1 is the default value, don't emit a mapping.
continue;
- OS << " { " << getQualifiedName(I->first) << ", " << RegNo
+ OS << " { " << getQualifiedName(DwarfRegNum.first) << ", " << RegNo
<< "U },\n";
}
OS << "};\n";
@@ -1029,9 +1022,10 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
ArrayRef<const CodeGenRegister*> Roots = RegBank.getRegUnit(i).getRoots();
assert(!Roots.empty() && "All regunits must have a root register.");
assert(Roots.size() <= 2 && "More than two roots not supported yet.");
- OS << " { " << getQualifiedName(Roots.front()->TheDef);
- for (unsigned r = 1; r != Roots.size(); ++r)
- OS << ", " << getQualifiedName(Roots[r]->TheDef);
+ OS << " { ";
+ ListSeparator LS;
+ for (const CodeGenRegister *R : Roots)
+ OS << LS << getQualifiedName(R->TheDef);
OS << " },\n";
}
OS << "};\n\n";
@@ -1083,12 +1077,15 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
for (const auto &RC : RegisterClasses) {
assert(isInt<8>(RC.CopyCost) && "Copy cost too large.");
+ uint32_t RegSize = 0;
+ if (RC.RSI.isSimple())
+ RegSize = RC.RSI.getSimple().RegSize;
OS << " { " << RC.getName() << ", " << RC.getName() << "Bits, "
- << RegClassStrings.get(RC.getName()) << ", "
- << RC.getOrder().size() << ", sizeof(" << RC.getName() << "Bits), "
- << RC.getQualifiedName() + "RegClassID" << ", "
- << RC.CopyCost << ", "
- << ( RC.Allocatable ? "true" : "false" ) << " },\n";
+ << RegClassStrings.get(RC.getName()) << ", " << RC.getOrder().size()
+ << ", sizeof(" << RC.getName() << "Bits), "
+ << RC.getQualifiedName() + "RegClassID"
+ << ", " << RegSize << ", " << RC.CopyCost << ", "
+ << (RC.Allocatable ? "true" : "false") << " },\n";
}
OS << "};\n\n";
@@ -1441,19 +1438,52 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
// Emit extra information about registers.
const std::string &TargetName = std::string(Target.getName());
- OS << "\nstatic const TargetRegisterInfoDesc "
- << TargetName << "RegInfoDesc[] = { // Extra Descriptors\n";
- OS << " { 0, false },\n";
-
const auto &Regs = RegBank.getRegisters();
+ unsigned NumRegCosts = 1;
+ for (const auto &Reg : Regs)
+ NumRegCosts = std::max((size_t)NumRegCosts, Reg.CostPerUse.size());
+
+ std::vector<unsigned> AllRegCostPerUse;
+ llvm::BitVector InAllocClass(Regs.size() + 1, false);
+ AllRegCostPerUse.insert(AllRegCostPerUse.end(), NumRegCosts, 0);
+
+ // Populate the vector RegCosts with the CostPerUse list of the registers
+ // in the order they are read. Have at most NumRegCosts entries for
+ // each register. Fill with zero for values which are not explicitly given.
for (const auto &Reg : Regs) {
- OS << " { ";
- OS << Reg.CostPerUse << ", "
- << ( AllocatableRegs.count(Reg.TheDef) != 0 ? "true" : "false" )
- << " },\n";
+ auto Costs = Reg.CostPerUse;
+ AllRegCostPerUse.insert(AllRegCostPerUse.end(), Costs.begin(), Costs.end());
+ if (NumRegCosts > Costs.size())
+ AllRegCostPerUse.insert(AllRegCostPerUse.end(),
+ NumRegCosts - Costs.size(), 0);
+
+ if (AllocatableRegs.count(Reg.TheDef))
+ InAllocClass.set(Reg.EnumValue);
}
- OS << "};\n"; // End of register descriptors...
+ // Emit the cost values as a 1D-array after grouping them by their indices,
+ // i.e. the costs for all registers corresponds to index 0, 1, 2, etc.
+ // Size of the emitted array should be NumRegCosts * (Regs.size() + 1).
+ OS << "\nstatic const uint8_t "
+ << "CostPerUseTable[] = { \n";
+ for (unsigned int I = 0; I < NumRegCosts; ++I) {
+ for (unsigned J = I, E = AllRegCostPerUse.size(); J < E; J += NumRegCosts)
+ OS << AllRegCostPerUse[J] << ", ";
+ }
+ OS << "};\n\n";
+
+ OS << "\nstatic const bool "
+ << "InAllocatableClassTable[] = { \n";
+ for (unsigned I = 0, E = InAllocClass.size(); I < E; ++I) {
+ OS << (InAllocClass[I] ? "true" : "false") << ", ";
+ }
+ OS << "};\n\n";
+
+ OS << "\nstatic const TargetRegisterInfoDesc " << TargetName
+ << "RegInfoDesc = { // Extra Descriptors\n";
+ OS << "CostPerUseTable, " << NumRegCosts << ", "
+ << "InAllocatableClassTable";
+ OS << "};\n\n"; // End of register descriptors...
std::string ClassName = Target.getName().str() + "GenRegisterInfo";
@@ -1513,10 +1543,11 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
EmitRegMappingTables(OS, Regs, true);
- OS << ClassName << "::\n" << ClassName
+ OS << ClassName << "::\n"
+ << ClassName
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour,\n"
" unsigned PC, unsigned HwMode)\n"
- << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
+ << " : TargetRegisterInfo(&" << TargetName << "RegInfoDesc"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() << ",\n"
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable,\n"
<< " ";
@@ -1679,7 +1710,10 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) {
for (const CodeGenRegister &R : RegBank.getRegisters()) {
OS << "Register " << R.getName() << ":\n";
- OS << "\tCostPerUse: " << R.CostPerUse << '\n';
+ OS << "\tCostPerUse: ";
+ for (const auto &Cost : R.CostPerUse)
+ OS << Cost << " ";
+ OS << '\n';
OS << "\tCoveredBySubregs: " << R.CoveredBySubRegs << '\n';
OS << "\tHasDisjunctSubRegs: " << R.HasDisjunctSubRegs << '\n';
for (std::pair<CodeGenSubRegIndex*,CodeGenRegister*> P : R.getSubRegs()) {