mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 20:29:53 +00:00
Range-for some stuff related to RegClasses, and comment cases where range-for isn't suitable.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223260 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
93ce526d0a
commit
89036eb44c
@ -1081,8 +1081,7 @@ struct LessRegisterSet {
|
||||
void AsmMatcherInfo::
|
||||
buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
|
||||
const auto &Registers = Target.getRegBank().getRegisters();
|
||||
ArrayRef<CodeGenRegisterClass*> RegClassList =
|
||||
Target.getRegBank().getRegClasses();
|
||||
auto &RegClassList = Target.getRegBank().getRegClasses();
|
||||
|
||||
typedef std::set<RegisterSet, LessRegisterSet> RegisterSetSet;
|
||||
|
||||
|
@ -812,8 +812,8 @@ static bool testSubClass(const CodeGenRegisterClass *A,
|
||||
///
|
||||
static int TopoOrderRC(CodeGenRegisterClass *const *PA,
|
||||
CodeGenRegisterClass *const *PB) {
|
||||
const CodeGenRegisterClass *A = *PA;
|
||||
const CodeGenRegisterClass *B = *PB;
|
||||
auto *A = *PA;
|
||||
auto *B = *PB;
|
||||
if (A == B)
|
||||
return 0;
|
||||
|
||||
@ -850,47 +850,51 @@ std::string CodeGenRegisterClass::getQualifiedName() const {
|
||||
// Compute sub-classes of all register classes.
|
||||
// Assume the classes are ordered topologically.
|
||||
void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
|
||||
ArrayRef<CodeGenRegisterClass*> RegClasses = RegBank.getRegClasses();
|
||||
auto &RegClasses = RegBank.getRegClasses();
|
||||
|
||||
// Visit backwards so sub-classes are seen first.
|
||||
for (unsigned rci = RegClasses.size(); rci; --rci) {
|
||||
CodeGenRegisterClass &RC = *RegClasses[rci - 1];
|
||||
for (auto I = RegClasses.rbegin(), E = RegClasses.rend(); I != E; ++I) {
|
||||
CodeGenRegisterClass &RC = **I;
|
||||
RC.SubClasses.resize(RegClasses.size());
|
||||
RC.SubClasses.set(RC.EnumValue);
|
||||
|
||||
// Normally, all subclasses have IDs >= rci, unless RC is part of a clique.
|
||||
for (unsigned s = rci; s != RegClasses.size(); ++s) {
|
||||
if (RC.SubClasses.test(s))
|
||||
for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) {
|
||||
CodeGenRegisterClass &SubRC = **I2;
|
||||
if (RC.SubClasses.test(SubRC.EnumValue))
|
||||
continue;
|
||||
CodeGenRegisterClass *SubRC = RegClasses[s];
|
||||
if (!testSubClass(&RC, SubRC))
|
||||
if (!testSubClass(&RC, &SubRC))
|
||||
continue;
|
||||
// SubRC is a sub-class. Grap all its sub-classes so we won't have to
|
||||
// check them again.
|
||||
RC.SubClasses |= SubRC->SubClasses;
|
||||
RC.SubClasses |= SubRC.SubClasses;
|
||||
}
|
||||
|
||||
// Sweep up missed clique members. They will be immediately preceding RC.
|
||||
for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s)
|
||||
RC.SubClasses.set(s - 1);
|
||||
for (auto I2 = std::next(I); I2 != E && testSubClass(&RC, *I2); ++I2)
|
||||
RC.SubClasses.set((*I2)->EnumValue);
|
||||
}
|
||||
|
||||
// Compute the SuperClasses lists from the SubClasses vectors.
|
||||
for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
|
||||
const BitVector &SC = RegClasses[rci]->getSubClasses();
|
||||
for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) {
|
||||
if (unsigned(s) == rci)
|
||||
for (auto *RC : RegClasses) {
|
||||
const BitVector &SC = RC->getSubClasses();
|
||||
auto I = RegClasses.begin();
|
||||
for (int s = 0, next_s = SC.find_first(); next_s != -1;
|
||||
next_s = SC.find_next(s)) {
|
||||
std::advance(I, next_s - s);
|
||||
s = next_s;
|
||||
if (*I == RC)
|
||||
continue;
|
||||
RegClasses[s]->SuperClasses.push_back(RegClasses[rci]);
|
||||
(*I)->SuperClasses.push_back(RC);
|
||||
}
|
||||
}
|
||||
|
||||
// With the class hierarchy in place, let synthesized register classes inherit
|
||||
// properties from their closest super-class. The iteration order here can
|
||||
// propagate properties down multiple levels.
|
||||
for (unsigned rci = 0; rci != RegClasses.size(); ++rci)
|
||||
if (!RegClasses[rci]->getDef())
|
||||
RegClasses[rci]->inheritProperties(RegBank);
|
||||
for (auto *RC : RegClasses)
|
||||
if (!RC->getDef())
|
||||
RC->inheritProperties(RegBank);
|
||||
}
|
||||
|
||||
void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
|
||||
@ -990,24 +994,22 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) {
|
||||
PrintFatalError("No 'RegisterClass' subclasses defined!");
|
||||
|
||||
// Allocate user-defined register classes.
|
||||
RegClasses.reserve(RCs.size());
|
||||
for (unsigned i = 0, e = RCs.size(); i != e; ++i)
|
||||
addToMaps(new CodeGenRegisterClass(*this, RCs[i]));
|
||||
for (auto *RC : RCs) {
|
||||
RegClasses.push_back(new CodeGenRegisterClass(*this, RC));
|
||||
addToMaps(RegClasses.back());
|
||||
}
|
||||
|
||||
// Infer missing classes to create a full algebra.
|
||||
computeInferredRegisterClasses();
|
||||
|
||||
// Order register classes topologically and assign enum values.
|
||||
array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC);
|
||||
for (unsigned i = 0, e = RegClasses.size(); i != e; ++i)
|
||||
RegClasses[i]->EnumValue = i;
|
||||
unsigned i = 0;
|
||||
for (auto *RC : RegClasses)
|
||||
RC->EnumValue = i++;
|
||||
CodeGenRegisterClass::computeSubClasses(*this);
|
||||
}
|
||||
|
||||
CodeGenRegBank::~CodeGenRegBank() {
|
||||
DeleteContainerPointers(RegClasses);
|
||||
}
|
||||
|
||||
// Create a synthetic CodeGenSubRegIndex without a corresponding Record.
|
||||
CodeGenSubRegIndex*
|
||||
CodeGenRegBank::createSubRegIndex(StringRef Name, StringRef Namespace) {
|
||||
@ -1034,8 +1036,6 @@ CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
|
||||
}
|
||||
|
||||
void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) {
|
||||
RegClasses.push_back(RC);
|
||||
|
||||
if (Record *Def = RC->getDef())
|
||||
Def2RC.insert(std::make_pair(Def, RC));
|
||||
|
||||
@ -1057,9 +1057,9 @@ CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
|
||||
return FoundI->second;
|
||||
|
||||
// Sub-class doesn't exist, create a new one.
|
||||
CodeGenRegisterClass *NewRC = new CodeGenRegisterClass(*this, Name, K);
|
||||
addToMaps(NewRC);
|
||||
return NewRC;
|
||||
RegClasses.push_back(new CodeGenRegisterClass(*this, Name, K));
|
||||
addToMaps(RegClasses.back());
|
||||
return RegClasses.back();
|
||||
}
|
||||
|
||||
CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) {
|
||||
@ -1247,9 +1247,7 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
|
||||
// For simplicitly make the SetID the same as EnumValue.
|
||||
IntEqClasses UberSetIDs(Registers.size()+1);
|
||||
std::set<unsigned> AllocatableRegs;
|
||||
for (unsigned i = 0, e = RegBank.getRegClasses().size(); i != e; ++i) {
|
||||
|
||||
CodeGenRegisterClass *RegClass = RegBank.getRegClasses()[i];
|
||||
for (auto *RegClass : RegBank.getRegClasses()) {
|
||||
if (!RegClass->Allocatable)
|
||||
continue;
|
||||
|
||||
@ -1526,18 +1524,17 @@ void CodeGenRegBank::computeRegUnitSets() {
|
||||
assert(RegUnitSets.empty() && "dirty RegUnitSets");
|
||||
|
||||
// Compute a unique RegUnitSet for each RegClass.
|
||||
ArrayRef<CodeGenRegisterClass*> RegClasses = getRegClasses();
|
||||
unsigned NumRegClasses = RegClasses.size();
|
||||
for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
|
||||
if (!RegClasses[RCIdx]->Allocatable)
|
||||
auto &RegClasses = getRegClasses();
|
||||
for (auto *RC : RegClasses) {
|
||||
if (!RC->Allocatable)
|
||||
continue;
|
||||
|
||||
// Speculatively grow the RegUnitSets to hold the new set.
|
||||
RegUnitSets.resize(RegUnitSets.size() + 1);
|
||||
RegUnitSets.back().Name = RegClasses[RCIdx]->getName();
|
||||
RegUnitSets.back().Name = RC->getName();
|
||||
|
||||
// Compute a sorted list of units in this class.
|
||||
RegClasses[RCIdx]->buildRegUnitSet(RegUnitSets.back().Units);
|
||||
RC->buildRegUnitSet(RegUnitSets.back().Units);
|
||||
|
||||
// Find an existing RegUnitSet.
|
||||
std::vector<RegUnitSet>::const_iterator SetI =
|
||||
@ -1635,22 +1632,24 @@ void CodeGenRegBank::computeRegUnitSets() {
|
||||
});
|
||||
|
||||
// For each register class, list the UnitSets that are supersets.
|
||||
RegClassUnitSets.resize(NumRegClasses);
|
||||
for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) {
|
||||
if (!RegClasses[RCIdx]->Allocatable)
|
||||
RegClassUnitSets.resize(RegClasses.size());
|
||||
int RCIdx = -1;
|
||||
for (auto *RC : RegClasses) {
|
||||
++RCIdx;
|
||||
if (!RC->Allocatable)
|
||||
continue;
|
||||
|
||||
// Recompute the sorted list of units in this class.
|
||||
std::vector<unsigned> RCRegUnits;
|
||||
RegClasses[RCIdx]->buildRegUnitSet(RCRegUnits);
|
||||
RC->buildRegUnitSet(RCRegUnits);
|
||||
|
||||
// Don't increase pressure for unallocatable regclasses.
|
||||
if (RCRegUnits.empty())
|
||||
continue;
|
||||
|
||||
DEBUG(dbgs() << "RC " << RegClasses[RCIdx]->getName() << " Units: \n";
|
||||
for (unsigned i = 0, e = RCRegUnits.size(); i < e; ++i)
|
||||
dbgs() << RegUnits[RCRegUnits[i]].getRoots()[0]->getName() << " ";
|
||||
DEBUG(dbgs() << "RC " << RC->getName() << " Units: \n";
|
||||
for (unsigned i = 0, e = RCRegUnits.size(); i < e; ++i) dbgs()
|
||||
<< RegUnits[RCRegUnits[i]].getRoots()[0]->getName() << " ";
|
||||
dbgs() << "\n UnitSetIDs:");
|
||||
|
||||
// Find all supersets.
|
||||
@ -1733,6 +1732,9 @@ void CodeGenRegBank::computeDerivedInfo() {
|
||||
// returns a maximal register class for all X.
|
||||
//
|
||||
void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) {
|
||||
// This loop might add more subclasses, invalidating iterators, so don't use
|
||||
// range-for or iterator-based loops (unless RegClasses is changed to use a
|
||||
// container with appropriate iterator invalidation semantics for this).
|
||||
for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) {
|
||||
CodeGenRegisterClass *RC1 = RC;
|
||||
CodeGenRegisterClass *RC2 = RegClasses[rci];
|
||||
@ -1840,29 +1842,31 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
|
||||
|
||||
// Iterate over sub-register class candidates. Ignore classes created by
|
||||
// this loop. They will never be useful.
|
||||
// Careful if trying to transform this loop to use iterators - as this loop
|
||||
// will add new classes it will invalidate iterators to RegClasses.
|
||||
for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
|
||||
++rci) {
|
||||
CodeGenRegisterClass *SubRC = RegClasses[rci];
|
||||
CodeGenRegisterClass &SubRC = *RegClasses[rci];
|
||||
// Topological shortcut: SubRC members have the wrong shape.
|
||||
if (!TopoSigs.anyCommon(SubRC->getTopoSigs()))
|
||||
if (!TopoSigs.anyCommon(SubRC.getTopoSigs()))
|
||||
continue;
|
||||
// Compute the subset of RC that maps into SubRC.
|
||||
CodeGenRegister::Set SubSet;
|
||||
for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
|
||||
if (SubRC->contains(SSPairs[i].second))
|
||||
if (SubRC.contains(SSPairs[i].second))
|
||||
SubSet.insert(SSPairs[i].first);
|
||||
if (SubSet.empty())
|
||||
continue;
|
||||
// RC injects completely into SubRC.
|
||||
if (SubSet.size() == SSPairs.size()) {
|
||||
SubRC->addSuperRegClass(&SubIdx, RC);
|
||||
SubRC.addSuperRegClass(&SubIdx, RC);
|
||||
continue;
|
||||
}
|
||||
// Only a subset of RC maps into SubRC. Make sure it is represented by a
|
||||
// class.
|
||||
getOrCreateSubClass(RC, &SubSet, RC->getName() + "_with_" +
|
||||
SubIdx.getName() + "_in_" +
|
||||
SubRC->getName());
|
||||
SubRC.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1878,6 +1882,9 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
||||
unsigned FirstNewRC = RegClasses.size();
|
||||
|
||||
// Visit all register classes, including the ones being added by the loop.
|
||||
// Watch out for iterator invalidation here.
|
||||
// inferMatchingSuperRegClass inside this loop can add new elements to
|
||||
// RegClasses, so this loop can't use range-for or even explicit iterators.
|
||||
for (unsigned rci = 0; rci != RegClasses.size(); ++rci) {
|
||||
CodeGenRegisterClass *RC = RegClasses[rci];
|
||||
|
||||
@ -1899,6 +1906,8 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
||||
if (rci + 1 == FirstNewRC) {
|
||||
unsigned NextNewRC = RegClasses.size();
|
||||
for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2)
|
||||
// This can add more things to RegClasses, be careful about iterator
|
||||
// invalidation of outer loop variables.
|
||||
inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC);
|
||||
FirstNewRC = NextNewRC;
|
||||
}
|
||||
@ -1913,10 +1922,9 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
||||
const CodeGenRegisterClass*
|
||||
CodeGenRegBank::getRegClassForRegister(Record *R) {
|
||||
const CodeGenRegister *Reg = getReg(R);
|
||||
ArrayRef<CodeGenRegisterClass*> RCs = getRegClasses();
|
||||
const CodeGenRegisterClass *FoundRC = nullptr;
|
||||
for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
|
||||
const CodeGenRegisterClass &RC = *RCs[i];
|
||||
for (const auto *RCP : getRegClasses()) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
if (!RC.contains(Reg))
|
||||
continue;
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "llvm/TableGen/Record.h"
|
||||
#include "llvm/TableGen/SetTheory.h"
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
@ -523,7 +524,6 @@ namespace llvm {
|
||||
|
||||
public:
|
||||
CodeGenRegBank(RecordKeeper&);
|
||||
~CodeGenRegBank();
|
||||
|
||||
SetTheory &getSets() { return Sets; }
|
||||
|
||||
@ -609,7 +609,9 @@ namespace llvm {
|
||||
RegUnit &getRegUnit(unsigned RUID) { return RegUnits[RUID]; }
|
||||
const RegUnit &getRegUnit(unsigned RUID) const { return RegUnits[RUID]; }
|
||||
|
||||
ArrayRef<CodeGenRegisterClass*> getRegClasses() const {
|
||||
std::vector<CodeGenRegisterClass *> &getRegClasses() { return RegClasses; }
|
||||
|
||||
const std::vector<CodeGenRegisterClass *> &getRegClasses() const {
|
||||
return RegClasses;
|
||||
}
|
||||
|
||||
|
@ -232,11 +232,9 @@ std::vector<MVT::SimpleValueType> CodeGenTarget::
|
||||
getRegisterVTs(Record *R) const {
|
||||
const CodeGenRegister *Reg = getRegBank().getReg(R);
|
||||
std::vector<MVT::SimpleValueType> Result;
|
||||
ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
|
||||
for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
|
||||
const CodeGenRegisterClass &RC = *RCs[i];
|
||||
if (RC.contains(Reg)) {
|
||||
ArrayRef<MVT::SimpleValueType> InVTs = RC.getValueTypes();
|
||||
for (const auto &RC : getRegBank().getRegClasses()) {
|
||||
if (RC->contains(Reg)) {
|
||||
ArrayRef<MVT::SimpleValueType> InVTs = RC->getValueTypes();
|
||||
Result.insert(Result.end(), InVTs.begin(), InVTs.end());
|
||||
}
|
||||
}
|
||||
@ -249,10 +247,9 @@ getRegisterVTs(Record *R) const {
|
||||
|
||||
|
||||
void CodeGenTarget::ReadLegalValueTypes() const {
|
||||
ArrayRef<CodeGenRegisterClass*> RCs = getRegBank().getRegClasses();
|
||||
for (unsigned i = 0, e = RCs.size(); i != e; ++i)
|
||||
for (unsigned ri = 0, re = RCs[i]->VTs.size(); ri != re; ++ri)
|
||||
LegalValueTypes.push_back(RCs[i]->VTs[ri]);
|
||||
for (const auto *RC : getRegBank().getRegClasses())
|
||||
for (unsigned ri = 0, re = RC->VTs.size(); ri != re; ++ri)
|
||||
LegalValueTypes.push_back(RC->VTs[ri]);
|
||||
|
||||
// Remove duplicates.
|
||||
std::sort(LegalValueTypes.begin(), LegalValueTypes.end());
|
||||
|
@ -27,21 +27,19 @@ static MVT::SimpleValueType getRegisterValueType(Record *R,
|
||||
bool FoundRC = false;
|
||||
MVT::SimpleValueType VT = MVT::Other;
|
||||
const CodeGenRegister *Reg = T.getRegBank().getReg(R);
|
||||
ArrayRef<CodeGenRegisterClass*> RCs = T.getRegBank().getRegClasses();
|
||||
|
||||
for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) {
|
||||
const CodeGenRegisterClass &RC = *RCs[rc];
|
||||
if (!RC.contains(Reg))
|
||||
for (const auto *RC : T.getRegBank().getRegClasses()) {
|
||||
if (!RC->contains(Reg))
|
||||
continue;
|
||||
|
||||
if (!FoundRC) {
|
||||
FoundRC = true;
|
||||
VT = RC.getValueTypeNum(0);
|
||||
VT = RC->getValueTypeNum(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If this occurs in multiple register classes, they all have to agree.
|
||||
assert(VT == RC.getValueTypeNum(0));
|
||||
assert(VT == RC->getValueTypeNum(0));
|
||||
}
|
||||
return VT;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
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.
|
||||
@ -111,11 +111,9 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS,
|
||||
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";
|
||||
@ -179,8 +177,8 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
|
||||
<< "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];
|
||||
for (const auto *RCP : RegBank.getRegClasses()) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
const CodeGenRegister::Set &Regs = RC.getMembers();
|
||||
if (Regs.empty())
|
||||
OS << " {0, 0";
|
||||
@ -838,7 +836,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
}
|
||||
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";
|
||||
@ -846,8 +844,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
ArrayRef<Record*> Order = RC.getOrder();
|
||||
|
||||
// Give the register class a legal C name if it's anonymous.
|
||||
@ -887,8 +885,8 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
|
||||
// Asserts to make sure values will fit in table assuming types from
|
||||
// MCRegisterInfo.h
|
||||
@ -988,14 +986,14 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< "unsigned RegUnit) const override;\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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
const std::string &Name = RC.getName();
|
||||
|
||||
// Output the extern for the instance.
|
||||
@ -1025,15 +1023,15 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< "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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
ArrayRef<Record*> Order = RC.getOrder();
|
||||
|
||||
if (RC.Allocatable)
|
||||
@ -1042,8 +1040,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
// 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");
|
||||
@ -1096,14 +1094,14 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
SequenceToOffsetTable<IdxList, CodeGenSubRegIndex::Less> SuperRegIdxSeqs;
|
||||
BitVector MaskBV(RegisterClasses.size());
|
||||
|
||||
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
||||
const CodeGenRegisterClass &RC = *RegisterClasses[rc];
|
||||
for (const auto *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
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);
|
||||
@ -1124,8 +1122,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();
|
||||
|
||||
// Skip classes without supers. We can reuse NullRegClasses.
|
||||
@ -1134,14 +1132,14 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
if (!RC.AltOrderSelect.empty()) {
|
||||
OS << "\nstatic inline unsigned " << RC.getName()
|
||||
<< "AltOrderSelect(const MachineFunction &MF) {"
|
||||
@ -1169,22 +1167,21 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
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 ";
|
||||
if (RC.getSuperClasses().empty())
|
||||
OS << "NullRegClasses,\n ";
|
||||
else
|
||||
@ -1201,9 +1198,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
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...
|
||||
|
||||
@ -1244,8 +1240,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
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 *RCP : RegisterClasses) {
|
||||
const CodeGenRegisterClass &RC = *RCP;
|
||||
OS << " {\t// " << RC.getName() << "\n";
|
||||
for (auto &Idx : SubRegIndices) {
|
||||
if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(&Idx))
|
||||
|
Loading…
Reference in New Issue
Block a user