void EmitRegMappingTables(raw_ostream &o,
const std::vector<CodeGenRegister*> &Regs,
bool isCtor);
- void EmitRegClasses(raw_ostream &OS, CodeGenTarget &Target);
-
void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
const std::string &ClassName);
+ void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
+ const std::string &ClassName);
};
} // End anonymous namespace
<< " return RCWeightTable[RC->getID()];\n"
<< "}\n\n";
+ // Reasonable targets (not ARMv7) have unit weight for all units, so don't
+ // bother generating a table.
+ bool RegUnitsHaveUnitWeight = true;
+ for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ if (RegBank.getRegUnit(UnitIdx).Weight > 1)
+ RegUnitsHaveUnitWeight = false;
+ }
+ OS << "/// Get the weight in units of pressure for this register unit.\n"
+ << "unsigned " << ClassName << "::\n"
+ << "getRegUnitWeight(unsigned RegUnit) const {\n"
+ << " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
+ << " && \"invalid register unit\");\n";
+ if (!RegUnitsHaveUnitWeight) {
+ OS << " static const uint8_t RUWeightTable[] = {\n ";
+ for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ const RegUnit &RU = RegBank.getRegUnit(UnitIdx);
+ assert(RU.Weight < 256 && "RegUnit too heavy");
+ OS << RU.Weight << ", ";
+ }
+ OS << "0 };\n"
+ << " return RUWeightTable[RegUnit];\n";
+ }
+ else {
+ OS << " // All register units have unit weight.\n"
+ << " return 1;\n";
+ }
+ OS << "}\n\n";
+
OS << "\n"
<< "// Get the number of dimensions of register pressure.\n"
<< "unsigned " << ClassName << "::getNumRegPressureSets() const {\n"
<< " return PressureLimitTable[Idx];\n"
<< "}\n\n";
- OS << "/// Get the dimensions of register pressure "
- << "impacted by this register class.\n"
- << "/// Returns a -1 terminated array of pressure set IDs\n"
- << "const int* " << ClassName << "::\n"
- << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n"
- << " static const int RCSetsTable[] = {\n ";
- std::vector<unsigned> RCSetStarts(NumRCs);
- for (unsigned i = 0, StartIdx = 0, e = NumRCs; i != e; ++i) {
+ // This table may be larger than NumRCs if some register units needed a list
+ // of unit sets that did not correspond to a register class.
+ unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists();
+ OS << "/// Table of pressure sets per register class or unit.\n"
+ << "static const int RCSetsTable[] = {\n ";
+ std::vector<unsigned> RCSetStarts(NumRCUnitSets);
+ for (unsigned i = 0, StartIdx = 0, e = NumRCUnitSets; i != e; ++i) {
RCSetStarts[i] = StartIdx;
ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i);
for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
OS << *PSetI << ", ";
++StartIdx;
}
- OS << "-1, \t// " << RegBank.getRegClasses()[i]->getName() << "\n ";
+ OS << "-1, \t// #" << RCSetStarts[i] << " ";
+ if (i < NumRCs)
+ OS << RegBank.getRegClasses()[i]->getName();
+ else {
+ OS << "inferred";
+ for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(),
+ PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) {
+ OS << "~" << RegBank.getRegPressureSet(*PSetI).Name;
+ }
+ }
+ OS << "\n ";
++StartIdx;
}
- OS << "-1 };\n";
+ OS << "-1 };\n\n";
+
+ OS << "/// Get the dimensions of register pressure impacted by this "
+ << "register class.\n"
+ << "/// Returns a -1 terminated array of pressure set IDs\n"
+ << "const int* " << ClassName << "::\n"
+ << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n";
OS << " static const unsigned RCSetStartTable[] = {\n ";
for (unsigned i = 0, e = NumRCs; i != e; ++i) {
OS << RCSetStarts[i] << ",";
<< " unsigned SetListStart = RCSetStartTable[RC->getID()];\n"
<< " return &RCSetsTable[SetListStart];\n"
<< "}\n\n";
+
+ OS << "/// Get the dimensions of register pressure impacted by this "
+ << "register unit.\n"
+ << "/// Returns a -1 terminated array of pressure set IDs\n"
+ << "const int* " << ClassName << "::\n"
+ << "getRegUnitPressureSets(unsigned RegUnit) const {\n"
+ << " assert(RegUnit < " << RegBank.getNumNativeRegUnits()
+ << " && \"invalid register unit\");\n";
+ OS << " static const unsigned RUSetStartTable[] = {\n ";
+ for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits();
+ UnitIdx < UnitEnd; ++UnitIdx) {
+ OS << RCSetStarts[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx] << ",";
+ }
+ OS << "0 };\n"
+ << " unsigned SetListStart = RUSetStartTable[RegUnit];\n"
+ << " return &RCSetsTable[SetListStart];\n"
+ << "}\n\n";
}
void
const std::vector<CodeGenRegister*> &Regs,
bool isCtor) {
// Collect all information about dwarf register numbers
- typedef std::map<Record*, std::vector<int64_t>, LessRecord> DwarfRegNumsMapTy;
+ typedef std::map<Record*, std::vector<int64_t>, LessRecordRegister> DwarfRegNumsMapTy;
DwarfRegNumsMapTy DwarfRegNums;
// First, just pull all provided information to the map
if (!V || !V->getValue())
continue;
- DefInit *DI = dynamic_cast<DefInit*>(V->getValue());
+ DefInit *DI = cast<DefInit>(V->getValue());
Record *Alias = DI->getDef();
DwarfRegNums[Reg] = DwarfRegNums[Alias];
}
OS << Val;
}
+// Try to combine Idx's compose map into Vec if it is compatible.
+// Return false if it's not possible.
+static bool combine(const CodeGenSubRegIndex *Idx,
+ SmallVectorImpl<CodeGenSubRegIndex*> &Vec) {
+ const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
+ for (CodeGenSubRegIndex::CompMap::const_iterator
+ I = Map.begin(), E = Map.end(); I != E; ++I) {
+ CodeGenSubRegIndex *&Entry = Vec[I->first->EnumValue - 1];
+ if (Entry && Entry != I->second)
+ return false;
+ }
+
+ // All entries are compatible. Make it so.
+ for (CodeGenSubRegIndex::CompMap::const_iterator
+ I = Map.begin(), E = Map.end(); I != E; ++I)
+ Vec[I->first->EnumValue - 1] = I->second;
+ return true;
+}
+
+static const char *getMinimalTypeForRange(uint64_t Range) {
+ assert(Range < 0xFFFFFFFFULL && "Enum too large");
+ if (Range > 0xFFFF)
+ return "uint32_t";
+ if (Range > 0xFF)
+ return "uint16_t";
+ return "uint8_t";
+}
+
+void
+RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
+ CodeGenRegBank &RegBank,
+ const std::string &ClName) {
+ ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
+ OS << "unsigned " << ClName
+ << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
+
+ // Many sub-register indexes are composition-compatible, meaning that
+ //
+ // compose(IdxA, IdxB) == compose(IdxA', IdxB)
+ //
+ // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
+ // The illegal entries can be use as wildcards to compress the table further.
+
+ // Map each Sub-register index to a compatible table row.
+ SmallVector<unsigned, 4> RowMap;
+ SmallVector<SmallVector<CodeGenSubRegIndex*, 4>, 4> Rows;
+
+ for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
+ unsigned Found = ~0u;
+ for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
+ if (combine(SubRegIndices[i], Rows[r])) {
+ Found = r;
+ break;
+ }
+ }
+ if (Found == ~0u) {
+ Found = Rows.size();
+ Rows.resize(Found + 1);
+ Rows.back().resize(SubRegIndices.size());
+ combine(SubRegIndices[i], Rows.back());
+ }
+ RowMap.push_back(Found);
+ }
+
+ // Output the row map if there is multiple rows.
+ if (Rows.size() > 1) {
+ OS << " static const " << getMinimalTypeForRange(Rows.size())
+ << " RowMap[" << SubRegIndices.size() << "] = {\n ";
+ for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+ OS << RowMap[i] << ", ";
+ OS << "\n };\n";
+ }
+
+ // Output the rows.
+ OS << " static const " << getMinimalTypeForRange(SubRegIndices.size()+1)
+ << " Rows[" << Rows.size() << "][" << SubRegIndices.size() << "] = {\n";
+ for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
+ OS << " { ";
+ for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+ if (Rows[r][i])
+ OS << Rows[r][i]->EnumValue << ", ";
+ else
+ OS << "0, ";
+ OS << "},\n";
+ }
+ OS << " };\n\n";
+
+ OS << " --IdxA; assert(IdxA < " << SubRegIndices.size() << ");\n"
+ << " --IdxB; assert(IdxB < " << SubRegIndices.size() << ");\n";
+ if (Rows.size() > 1)
+ OS << " return Rows[RowMap[IdxA]][IdxB];\n";
+ else
+ OS << " return Rows[0][IdxB];\n";
+ OS << "}\n\n";
+}
+
//
// runMCDesc - Print out MC register descriptions.
//
const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
- // The lists of sub-registers, super-registers, and overlaps all go in the
- // same array. That allows us to share suffixes.
+ ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
+ // The lists of sub-registers and super-registers go in the same array. That
+ // allows us to share suffixes.
typedef std::vector<const CodeGenRegister*> RegVec;
// Differentially encoded lists.
SequenceToOffsetTable<DiffVec> DiffSeqs;
SmallVector<DiffVec, 4> SubRegLists(Regs.size());
SmallVector<DiffVec, 4> SuperRegLists(Regs.size());
- SmallVector<DiffVec, 4> OverlapLists(Regs.size());
SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
SmallVector<unsigned, 4> RegUnitInitScale(Regs.size());
SuperRegList.begin(), SuperRegList.end());
DiffSeqs.add(SuperRegLists[i]);
- // The list of overlaps doesn't need to have any particular order, and Reg
- // itself must be omitted.
- DiffVec &OverlapList = OverlapLists[i];
- CodeGenRegister::Set OSet;
- Reg->computeOverlaps(OSet, RegBank);
- OSet.erase(Reg);
- diffEncode(OverlapList, Reg->EnumValue, OSet.begin(), OSet.end());
- DiffSeqs.add(OverlapList);
-
// Differentially encode the register unit list, seeded by register number.
// First compute a scale factor that allows more diff-lists to be reused:
//
const std::string &TargetName = Target.getName();
// Emit the shared table of differential lists.
- OS << "extern const uint16_t " << TargetName << "RegDiffLists[] = {\n";
+ OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[] = {\n";
DiffSeqs.emit(OS, printDiff16);
OS << "};\n\n";
SubRegIdxSeqs.emit(OS, printSubRegIndex);
OS << "};\n\n";
+ // Emit the table of sub-register index sizes.
+ OS << "extern const MCRegisterInfo::SubRegCoveredBits "
+ << TargetName << "SubRegIdxRanges[] = {\n";
+ OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n";
+ for (ArrayRef<CodeGenSubRegIndex*>::const_iterator
+ SRI = SubRegIndices.begin(), SRE = SubRegIndices.end();
+ SRI != SRE; ++SRI) {
+ OS << " { " << (*SRI)->Offset << ", "
+ << (*SRI)->Size
+ << " },\t// " << (*SRI)->getName() << "\n";
+ }
+ OS << "};\n\n";
+
// Emit the string table.
RegStrings.layout();
OS << "extern const char " << TargetName << "RegStrings[] = {\n";
OS << "extern const MCRegisterDesc " << TargetName
<< "RegDesc[] = { // Descriptors\n";
- OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n";
+ OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0 },\n";
// Emit the register descriptors now.
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
const CodeGenRegister *Reg = Regs[i];
OS << " { " << RegStrings.get(Reg->getName()) << ", "
- << DiffSeqs.get(OverlapLists[i]) << ", "
<< DiffSeqs.get(SubRegLists[i]) << ", "
<< DiffSeqs.get(SuperRegLists[i]) << ", "
<< SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
OS << "};\n\n";
- ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
-
EmitRegMappingTables(OS, Regs, false);
// Emit Reg encoding table
BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
uint64_t Value = 0;
for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
- if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(b)))
+ if (BitInit *B = dyn_cast<BitInit>(BI->getBit(b)))
Value |= (uint64_t)B->getValue() << b;
}
OS << " " << Value << ",\n";
// MCRegisterInfo initialization routine.
OS << "static inline void Init" << TargetName
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
- << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"
+ << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) {\n"
<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
- << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
+ << Regs.size()+1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
<< RegisterClasses.size() << ", "
<< TargetName << "RegUnitRoots, "
<< RegBank.getNumNativeRegUnits() << ", "
<< TargetName << "RegStrings, "
<< TargetName << "SubRegIdxLists, "
<< (SubRegIndices.size() + 1) << ",\n"
+ << TargetName << "SubRegIdxRanges, "
<< " " << TargetName << "RegEncodingTable);\n\n";
EmitRegMapping(OS, Regs, false);
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
- << "(unsigned RA, unsigned D = 0, unsigned E = 0);\n"
+ << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
<< " { return false; }\n";
if (!RegBank.getSubRegIndices().empty()) {
- OS << " virtual unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
+ OS << " virtual unsigned composeSubRegIndicesImpl"
+ << "(unsigned, unsigned) const;\n"
<< " virtual const TargetRegisterClass *"
"getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n";
}
OS << " virtual const RegClassWeight &getRegClassWeight("
<< "const TargetRegisterClass *RC) const;\n"
+ << " virtual unsigned getRegUnitWeight(unsigned RegUnit) const;\n"
<< " virtual unsigned getNumRegPressureSets() const;\n"
<< " virtual const char *getRegPressureSetName(unsigned Idx) const;\n"
<< " virtual unsigned getRegPressureSetLimit(unsigned Idx) const;\n"
<< " virtual const int *getRegClassPressureSets("
<< "const TargetRegisterClass *RC) const;\n"
+ << " virtual const int *getRegUnitPressureSets(unsigned RegUnit) const;\n"
<< "};\n\n";
ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
}
// Build a shared array of value types.
- SequenceToOffsetTable<std::vector<MVT::SimpleValueType> > VTSeqs;
+ SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc)
VTSeqs.add(RegisterClasses[rc]->VTs);
VTSeqs.layout();
OS << "\nstatic inline unsigned " << RC.getName()
<< "AltOrderSelect(const MachineFunction &MF) {"
<< RC.AltOrderSelect << "}\n\n"
- << "static ArrayRef<uint16_t> " << RC.getName()
+ << "static ArrayRef<MCPhysReg> " << RC.getName()
<< "GetRawAllocationOrder(const MachineFunction &MF) {\n";
for (unsigned oi = 1 , oe = RC.getNumOrders(); oi != oe; ++oi) {
ArrayRef<Record*> Elems = RC.getOrder(oi);
if (!Elems.empty()) {
- OS << " static const uint16_t AltOrder" << oi << "[] = {";
+ OS << " static const MCPhysReg AltOrder" << oi << "[] = {";
for (unsigned elem = 0; elem != Elems.size(); ++elem)
OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
OS << " };\n";
}
OS << " const MCRegisterClass &MCR = " << Target.getName()
<< "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"
- << " const ArrayRef<uint16_t> Order[] = {\n"
+ << " const ArrayRef<MCPhysReg> Order[] = {\n"
<< " makeArrayRef(MCR.begin(), MCR.getNumRegs()";
for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
if (RC.getOrder(oi).empty())
- OS << "),\n ArrayRef<uint16_t>(";
+ OS << "),\n ArrayRef<MCPhysReg>(";
else
OS << "),\n makeArrayRef(AltOrder" << oi;
OS << ")\n };\n const unsigned Select = " << RC.getName()
std::string ClassName = Target.getName() + "GenRegisterInfo";
- // Emit composeSubRegIndices
- if (!SubRegIndices.empty()) {
- OS << "unsigned " << ClassName
- << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
- << " switch (IdxA) {\n"
- << " default:\n return IdxB;\n";
- for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
- bool Open = false;
- for (unsigned j = 0; j != e; ++j) {
- CodeGenSubRegIndex *Comp = SubRegIndices[i]->compose(SubRegIndices[j]);
- if (Comp && Comp != SubRegIndices[j]) {
- if (!Open) {
- OS << " case " << SubRegIndices[i]->getQualifiedName()
- << ": switch(IdxB) {\n default: return IdxB;\n";
- Open = true;
- }
- OS << " case " << SubRegIndices[j]->getQualifiedName()
- << ": return " << Comp->getQualifiedName() << ";\n";
- }
- }
- if (Open)
- OS << " }\n";
- }
- OS << " }\n}\n\n";
- }
+ if (!SubRegIndices.empty())
+ emitComposeSubRegIndices(OS, RegBank, ClassName);
// Emit getSubClassWithSubReg.
if (!SubRegIndices.empty()) {
else if (RegisterClasses.size() < UINT16_MAX)
OS << " static const uint16_t Table[";
else
- throw "Too many register classes.";
+ PrintFatalError("Too many register classes.");
OS << RegisterClasses.size() << "][" << SubRegIndices.size() << "] = {\n";
for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) {
const CodeGenRegisterClass &RC = *RegisterClasses[rci];
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
- OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n";
+ OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
OS << "extern const char " << TargetName << "RegStrings[];\n";
OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n";
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n";
+ OS << "extern const MCRegisterInfo::SubRegCoveredBits "
+ << TargetName << "SubRegIdxRanges[];\n";
OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
EmitRegMappingTables(OS, Regs, true);
OS << ClassName << "::\n" << ClassName
- << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
+ << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
- << " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
+ << " SubRegIndexNameTable, SubRegIndexLaneMaskTable, 0x";
+ OS.write_hex(RegBank.CoveringLanes);
+ OS << ") {\n"
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
- << Regs.size()+1 << ", RA,\n " << TargetName
+ << Regs.size()+1 << ", RA, PC,\n " << TargetName
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
<< " " << TargetName << "RegUnitRoots,\n"
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
<< " " << TargetName << "RegStrings,\n"
<< " " << TargetName << "SubRegIdxLists,\n"
<< " " << SubRegIndices.size() + 1 << ",\n"
+ << " " << TargetName << "SubRegIdxRanges,\n"
<< " " << TargetName << "RegEncodingTable);\n\n";
EmitRegMapping(OS, Regs, true);
assert(Regs && "Cannot expand CalleeSavedRegs instance");
// Emit the *_SaveList list of callee-saved registers.
- OS << "static const uint16_t " << CSRSet->getName()
+ OS << "static const MCPhysReg " << CSRSet->getName()
<< "_SaveList[] = { ";
for (unsigned r = 0, re = Regs->size(); r != re; ++r)
OS << getQualifiedName((*Regs)[r]) << ", ";