void run(raw_ostream &o);
private:
- void EmitRegMapping(raw_ostream &o,
- const std::vector<CodeGenRegister*> &Regs, bool isCtor);
+ void EmitRegMapping(raw_ostream &o, const std::deque<CodeGenRegister> &Regs,
+ bool isCtor);
void EmitRegMappingTables(raw_ostream &o,
- const std::vector<CodeGenRegister*> &Regs,
+ const std::deque<CodeGenRegister> &Regs,
bool isCtor);
void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
const std::string &ClassName);
void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
const std::string &ClassName);
+ void emitComposeSubRegIndexLaneMask(raw_ostream &OS, CodeGenRegBank &RegBank,
+ const std::string &ClassName);
};
} // End anonymous namespace
// runEnums - Print out enum values for all of the registers.
void RegisterInfoEmitter::runEnums(raw_ostream &OS,
CodeGenTarget &Target, CodeGenRegBank &Bank) {
- const std::vector<CodeGenRegister*> &Registers = Bank.getRegisters();
+ const auto &Registers = Bank.getRegisters();
// Register enums are stored as uint16_t in the tables. Make sure we'll fit.
assert(Registers.size() <= 0xffff && "Too many regs to fit in tables");
- std::string Namespace = Registers[0]->TheDef->getValueAsString("Namespace");
+ std::string Namespace =
+ Registers.front().TheDef->getValueAsString("Namespace");
emitSourceFileHeader("Target Register Enum Values", OS);
OS << "namespace " << Namespace << " {\n";
OS << "enum {\n NoRegister,\n";
- for (unsigned i = 0, e = Registers.size(); i != e; ++i)
- OS << " " << Registers[i]->getName() << " = " <<
- Registers[i]->EnumValue << ",\n";
- assert(Registers.size() == Registers[Registers.size()-1]->EnumValue &&
+ for (const auto &Reg : Registers)
+ OS << " " << Reg.getName() << " = " << Reg.EnumValue << ",\n";
+ assert(Registers.size() == Registers.back().EnumValue &&
"Register enum value mismatch!");
OS << " NUM_TARGET_REGS \t// " << Registers.size()+1 << "\n";
OS << "};\n";
if (!Namespace.empty())
OS << "}\n";
- ArrayRef<CodeGenRegisterClass*> RegisterClasses = Bank.getRegClasses();
+ const auto &RegisterClasses = Bank.getRegClasses();
if (!RegisterClasses.empty()) {
// RegisterClass enums are stored as uint16_t in the tables.
if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n";
OS << "enum {\n";
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- if (i) OS << ",\n";
- OS << " " << RegisterClasses[i]->getName() << "RegClassID";
- OS << " = " << i;
- }
+ for (const auto &RC : RegisterClasses)
+ OS << " " << RC.getName() << "RegClassID"
+ << " = " << RC.EnumValue << ",\n";
OS << "\n };\n";
if (!Namespace.empty())
OS << "}\n";
auto &SubRegIndices = Bank.getSubRegIndices();
if (!SubRegIndices.empty()) {
OS << "\n// Subregister indices\n";
- std::string Namespace = SubRegIndices.front()->getNamespace();
+ std::string Namespace = SubRegIndices.front().getNamespace();
if (!Namespace.empty())
OS << "namespace " << Namespace << " {\n";
OS << "enum {\n NoSubRegister,\n";
unsigned i = 0;
for (const auto &Idx : SubRegIndices)
- OS << " " << Idx->getName() << ",\t// " << ++i << "\n";
+ OS << " " << Idx.getName() << ",\t// " << ++i << "\n";
OS << " NUM_TARGET_SUBREGS\n};\n";
if (!Namespace.empty())
OS << "}\n";
<< "const RegClassWeight &" << ClassName << "::\n"
<< "getRegClassWeight(const TargetRegisterClass *RC) const {\n"
<< " static const RegClassWeight RCWeightTable[] = {\n";
- for (unsigned i = 0, e = NumRCs; i != e; ++i) {
- const CodeGenRegisterClass &RC = *RegBank.getRegClasses()[i];
- const CodeGenRegister::Set &Regs = RC.getMembers();
+ for (const auto &RC : RegBank.getRegClasses()) {
+ const CodeGenRegister::Vec &Regs = RC.getMembers();
if (Regs.empty())
OS << " {0, 0";
else {
OS << "// Get the name of this register unit pressure set.\n"
<< "const char *" << ClassName << "::\n"
<< "getRegPressureSetName(unsigned Idx) const {\n"
- << " static const char *PressureNameTable[] = {\n";
+ << " static const char *const PressureNameTable[] = {\n";
unsigned MaxRegUnitWeight = 0;
for (unsigned i = 0; i < NumSets; ++i ) {
const RegUnitSet &RegUnits = RegBank.getRegSetAt(i);
MaxRegUnitWeight = std::max(MaxRegUnitWeight, RegUnits.Weight);
OS << " \"" << RegUnits.Name << "\",\n";
}
- OS << " nullptr };\n"
+ OS << " };\n"
<< " return PressureNameTable[Idx];\n"
<< "}\n\n";
OS << "// Get the register unit pressure limit for this dimension.\n"
<< "// This limit must be adjusted dynamically for reserved registers.\n"
<< "unsigned " << ClassName << "::\n"
- << "getRegPressureSetLimit(unsigned Idx) const {\n"
+ << "getRegPressureSetLimit(const MachineFunction &MF, unsigned Idx) const {\n"
<< " static const " << getMinimalTypeForRange(MaxRegUnitWeight)
<< " PressureLimitTable[] = {\n";
for (unsigned i = 0; i < NumSets; ++i ) {
<< "}\n\n";
}
-void
-RegisterInfoEmitter::EmitRegMappingTables(raw_ostream &OS,
- const std::vector<CodeGenRegister*> &Regs,
- bool isCtor) {
+void RegisterInfoEmitter::EmitRegMappingTables(
+ raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
// Collect all information about dwarf register numbers
typedef std::map<Record*, std::vector<int64_t>, LessRecordRegister> DwarfRegNumsMapTy;
DwarfRegNumsMapTy DwarfRegNums;
// First, just pull all provided information to the map
unsigned maxLength = 0;
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- Record *Reg = Regs[i]->TheDef;
+ for (auto &RE : Regs) {
+ Record *Reg = RE.TheDef;
std::vector<int64_t> RegNums = Reg->getValueAsListOfInts("DwarfNumbers");
maxLength = std::max((size_t)maxLength, RegNums.size());
if (DwarfRegNums.count(Reg))
for (unsigned i = I->second.size(), e = maxLength; i != e; ++i)
I->second.push_back(-1);
- std::string Namespace = Regs[0]->TheDef->getValueAsString("Namespace");
+ std::string Namespace = Regs.front().TheDef->getValueAsString("Namespace");
OS << "// " << Namespace << " Dwarf<->LLVM register mappings.\n";
}
}
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- Record *Reg = Regs[i]->TheDef;
+ for (auto &RE : Regs) {
+ Record *Reg = RE.TheDef;
const RecordVal *V = Reg->getValue("DwarfAlias");
if (!V || !V->getValue())
continue;
}
}
-void
-RegisterInfoEmitter::EmitRegMapping(raw_ostream &OS,
- const std::vector<CodeGenRegister*> &Regs,
- bool isCtor) {
+void RegisterInfoEmitter::EmitRegMapping(
+ raw_ostream &OS, const std::deque<CodeGenRegister> &Regs, bool isCtor) {
// Emit the initializer so the tables from EmitRegMappingTables get wired up
// to the MCRegisterInfo object.
unsigned maxLength = 0;
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- Record *Reg = Regs[i]->TheDef;
+ for (auto &RE : Regs) {
+ Record *Reg = RE.TheDef;
maxLength = std::max((size_t)maxLength,
Reg->getValueAsListOfInts("DwarfNumbers").size());
}
if (!maxLength)
return;
- std::string Namespace = Regs[0]->TheDef->getValueAsString("Namespace");
+ std::string Namespace = Regs.front().TheDef->getValueAsString("Namespace");
// Emit reverse information about the dwarf register numbers.
for (unsigned j = 0; j < 2; ++j) {
// 0 differential which means we can't encode repeated elements.
typedef SmallVector<uint16_t, 4> DiffVec;
+typedef SmallVector<unsigned, 4> MaskVec;
// Differentially encode a sequence of numbers into V. The starting value and
// terminating 0 are not added to V, so it will have the same size as List.
static
-DiffVec &diffEncode(DiffVec &V, unsigned InitVal, ArrayRef<unsigned> List) {
+DiffVec &diffEncode(DiffVec &V, unsigned InitVal, SparseBitVector<> List) {
assert(V.empty() && "Clear DiffVec before diffEncode.");
uint16_t Val = uint16_t(InitVal);
- for (unsigned i = 0; i != List.size(); ++i) {
- uint16_t Cur = List[i];
+
+ for (uint16_t Cur : List) {
V.push_back(Cur - Val);
Val = Cur;
}
OS << Val;
}
+static void printMask(raw_ostream &OS, unsigned Val) {
+ OS << format("0x%08X", 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)
+ for (const auto &I : Map) {
+ 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;
+ for (const auto &I : Map) {
+ auto *&Entry = Vec[I.first->EnumValue - 1];
+ assert((!Entry || Entry == I.second) &&
+ "Expected EnumValue to be unique");
+ Entry = I.second;
+ }
return true;
}
for (const auto &Idx : SubRegIndices) {
unsigned Found = ~0u;
for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
- if (combine(Idx, Rows[r])) {
+ if (combine(&Idx, Rows[r])) {
Found = r;
break;
}
Found = Rows.size();
Rows.resize(Found + 1);
Rows.back().resize(SubRegIndicesSize);
- combine(Idx, Rows.back());
+ combine(&Idx, Rows.back());
}
RowMap.push_back(Found);
}
OS << "}\n\n";
}
+void
+RegisterInfoEmitter::emitComposeSubRegIndexLaneMask(raw_ostream &OS,
+ CodeGenRegBank &RegBank,
+ const std::string &ClName) {
+ // See the comments in computeSubRegLaneMasks() for our goal here.
+ const auto &SubRegIndices = RegBank.getSubRegIndices();
+
+ // Create a list of Mask+Rotate operations, with equivalent entries merged.
+ SmallVector<unsigned, 4> SubReg2SequenceIndexMap;
+ SmallVector<SmallVector<MaskRolPair, 1>, 4> Sequences;
+ for (const auto &Idx : SubRegIndices) {
+ const SmallVector<MaskRolPair, 1> &IdxSequence
+ = Idx.CompositionLaneMaskTransform;
+
+ unsigned Found = ~0u;
+ unsigned SIdx = 0;
+ unsigned NextSIdx;
+ for (size_t s = 0, se = Sequences.size(); s != se; ++s, SIdx = NextSIdx) {
+ SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
+ NextSIdx = SIdx + Sequence.size() + 1;
+ if (Sequence == IdxSequence) {
+ Found = SIdx;
+ break;
+ }
+ }
+ if (Found == ~0u) {
+ Sequences.push_back(IdxSequence);
+ Found = SIdx;
+ }
+ SubReg2SequenceIndexMap.push_back(Found);
+ }
+
+ OS << "unsigned " << ClName
+ << "::composeSubRegIndexLaneMaskImpl(unsigned IdxA, unsigned LaneMask)"
+ " const {\n";
+
+ OS << " struct MaskRolOp {\n"
+ " unsigned Mask;\n"
+ " uint8_t RotateLeft;\n"
+ " };\n"
+ " static const MaskRolOp Seqs[] = {\n";
+ unsigned Idx = 0;
+ for (size_t s = 0, se = Sequences.size(); s != se; ++s) {
+ OS << " ";
+ const SmallVectorImpl<MaskRolPair> &Sequence = Sequences[s];
+ for (size_t p = 0, pe = Sequence.size(); p != pe; ++p) {
+ const MaskRolPair &P = Sequence[p];
+ OS << format("{ 0x%08X, %2u }, ", P.Mask, P.RotateLeft);
+ }
+ OS << "{ 0, 0 }";
+ if (s+1 != se)
+ OS << ", ";
+ OS << " // Sequence " << Idx << "\n";
+ Idx += Sequence.size() + 1;
+ }
+ OS << " };\n"
+ " static const MaskRolOp *const CompositeSequences[] = {\n";
+ for (size_t i = 0, e = SubRegIndices.size(); i != e; ++i) {
+ OS << " ";
+ unsigned Idx = SubReg2SequenceIndexMap[i];
+ OS << format("&Seqs[%u]", Idx);
+ if (i+1 != e)
+ OS << ",";
+ OS << " // to " << SubRegIndices[i].getName() << "\n";
+ }
+ OS << " };\n\n";
+
+ OS << " --IdxA; assert(IdxA < " << SubRegIndices.size()
+ << " && \"Subregister index out of bounds\");\n"
+ " unsigned Result = 0;\n"
+ " for (const MaskRolOp *Ops = CompositeSequences[IdxA]; Ops->Mask != 0; ++Ops)"
+ " {\n"
+ " unsigned Masked = LaneMask & Ops->Mask;\n"
+ " Result |= (Masked << Ops->RotateLeft) & 0xFFFFFFFF;\n"
+ " Result |= (Masked >> ((32 - Ops->RotateLeft) & 0x1F));\n"
+ " }\n"
+ " return Result;\n"
+ "}\n";
+}
+
//
// runMCDesc - Print out MC register descriptions.
//
OS << "\n#ifdef GET_REGINFO_MC_DESC\n";
OS << "#undef GET_REGINFO_MC_DESC\n";
- const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
+ const auto &Regs = RegBank.getRegisters();
auto &SubRegIndices = RegBank.getSubRegIndices();
// The lists of sub-registers and super-registers go in the same array. That
SmallVector<DiffVec, 4> RegUnitLists(Regs.size());
SmallVector<unsigned, 4> RegUnitInitScale(Regs.size());
+ // List of lane masks accompanying register unit sequences.
+ SequenceToOffsetTable<MaskVec> LaneMaskSeqs;
+ SmallVector<MaskVec, 4> RegUnitLaneMasks(Regs.size());
+
// Keep track of sub-register names as well. These are not differentially
// encoded.
typedef SmallVector<const CodeGenSubRegIndex*, 4> SubRegIdxVec;
- SequenceToOffsetTable<SubRegIdxVec, CodeGenSubRegIndex::Less> SubRegIdxSeqs;
+ SequenceToOffsetTable<SubRegIdxVec, deref<llvm::less>> SubRegIdxSeqs;
SmallVector<SubRegIdxVec, 4> SubRegIdxLists(Regs.size());
SequenceToOffsetTable<std::string> RegStrings;
// Precompute register lists for the SequenceToOffsetTable.
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- const CodeGenRegister *Reg = Regs[i];
-
- RegStrings.add(Reg->getName());
+ unsigned i = 0;
+ for (auto I = Regs.begin(), E = Regs.end(); I != E; ++I, ++i) {
+ const auto &Reg = *I;
+ RegStrings.add(Reg.getName());
// Compute the ordered sub-register list.
SetVector<const CodeGenRegister*> SR;
- Reg->addSubRegsPreOrder(SR, RegBank);
- diffEncode(SubRegLists[i], Reg->EnumValue, SR.begin(), SR.end());
+ Reg.addSubRegsPreOrder(SR, RegBank);
+ 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]));
+ 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,
- SuperRegList.begin(), SuperRegList.end());
+ const RegVec &SuperRegList = Reg.getSuperRegs();
+ diffEncode(SuperRegLists[i], Reg.EnumValue, SuperRegList.begin(),
+ SuperRegList.end());
DiffSeqs.add(SuperRegLists[i]);
// Differentially encode the register unit list, seeded by register number.
//
// Check the neighboring registers for arithmetic progressions.
unsigned ScaleA = ~0u, ScaleB = ~0u;
- ArrayRef<unsigned> RUs = Reg->getNativeRegUnits();
- if (i > 0 && Regs[i-1]->getNativeRegUnits().size() == RUs.size())
- ScaleB = RUs.front() - Regs[i-1]->getNativeRegUnits().front();
- if (i+1 != Regs.size() &&
- Regs[i+1]->getNativeRegUnits().size() == RUs.size())
- ScaleA = Regs[i+1]->getNativeRegUnits().front() - RUs.front();
+ SparseBitVector<> RUs = Reg.getNativeRegUnits();
+ if (I != Regs.begin() &&
+ std::prev(I)->getNativeRegUnits().count() == RUs.count())
+ ScaleB = *RUs.begin() - *std::prev(I)->getNativeRegUnits().begin();
+ if (std::next(I) != Regs.end() &&
+ std::next(I)->getNativeRegUnits().count() == RUs.count())
+ ScaleA = *std::next(I)->getNativeRegUnits().begin() - *RUs.begin();
unsigned Scale = std::min(ScaleB, ScaleA);
// Default the scale to 0 if it can't be encoded in 4 bits.
if (Scale >= 16)
Scale = 0;
RegUnitInitScale[i] = Scale;
- DiffSeqs.add(diffEncode(RegUnitLists[i], Scale * Reg->EnumValue, RUs));
+ DiffSeqs.add(diffEncode(RegUnitLists[i], Scale * Reg.EnumValue, RUs));
+
+ const auto &RUMasks = Reg.getRegUnitLaneMasks();
+ MaskVec &LaneMaskVec = RegUnitLaneMasks[i];
+ assert(LaneMaskVec.empty());
+ LaneMaskVec.insert(LaneMaskVec.begin(), RUMasks.begin(), RUMasks.end());
+ // Terminator mask should not be used inside of the list.
+#ifndef NDEBUG
+ for (unsigned M : LaneMaskVec) {
+ assert(M != ~0u && "terminator mask should not be part of the list");
+ }
+#endif
+ LaneMaskSeqs.add(LaneMaskVec);
}
// Compute the final layout of the sequence table.
DiffSeqs.layout();
+ LaneMaskSeqs.layout();
SubRegIdxSeqs.layout();
OS << "namespace llvm {\n\n";
DiffSeqs.emit(OS, printDiff16);
OS << "};\n\n";
+ // Emit the shared table of regunit lane mask sequences.
+ OS << "extern const unsigned " << TargetName << "LaneMaskLists[] = {\n";
+ LaneMaskSeqs.emit(OS, printMask, "~0u");
+ OS << "};\n\n";
+
// Emit the table of sub-register indexes.
OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n";
SubRegIdxSeqs.emit(OS, printSubRegIndex);
<< TargetName << "SubRegIdxRanges[] = {\n";
OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n";
for (const auto &Idx : SubRegIndices) {
- OS << " { " << Idx->Offset << ", "
- << Idx->Size
- << " },\t// " << Idx->getName() << "\n";
+ OS << " { " << Idx.Offset << ", " << Idx.Size << " },\t// "
+ << Idx.getName() << "\n";
}
OS << "};\n\n";
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) {
- const CodeGenRegister *Reg = Regs[i];
- OS << " { " << RegStrings.get(Reg->getName()) << ", "
- << DiffSeqs.get(SubRegLists[i]) << ", "
- << DiffSeqs.get(SuperRegLists[i]) << ", "
- << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
- << (DiffSeqs.get(RegUnitLists[i])*16 + RegUnitInitScale[i]) << " },\n";
+ i = 0;
+ for (const auto &Reg : Regs) {
+ OS << " { " << RegStrings.get(Reg.getName()) << ", "
+ << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i])
+ << ", " << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", "
+ << (DiffSeqs.get(RegUnitLists[i]) * 16 + RegUnitInitScale[i]) << ", "
+ << LaneMaskSeqs.get(RegUnitLaneMasks[i]) << " },\n";
+ ++i;
}
OS << "};\n\n"; // End of register descriptors...
}
OS << "};\n\n";
- ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
+ const auto &RegisterClasses = RegBank.getRegClasses();
// 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];
+ for (const auto &RC : RegisterClasses) {
ArrayRef<Record*> Order = RC.getOrder();
// Give the register class a legal C name if it's anonymous.
OS << "extern const MCRegisterClass " << TargetName
<< "MCRegisterClasses[] = {\n";
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- const CodeGenRegisterClass &RC = *RegisterClasses[rc];
-
+ for (const auto &RC : RegisterClasses) {
// Asserts to make sure values will fit in table assuming types from
// MCRegisterInfo.h
assert((RC.SpillSize/8) <= 0xffff && "SpillSize too large.");
OS << "RegEncodingTable[] = {\n";
// Add entry for NoRegister
OS << " 0,\n";
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- Record *Reg = Regs[i]->TheDef;
+ for (const auto &RE : Regs) {
+ Record *Reg = RE.TheDef;
BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
uint64_t Value = 0;
for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
<< Regs.size() + 1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
<< RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, "
<< RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, "
- << TargetName << "RegStrings, " << TargetName << "RegClassStrings, "
- << TargetName << "SubRegIdxLists, "
+ << TargetName << "LaneMaskLists, " << TargetName << "RegStrings, "
+ << TargetName << "RegClassStrings, " << TargetName << "SubRegIdxLists, "
<< (std::distance(SubRegIndices.begin(), SubRegIndices.end()) + 1) << ",\n"
<< TargetName << "SubRegIdxRanges, " << TargetName
<< "RegEncodingTable);\n\n";
OS << "namespace llvm {\n\n";
+ OS << "class " << TargetName << "FrameLowering;\n\n";
+
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
<< " explicit " << ClassName
- << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
- << " bool needsStackRealignment(const MachineFunction &) const override\n"
- << " { return false; }\n";
+ << "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n";
if (!RegBank.getSubRegIndices().empty()) {
OS << " unsigned composeSubRegIndicesImpl"
+ << "(unsigned, unsigned) const override;\n"
+ << " unsigned composeSubRegIndexLaneMaskImpl"
<< "(unsigned, unsigned) const override;\n"
<< " const TargetRegisterClass *getSubClassWithSubReg"
<< "(const TargetRegisterClass*, unsigned) const override;\n";
<< " unsigned getRegUnitWeight(unsigned RegUnit) const override;\n"
<< " unsigned getNumRegPressureSets() const override;\n"
<< " const char *getRegPressureSetName(unsigned Idx) const override;\n"
- << " unsigned getRegPressureSetLimit(unsigned Idx) const override;\n"
+ << " unsigned getRegPressureSetLimit(const MachineFunction &MF, unsigned "
+ "Idx) const override;\n"
<< " const int *getRegClassPressureSets("
<< "const TargetRegisterClass *RC) const override;\n"
<< " const int *getRegUnitPressureSets("
<< "unsigned RegUnit) const override;\n"
+ << " ArrayRef<const char *> getRegMaskNames() const override;\n"
+ << " ArrayRef<const uint32_t *> getRegMasks() const override;\n"
+ << " /// Devirtualized TargetFrameLowering.\n"
+ << " static const " << TargetName << "FrameLowering *getFrameLowering(\n"
+ << " const MachineFunction &MF);\n"
<< "};\n\n";
- ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
+ const auto &RegisterClasses = RegBank.getRegClasses();
if (!RegisterClasses.empty()) {
- OS << "namespace " << RegisterClasses[0]->Namespace
+ OS << "namespace " << RegisterClasses.front().Namespace
<< " { // Register classes\n";
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- const CodeGenRegisterClass &RC = *RegisterClasses[i];
+ for (const auto &RC : RegisterClasses) {
const std::string &Name = RC.getName();
// Output the extern for the instance.
<< "MCRegisterClasses[];\n";
// Start out by emitting each of the register classes.
- ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
+ const auto &RegisterClasses = RegBank.getRegClasses();
const auto &SubRegIndices = RegBank.getSubRegIndices();
// Collect all registers belonging to any allocatable class.
std::set<Record*> AllocatableRegs;
// Collect allocatable registers.
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- const CodeGenRegisterClass &RC = *RegisterClasses[rc];
+ for (const auto &RC : RegisterClasses) {
ArrayRef<Record*> Order = RC.getOrder();
if (RC.Allocatable)
// Build a shared array of value types.
SequenceToOffsetTable<SmallVector<MVT::SimpleValueType, 4> > VTSeqs;
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc)
- VTSeqs.add(RegisterClasses[rc]->VTs);
+ for (const auto &RC : RegisterClasses)
+ VTSeqs.add(RC.VTs);
VTSeqs.layout();
OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
OS << "\nstatic const char *const SubRegIndexNameTable[] = { \"";
for (const auto &Idx : SubRegIndices) {
- OS << Idx->getName();
+ OS << Idx.getName();
OS << "\", \"";
}
OS << "\" };\n\n";
// Emit SubRegIndex lane masks, including 0.
OS << "\nstatic const unsigned SubRegIndexLaneMaskTable[] = {\n ~0u,\n";
for (const auto &Idx : SubRegIndices) {
- OS << format(" 0x%08x, // ", Idx->LaneMask)
- << Idx->getName() << '\n';
+ OS << format(" 0x%08x, // ", Idx.LaneMask) << Idx.getName() << '\n';
}
OS << " };\n\n";
// Compress the sub-reg index lists.
typedef std::vector<const CodeGenSubRegIndex*> IdxList;
SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
- SequenceToOffsetTable<IdxList, CodeGenSubRegIndex::Less> SuperRegIdxSeqs;
+ SequenceToOffsetTable<IdxList, deref<llvm::less>> SuperRegIdxSeqs;
BitVector MaskBV(RegisterClasses.size());
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- const CodeGenRegisterClass &RC = *RegisterClasses[rc];
+ for (const auto &RC : RegisterClasses) {
OS << "static const uint32_t " << RC.getName() << "SubClassMask[] = {\n ";
printBitVectorAsHex(OS, RC.getSubClasses(), 32);
// Emit super-reg class masks for any relevant SubRegIndices that can
// project into RC.
- IdxList &SRIList = SuperRegIdxLists[rc];
+ IdxList &SRIList = SuperRegIdxLists[RC.EnumValue];
for (auto &Idx : SubRegIndices) {
MaskBV.reset();
- RC.getSuperRegClasses(Idx, MaskBV);
+ RC.getSuperRegClasses(&Idx, MaskBV);
if (MaskBV.none())
continue;
- SRIList.push_back(Idx);
+ SRIList.push_back(&Idx);
OS << "\n ";
printBitVectorAsHex(OS, MaskBV, 32);
- OS << "// " << Idx->getName();
+ OS << "// " << Idx.getName();
}
SuperRegIdxSeqs.add(SRIList);
OS << "\n};\n\n";
OS << "};\n\n";
// Emit NULL terminated super-class lists.
- for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
- const CodeGenRegisterClass &RC = *RegisterClasses[rc];
+ for (const auto &RC : RegisterClasses) {
ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();
// Skip classes without supers. We can reuse NullRegClasses.
OS << "static const TargetRegisterClass *const "
<< RC.getName() << "Superclasses[] = {\n";
- for (unsigned i = 0; i != Supers.size(); ++i)
- OS << " &" << Supers[i]->getQualifiedName() << "RegClass,\n";
+ for (const auto *Super : Supers)
+ OS << " &" << Super->getQualifiedName() << "RegClass,\n";
OS << " nullptr\n};\n\n";
}
// Emit methods.
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- const CodeGenRegisterClass &RC = *RegisterClasses[i];
+ for (const auto &RC : RegisterClasses) {
if (!RC.AltOrderSelect.empty()) {
OS << "\nstatic inline unsigned " << RC.getName()
<< "AltOrderSelect(const MachineFunction &MF) {"
OS << ")\n };\n const unsigned Select = " << RC.getName()
<< "AltOrderSelect(MF);\n assert(Select < " << RC.getNumOrders()
<< ");\n return Order[Select];\n}\n";
- }
+ }
}
// Now emit the actual value-initialized register class instances.
- OS << "\nnamespace " << RegisterClasses[0]->Namespace
+ OS << "\nnamespace " << RegisterClasses.front().Namespace
<< " { // Register class instances\n";
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
- const CodeGenRegisterClass &RC = *RegisterClasses[i];
- OS << " extern const TargetRegisterClass "
- << RegisterClasses[i]->getName() << "RegClass = {\n "
- << '&' << Target.getName() << "MCRegisterClasses[" << RC.getName()
- << "RegClassID],\n "
- << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n "
- << RC.getName() << "SubClassMask,\n SuperRegIdxSeqs + "
- << SuperRegIdxSeqs.get(SuperRegIdxLists[i]) << ",\n ";
+ for (const auto &RC : RegisterClasses) {
+ OS << " extern const TargetRegisterClass " << RC.getName()
+ << "RegClass = {\n " << '&' << Target.getName()
+ << "MCRegisterClasses[" << RC.getName() << "RegClassID],\n "
+ << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n " << RC.getName()
+ << "SubClassMask,\n SuperRegIdxSeqs + "
+ << SuperRegIdxSeqs.get(SuperRegIdxLists[RC.EnumValue]) << ",\n "
+ << format("0x%08x,\n ", RC.LaneMask)
+ << (unsigned)RC.AllocationPriority << ",\n "
+ << (RC.HasDisjunctSubRegs?"true":"false")
+ << ", /* HasDisjunctSubRegs */\n ";
if (RC.getSuperClasses().empty())
OS << "NullRegClasses,\n ";
else
OS << "\nnamespace {\n";
OS << " const TargetRegisterClass* const RegisterClasses[] = {\n";
- for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
- OS << " &" << RegisterClasses[i]->getQualifiedName()
- << "RegClass,\n";
+ for (const auto &RC : RegisterClasses)
+ OS << " &" << RC.getQualifiedName() << "RegClass,\n";
OS << " };\n";
OS << "}\n"; // End of anonymous namespace...
<< TargetName << "RegInfoDesc[] = { // Extra Descriptors\n";
OS << " { 0, 0 },\n";
- const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
- for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
- const CodeGenRegister &Reg = *Regs[i];
+ const auto &Regs = RegBank.getRegisters();
+ for (const auto &Reg : Regs) {
OS << " { ";
OS << Reg.CostPerUse << ", "
<< int(AllocatableRegs.count(Reg.TheDef)) << " },\n";
auto SubRegIndicesSize =
std::distance(SubRegIndices.begin(), SubRegIndices.end());
- if (!SubRegIndices.empty())
+ if (!SubRegIndices.empty()) {
emitComposeSubRegIndices(OS, RegBank, ClassName);
+ emitComposeSubRegIndexLaneMask(OS, RegBank, ClassName);
+ }
// Emit getSubClassWithSubReg.
if (!SubRegIndices.empty()) {
else
PrintFatalError("Too many register classes.");
OS << RegisterClasses.size() << "][" << SubRegIndicesSize << "] = {\n";
- for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) {
- const CodeGenRegisterClass &RC = *RegisterClasses[rci];
+ for (const auto &RC : RegisterClasses) {
OS << " {\t// " << RC.getName() << "\n";
for (auto &Idx : SubRegIndices) {
- if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(Idx))
- OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx->getName()
+ if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
+ OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx.getName()
<< " -> " << SRC->getName() << "\n";
else
- OS << " 0,\t// " << Idx->getName() << "\n";
+ OS << " 0,\t// " << Idx.getName() << "\n";
}
OS << " },\n";
}
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
OS << "extern const MCPhysReg " << TargetName << "RegDiffLists[];\n";
+ OS << "extern const unsigned " << TargetName << "LaneMaskLists[];\n";
OS << "extern const char " << TargetName << "RegStrings[];\n";
OS << "extern const char " << TargetName << "RegClassStrings[];\n";
OS << "extern const MCPhysReg " << TargetName << "RegUnitRoots[][2];\n";
<< " " << TargetName << "RegUnitRoots,\n"
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
<< " " << TargetName << "RegDiffLists,\n"
+ << " " << TargetName << "LaneMaskLists,\n"
<< " " << TargetName << "RegStrings,\n"
<< " " << TargetName << "RegClassStrings,\n"
<< " " << TargetName << "SubRegIdxLists,\n"
}
OS << "\n\n";
+ OS << "ArrayRef<const uint32_t *> " << ClassName
+ << "::getRegMasks() const {\n";
+ if (!CSRSets.empty()) {
+ OS << " static const uint32_t *const Masks[] = {\n";
+ for (Record *CSRSet : CSRSets)
+ OS << " " << CSRSet->getName() << "_RegMask,\n";
+ OS << " };\n";
+ OS << " return makeArrayRef(Masks);\n";
+ } else {
+ OS << " return None;\n";
+ }
+ OS << "}\n\n";
+
+ OS << "ArrayRef<const char *> " << ClassName
+ << "::getRegMaskNames() const {\n";
+ if (!CSRSets.empty()) {
+ OS << " static const char *const Names[] = {\n";
+ for (Record *CSRSet : CSRSets)
+ OS << " " << '"' << CSRSet->getName() << '"' << ",\n";
+ OS << " };\n";
+ OS << " return makeArrayRef(Names);\n";
+ } else {
+ OS << " return None;\n";
+ }
+ OS << "}\n\n";
+
+ OS << "const " << TargetName << "FrameLowering *\n" << TargetName
+ << "GenRegisterInfo::getFrameLowering(const MachineFunction &MF) {\n"
+ << " return static_cast<const " << TargetName << "FrameLowering *>(\n"
+ << " MF.getSubtarget().getFrameLowering());\n"
+ << "}\n\n";
+
OS << "} // End llvm namespace\n";
OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
}